当前位置:首页 > 嵌入式培训 > 嵌入式学习 > 讲师博文 > 线程互斥与同步

线程互斥与同步 时间:2018-09-29      来源:未知

一、线程间互斥

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按照顺序执行)?

上一篇:vmware虚拟机网络问题的解决

下一篇:Linux字符设备驱动模型之字符设备初始化

热点文章推荐
华清学员就业榜单
高薪学员经验分享
热点新闻推荐
前台专线:010-82525158 企业培训洽谈专线:010-82525379 院校合作洽谈专线:010-82525379 Copyright © 2004-2022 北京华清远见科技集团有限公司 版权所有 ,京ICP备16055225号-5京公海网安备11010802025203号

回到顶部