C语言中线程间的互斥与同步

 

一、线程间互斥1.互斥锁1) 引入互斥(mutual exclusion)锁的目的是用来保证共享数据操作的完...



一、线程间互斥

1.互斥锁

1) 引入互斥(mutual exclusion)锁的目的是用来保证共享数据操作的完整性;

2) 互斥锁主要用来保护临界资源;

3) 每个临界资源都由一个互斥锁来保护,任何时刻最多只能有一个线程能访问该资源;

4) 线程必须先获得互斥锁才能访问临界资源,访问完资源后释放该锁。如果无法获得锁,线程会阻塞直到获得锁为止。

2.互斥锁API:

 设置锁:初始化锁

第一个参数是变量的地址,

第二个参数是互斥锁的属性。

 上锁:
 解锁:
拓展:pthread_mutex_destroy 删除锁。

pthread_mutex_trylock()试图加锁函数。

3.示例代码


一定会将加锁与解锁中的所以的动作完成后,下一个申请才会开始。保证数据的原子性。

比如两个线程同时操作日志文件。读写操作的结果可能被打断,结果是未知的。

互斥锁过程回顾:

定义锁变量   //买一把锁,(全局变量)

初始化锁    //设置锁状态

对临界资源加锁 //上锁

临界资源代码

对临界资源解锁 //解锁

二、同步与信号量

1.什么是同步

互斥表示的是两者不能同时对临界资源进行操作,先后顺序没有任何保证,哪个线程拥有时间片,哪个线程就进行临界资源访问。相当于两个操作之间是相互排斥的,必须保证一个线程访问结束,另一个线程才可以进行访问资源。(访问互斥,无序,当一个线程加锁之后,必须等当前线程的临界资源访问代码执行结束之后,执行了解锁代码,才会释放了锁!)

同步也是不可以同时运行(同时访问临界资源),同步是在互斥的基础上按照一定的顺序进程访问资源。同步在互斥的基础上,加入一定的机制保证资源访问的顺序。(访问互斥,有序)。

2.信号量的提出

实现同步的功能提出信号量的概念。在现实生活中,交通路口的红绿灯就是一种同步,有红绿两种等,红灯亮,则绿灯灭。红灯灭,则绿灯亮。

红灯状态: 1 --> 0

绿灯状态: 0 --> 1

信号量表示资源的数量,当绿灯状态为1,表示绿色方向的道路资源可用,可以通行后,绿灯再减1变成0。

资源的数量可以是多个,即信号量的数量可以大于1,比如公司PC的数量就是一种资源,可以有N台PC供员工申请试用,申请成功就要将资源的数量减1,当有员工返还PC时,资源的数据加1。
P/V操作:
3.有名信号与无名信号的比较

1) 有名信号量必须指定一个相关联的文件名称,这个name通常是文件系统中的某个文件;无名信号量不需要指定名称。

2) 有名信号量既可用于线程间的同步,又能用于进程间的同步;无名信号量通过shared参数来决定是进程内还是相关进程间共享。

3) 有名信号量是随内核持续的,一个进程创建一个信号量,另外的进程可以通过该信号量的外部名(创建信号量使用的文件名)来访问它。进程结束后,信号量还存在,并且信号量的值也不会改动。

4) 无名信号量的持续性却是不定的:如果无名信号量是由单个进程内的各个线程共享的,那么该信号量就是随进程持续的,当该进程终止时它也会消失。如果某个无名信号量是在不同进程间同步的,该信号量必须存放在共享内存区中,只要该共享内存区存在,该信号量就存在。

5) 无名信号量(文件系统不可见,内存信号量)。

信号量是一个受保护的变量,不可以随意操作,由相应的函数操作。

4.pthreaad库常用的信号量操作函数如下:

 int sem_init(sem_t *sem, int pshared, unsigned int value);

 int sem_wait(sem_t *sem);    //P操作

 int sem_post(sem_t *sem);    //V操作

 int sem_trywait(sem_t *sem);

 int sem_getvalue(sem_t *sem, int *svalue);
pshared: 信号量共享范围,0是线程间使用。非0表示进程间使用(不过函数并没有对进程间无名信号支持, 设想总是好的吗).

value: 资源的个数。
sem_wait() 信号量减一

sem_post() 信号量加一

sem_trywait() 不阻塞的方式P申请。

setm_getvalue() 获取当前信号量的个数,保存在第二个参数中。

5.示例代码

1) 信号量实现互斥:


2) 信号量实现同步


3) 锁实现同步:


PS:

1. 锁是信号量数量为1时的一种特殊情况,即锁也可以看成一种信号量。

2. 互斥的实现要用到一个锁变量或一个信号量。

3. 同步要用到至少两把锁或两个信号量。

思考:

如果三个线程,如果实现同步(即pthread1, pthread2 pthread3按照顺序执行)?

【近期文章推荐】

1.嵌入式培训靠谱吗 就业好不好?

2.分分钟了解什么是物联网技术

3.什么领域的人更适合学习嵌入式开发?

4.5个月达成年薪15W是怎样做到的?

5.Linux工程师培训前景怎么样

6.马云无人超市、华为人工智能交通都离不开这家公司

6月高薪就业榜超有料 北上广深月均资高达1.1w以上

回复“0-71”任一数字,即可查看往期文章精选哦

长按二维码3秒

与10万程序高手做朋友

每天干货享不停


(记得识别二维码哟)



或微信搜索华清远见,即可关注我们

免费讲座 | 干货分享 | 程序员生活 | 就业招聘

高端IT就业培训专家

m.embedu.org


    关注 华清远见


微信扫一扫关注公众号

0 个评论

要回复文章请先登录注册