文档章节

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
普陀
程序员
linux多线程网页截图-python

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

cszer
2013/06/14
0
1
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
Python标准库08 多线程与同步 (threading包)

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

osDaniel
2014/09/21
0
0
Python第十三堂课(并发)

一、并发 二、并发的解决 二、进程和线程 三、线程的状态 四、Python中的线程开发 名称含义current_thread( )返回当前线程对象main_thread()返回主线程对象active_count( )当前处于alive状态...

菜鸡满地跑
2017/12/19
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Univalsal_ImageLoader源码结构与创建者模式 初步小结

最近在回归看Univalsal_ImageLoader源码,本想自己也实现试试写一个,看源码是为了学习看能否使用,助于自己可以写出有自己逻辑结构的代码。 首先我们初始化ImageLoader的配置初始化的时候,...

DannyCoder
55分钟前
0
0
计算卷积神经网络浮点数运算量

前言 本文主要是介绍了,给定一个卷积神经网络的配置之后,如何大概估算它的浮点数运算量。 相关代码:CalFlops,基于MXNet框架的 Scala 接口实现的一个计算MXNet网络模型运算量的demo。 正文...

Ldpe2G
今天
3
0
Sql语言与MySql数据库

1. 数据库简介 1. 数据库,就是存储数据的仓库,只能通过sql语言来访问,数据库也是一个文件系统。通常,MySQL、Oracle等数据库,也被称为关系型数据库,其保存的不仅仅只是数据,还包括数据...

江左煤郎
今天
3
0
IDEA 取消自动import .*

打开设置 > Editor > Code Style > Java > Scheme Default > Imports ① 将 Class count to use import with "*" 改为 99 (导入同一个包的类超过这个数值自动变为 * ) ② 将 Names count ......

乔老哥
今天
4
0
PostGIS学习笔记(开篇)

PostGIS事实上算是笔者开始写博客的第一篇内容。而事实上那篇博文的内容并不丰富,笔者对PostGIS的了解仍然不多,然而17年在OSGeo课程学习时对PostGIS又有了进一步了解,并逐步发现它的强大。...

胖胖雕
今天
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部