文档章节

Linux Threading 线程

Freewheel
 Freewheel
发布于 2017/04/24 18:01
字数 1091
阅读 52
收藏 1

以下是单线程进程和多线程进程在内存方面的模型

即同一进程的线程之间共享一份代码,常量,全局变量和堆变量,但是有各自的本地变量(栈,寄存器)。

 

多线程与多进程的简单比较

数据共享方面:

进程之间无法访问对方的内存,因此需要通过kernel space创建共享对象进行沟通;

线程之间可以通过进程内的全局变量和堆变量进行沟通,更简单高效。(但同样需要解决race condition等同步问题)

 

POSIX thread library 标准线程库

 

pthread_create

int pthread_create( pthread_t *thread, 
                    const pthread_attr_t *attr, 
                    void *(*start_routine) (void *), 
                    void *arg 
                  );

线程的起始函数的参数和返回值都是 void* 类型,因此可以代入所有类型的指针。

传入线程的参数也是个指针,因此该参数的值在main thread 和 new thread 里都可以被更改。

 

pthread_exit

void pthread_exit(void *return_value);

 

pthread_join

int pthread_join(pthread_t thread, void **retval);

 

Pthread Synchronization 线程层面的同步

除了使用semaphore,thread之间的同步还可以使用pthread_mutex 和 Condition Variable。

由于semaphore在使用上(编写代码)比较难,并且可读性比较差(因为功能太强大),更推荐后两者。

 

pthread_mutex 顾名思义专门用于作为互斥锁,通常在声明为全局变量,使用时十分简单

 pthread_mutex_lock(&mutex);
 // ... critical section
 pthread_mutex_unlock(&mutex);

与semaphore不同,pthread_mutex在被获取成功的时候,它就被该线程拥有了;而semaphore则没有被拥有这个概念,它只是在kernel space作为一个第三方的存在。

 

Condition Variable 名称较为歧义,其真实用法主要是通知 notification。

它内部没有变量,计数器等,调用 wait 和 signal 方法都是 atomical 和 stateless的。(优点:性能更好,更新变量是件麻烦的事情。)

signal 方法是无条件的,即任何wait的thread都会被唤醒。因此,wait代码附近常使用 while 循环,加入条件检查代码。

while ( meet_requirement()) {
  cond_wait(&v, &m);
}

 

为什么wait方法的第二个参数是一个pthread_mutex变量?

当thread因为wait进入挂起状态时,必须释放手上的锁,使得别的thread能获得锁并执行任务;

当thread从wait中被唤醒,就需要重新拿回锁。

示例代码:

mutex_lock(&m);
while (x!=y) {
  cond_wait(&v, &m);
}
printf(x/y = 1);
mutex_unlock(&m);

 

Reentrant可重入

reentrant 可重入函数 指即使线程在中途被打断并且从头调用也可以得到正确的答案,无论这个函数之前的调用是否完成。“if it can be interrupted in the middle of its execution, and then be safely called again ("re-entered") before its previous invocations complete execution.”

-- https://en.wikipedia.org/wiki/Reentrancy_(computing)

即可重入的函数不会使用全局变量和静态变量,所有的变量都只跟单次执行有关。因此,可重入函数有益于消除共享状态share state。

 

Thread safety  线程安全

线程安全是指在多线程的环境中能够避免race condition,并且保证数据同步。

实现线程安全的途径之一就是采用可重入的编程方法减少共享状态。

 

CPU atomic instructions

test_and_set() 

//pseudocode (indeed a single atomic instruction)
boolean test_and_set(boolean *target){
  boolean tmp = *target; //original value
  *target = 1; //set
  return tmp; //return the original value!
}

使用 test_and_set 实现 mutex (示例代码,并非真实实现)

局限性: test_and_set 只能同步2个线程(进程)

 

compare_and_swap()

//pseudocode (indeed a single atomic instruction)
int compare_and_swap(int *value, int expected, int new_value) {
    int temp = *value; //original value
    if (*value == expected)
      *value = new_value;
    
    return temp; //return the original value
}

使用compare_and_swap实现mutex (示例代码,并非真实实现)

现在compare_and_swap在底层被大量用来实现semaphores, mutex, lock-free operations

 

几个编程概念

Lock-free programming

Lock-free DSA ensures a high throughput of a system/operation by 
- Guarantee progress for some threads when there are multiple threads 保证部分线程进展
- While any particular thread is blocked/waiting, some other threads must be running in order to make sure all the cores are doing useful work without stalls 保证CPU一直运行,做有用功

名字稍有歧义,Lock-free与实现中是否用到锁无关

 

Wait-free programming

Wait-free DSA ensures a high throughput of a system/operation by
– Guarantee progress for every thread when there are multiple threads without sacrificing latency of a particular thread ( Sometimes impossible to achieve) 保证所有线程都有进展
– Thread1.operation X() must finish in a finite number of steps,regardless of the state/speed of the other thread  保证一个线程操作在有限时间内一定完成

 

 

© 著作权归作者所有

共有 人打赏支持
Freewheel
粉丝 8
博文 83
码字总数 48265
作品 0
普陀
程序员
私信 提问
The C10K problem原文翻译

原文地址:http://www.cnblogs.com/fll/archive/2008/05/17/1201540.html The C10K problem 如今的web服务器需要同时处理一万个以上的客户端了,难道不是吗?毕竟如今的网络是个big place了。...

晨曦之光
2012/03/09
274
0
linux多线程网页截图-python

上一篇中(linux多线程网页截图-shell),使用shell多进程对大量的网站截图,大大减少了截图的时间。但慢慢的也发现了这种方式的弊端:每个进程分配的网站数量是相等的,有些进程截图较快,有...

cszer
2013/06/14
0
1
Python标准库08 多线程与同步 (threading包)

作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明。谢谢! Python主要通过标准库中的threading包来实现多线程。在当今网络时代,每个服务器都会接收到大量的请求...

osDaniel
2014/09/21
0
0
Python主进程hang住的两个原因

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/feilengcui008/article/details/52831354 最近使用Python遇到两个非常不好定位的问题,表现都是Python主进程h...

feilengcui008
2016/10/16
0
0
python之多线程并发处理模块-threading

thread:多线程的底层支持模块,一般不建议使用; threading:对thread进行了封装,将一些线程的操作对象化,一般采用这种方法实现多线程编程 多线程实现有两种模式: 1.创建线程要执行的函数...

zhpfxl
2016/12/27
0
0

没有更多内容

加载失败,请刷新页面

加载更多

没什么启示的启示——《中国生存启示录》读后感4300字范文

没什么启示的启示——《中国生存启示录》读后感4300字范文: 文:夜晨1981。先后两次阅读这本书,第一次是2016年3月,第二次是2018年12月。读了两遍,都有一个理由,就是梁晓声这个名字。不知...

原创小博客
昨天
1
0
ubuntu常用操作

显卡GPU 查看显卡信息sudo lshw -numeric -class video# 查看显卡型号lspci | grep -i nvidia# 查看驱动版本sudo dpkg --list | grep nvidia-*或者 ubuntu-drivers devices#查看显卡...

hc321
昨天
2
0
mysql密码重置

方法一: 在my.ini的[mysqld]字段加入: skip-grant-tables 重启mysql服务,这时的mysql不需要密码即可登录数据库 然后进入mysql mysql>use mysql; mysql>更新 update user set password=pas...

architect刘源源
昨天
6
1
SpringBoot + Mybatis 配置多数据源(Srping boot 二)

前置条件,你已经配置好spring boot+mybatis,可以参考之前的博客 实现逻辑通过注解+aop切面编程来动态更新datasource 第一步,配置多个DataSource server: port: 8080freezing: ...

小海bug
昨天
13
0
连续潜在变量---概率PCA

最大似然PCA 用于PCA的EM算法 贝叶斯PCA 因子分解

中国龙-扬科
昨天
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部