您的位置:首页 > 其它

POSIX pthread

2016-06-08 10:21 197 查看

基本概念

1.同步

所谓同步就是不可以同时进行,需要一种机制让他们按照一个顺序执行。也就是说执行结果依赖于执行顺序。

2.异步

就是两个线程可以独立进行

3.线程安全

就是函数可以同时被不同的线程调用而不产生严重的后果。

4.并发

1.使用线程来进行I/O同步

2.使用异步I/O

3.将活动视为事件,采用事件编程。即把事件集中在一个分派器的队列中,分别分派。

5.多线程编程模型

1.串行程序的同步需求隐藏在操作序列中。

2.使用线程的程序,他的同步结构应当限制在小范围内,比如一个函数中。

如果把一个活动设计为线程模式,那么每个函数之间的依赖关系必须显示的指出来,同步是显示的,而不是像串行程序那样隐藏在代码的执行序列中,造成一个函数隐式的依赖于另一个函数。

6.多线程适用场景

1.计算密集型

2.I/O密集型

线程

初始线程(主线程)

初始线程是一个特殊的线程,但是我们如果有初始线程的线程ID,那么我们可以在别的线程中分离它。

注意:如果A线程知道B线程的线程ID,那么在A线程中是可以分离线程B,或者等待线程B的终止。

线程之间是共享文件描述符与进程的地址空间的,这样有利于线程之间高效的通信。

线程状态

线程的4个状态:

1.就绪

2.运行

3.阻塞:可能分为

条件变量阻塞

互斥量阻塞

读阻塞

也就是等待其他条件而无法运行,这个时候需要别人唤醒,在唤醒之前是不占用CPU时间的。

4.终止

分为:

退出:调用return, pthread_exit

取消:被pthread_cancel

线程分离

1.僵尸线程

类似于僵尸进程:没有被分离的线程结束之后处于终止态,如果没有其他线程通过pthread_join来获得该线程的终止状态,那么这个线程退出时的状态被保留在一个内存空间中。

2.

通过函数返回或者pthread_exit调用正常终止的线程与通过取消调用终止的线程之间的唯一外部区别是:

被pthread_cancel取消的线程的返回值总是PTHREAD_CANCELLED

3.

如果有其他线程使用pthread_join来等待一个线程,比如A等待B的终止,那么在B终止之前,A被阻塞,直到B终止了,A被唤醒进入就绪态。A从pthread_join返回之后,B线程就是相当于被分离了。

需要注意的是pthread_join会获得一些B线程的信息,注意B在保存这些信息时要保存在堆空间中,而不要保存在自己私有空间中。

4.分离办法

1.创建时使用PTHREAD_CREAT_DETACH属性。

2.调用pthread_detach

3.线程终止之后,被别的线程调用pthread_join获取了相关数据之后,该线程就是被分离了。

注意:

线程一旦分离就没有办法去访问他了。

线程同步

互斥量

1.对于循环且等待条件的死锁的解决办法

固定加锁层次

尝试加锁和回退

pthread_mutex_trylock():试加锁失败会返回EBUSY

条件变量

条件变量的作用:

条件变量一般与一个共享数据有关,这个共享数据就是一个谓词,比如队列满了,队列空了。等等。

条件变量提供了一个机制,这个机制使得程序可以用条件变量来等待某个谓词为真。

理解:

因为普通的互斥量情况下,如果我们采用读队列,写队列;我们要锁住整个队列,然后去操作队列的头。

当队列为空时,我们需要等待别的线程来向队列中填充数据。

也就是说流程是:

test->wait,这需要一个原子操作,否则在wait的之前就有可能使得谓词为真,而我们却没有捕捉到这个变化。所以条件变量就提供了这么一个机制。

作用:(一定要注意)

条件变量的作用就是发信号,而不是提供互斥。所以需要使用一个互斥量来同步对共享数据(谓词)的访问,而条件变量就提供了一个通知机制。

等待一个条件:

要求先释放互斥量,然后在这个条件上等待(阻塞住)

使用:

条件变量一般与一个谓词想联系,所以最好将条件变量与相关谓词放在一起,比如一个struct 中。

注意线程在被条件满足被唤醒之后,一定要再次测试条件是否满足,比如这里的data.value。

因为:

1.唤醒可能被拦截:

有两个线程A,B都在竞争队列的使用,A,B都被唤醒,但是A先执行他把队列元素消耗光了,这样B的条件就不满足了。

2.松散的谓词结构

3.假唤醒
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: