详谈多线程2

上一篇中,我们已经介绍了互斥锁,实现了对临界资源的保护,并且我们留下了一个悬念:

解决了临界资源的访问,但似乎对线程的执行顺序无法得到控制,因线程 都是无序执行,之前采用sleep强行延时的方法勉强可以控制执行顺序,但此 方法在实际项目情况往往是不可取的,其仅仅可解决线程创建的顺序,当创建之后执行的顺序又不会受到控制,于是便引入了信号量的概念,解决线程执行顺序。

所以,接下来,我们来讲讲多线程编执行顺序控制:


信号量API简述

函数原型如下:

⚫ 该函数可以初始化一个信号量,第一个参数传入sem_t类型指针;

⚫ 第二个参数传入0代表线程控制,否则为进程控制;

⚫ 第三个参数表示信号量的初始值,0代表阻塞,1代表运行。

⚫ 待初始化结束信号量后,若执行成功会返回0。

信号量P/V操作

函数原型如下:

⚫ sem_wait函数作用为检测指定信号量是否有资源可用,若无资源可用会阻塞 等待,若有资源可用会自动的执行“sem-1”的操作。所谓的“sem-1”是与上述 初始化函数中第三个参数值一致,成功执行会返回0。

⚫ sem_post函数会释放指定信号量的资源,执行“sem+1”操作。

通过以上2个函数可以完成所谓的PV操作,即信号量的申请与释放,完成 对线程执行顺序的控制。

信号量申请(非阻塞方式)

函数原型如下:

此函数是信号量申请资源的非阻塞函数,功能与sem_wait一致,唯一区别在于此函数为非阻塞。

信号量销毁

函数原型如下:

该函数为信号量销毁函数,执行过后可将信号量进行销毁。

测试例程12:(Phtread_txex12.c)

运行结果:

该例程加入了信号量,使得线程的执行顺序变为可控的。在初始化信号量时, 将信号量1填入资源,第一个线程调用sem_wait函数可以成功获得信号量,在 执行完逻辑后使用sem_pos函数来释放。当执行函数sem_wait后,会执行sem 自减操作,使下一次竞争被阻塞,直至通过sem_pos被释放。

上述例程因38行初始化信号量1时候,使其默认获取到资源;第 43、48行 初始化信号量2、3时候,使之没有资源。于是在线程处理函数中,每个线程通 过sem_wait函数来等待资源,发生阻塞。因信号量1初始值为有资源,故可以 先执行线程1的逻辑。待执行完第12行sem_wait函数,会导致sem1-1,使得 下一次此线程会被阻塞。继而执行至14行,通过sem_post函数使sem2信号量 获取资源,从而冲破阻塞执行线程2的逻辑...以此类推完成线程的有序控制。

下面再来讲一个东西,其实小编之前也没有接触过这个:

条件变量:

条件变量时一种同步机制,用来通知其他线程条件满足了。一般是用来通知 对方共享数据的状态信息,因此条件变量时结合互斥量来使用的。(看到这个突然就想起来了,好像之前接触过(doge.))

创建和销毁条件变量

函数原型如下:

等待条件变量

函数原型如下:

这需要结合互斥量一起使用,示例代码如下:

通知条件变量

函数原型如下:

pthread_cond_signal 函数只会唤醒一个等待cond条件变量的线程,示 例代码如下:

这个大概讲一下就行了,感觉用处也不是很大,后面要用到再来细细探讨吧(doge.)

那关于多线程的,就差不多讲完了,下面我们来总结一下吧

总结:

线程使用流程图:

有关多线程的创建流程如图 9.14所示,首先需要创建线程,一旦线程创 建完成后,线程与线程之间会发生竞争执行,抢占时间片来执行线程逻辑。在 创建线程时候,可以通过创建线程的第四个参数传入参数,在线程退出时亦可 传出参数被线程回收函数所回收,获取到传出的参数。

互斥量使用流程图:

当多个线程出现后,会遇到同时操作临界公共资源的问题,当线程操作公 共资源时需要对线程进行保护加锁,防止其与线程在此线程更改变量时同时更 改变量,待逻辑执行完毕后再次解锁,使其余线程再度开始竞争。互斥锁创建 流程下图所示。

信号量使用流程图:

当多个线程出现后,同时会遇到无序执行的问题。有时候需要对线程的执 行顺序做出限定,变引入了信号量,通过PV操作来控制线程的执行顺序,如下 图所示。

那么到这里,我们就全部讲完啦,完结,撒花(doge.)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值