Linux 线程间的同步与互斥
在线程并发执行的时候,我们需要保证临界资源的安全访问,防止线程争抢资源,造成数据二义性。
线程同步: 条件变量
为什么使用条件变量?
对临界资源的时序可控性,条件满足会通知其他等待操作临界资源的线程,类似信号。 场景:T-DAY展会排队参观/生产者消费者模型
条件变量是什么?
是一种同步机制,一个线程用于修改这个变量使其满足其它线程继续往下执行的条件,其它线程则接收条件已经发生改变的信号。
条件变量操作?
初始化和销毁
pthread_cond_wait
条件不满足 会释放锁并阻塞等待 , 这个函数是原子性操作:1.将线程放入条件等待队列 2.释放锁
条件满足 则线程会被唤醒并加锁
pthread_cond_signal 一对一唤醒
唤醒等待队列中的一个线程
pthread_cond_broadcast 广播唤醒
唤醒等待队列中的全部线程
为什么等待和解锁需要原子操作/为什么条件变量要使用互斥锁?
因为pthread_cond_wait中的锁是为了保护条件变量,防止错过信号,如果等待解锁不是原子性操作,比如线程A先解锁,此时CPU时间片切换到线程B,线程B加锁并发送条件变量信号,此时再切换到线程A,线程A还来不及等待就错过了信号,就可能会永久阻塞下去。所以,等待和解锁必须是原子性操作。
为什么需要while循环判断临界资源是否存在?
在一对多的情况下,生产者发送一个信号,等待的线程被唤醒并加锁,但是只有一个线程能加锁,其他线程就会阻塞等待锁,如果这个线程用完了临界资源,其他线程不进行判断就继续往下走,是不合理的。
singnal要先解锁还是后解锁?
如果先解锁,锁被没有阻塞等待的线程拿到了,再把临界资源使用了,解锁后的singal就没意义了,也就是虚假唤醒;
先singal唤醒,再让唤醒的线程争抢锁,在linux下,有两个队列,一个是cond_wait,一个是mutex_lock,singal只是让cond_wait上的线程转移到mutex_lock,不会返回用户空间,这样能提高效率。
线程互斥: 互斥锁
为什么使用互斥锁?
对临界资源同时间唯一访问,保护临界资源防止修改。 场景:黄牛抢票
互斥锁是什么?
是一个0/1计数器,1代表有资源能操作,0代表没有资源可以操作。
互斥锁操作?
初始化和销毁
加锁---如果计数为1,置0,进行需要的操作;如果计数为0,则阻塞等待计数变为1
解锁---计数置为1
Linux 线程间的同步与互斥的更多相关文章
- 嵌入式开发之hi3519---进程线程间的同步和互斥,条件变量、信号了、互斥锁等
sem_post 最安全 sem 有序,会卡顿 阻塞 mutex 无序,不能同步 http://blog.chinaunix.net/uid-20671208-id-4935154.html ht ...
- vc++高级班之多线程篇[7]---线程间的同步机制②
//示例代码: CStringArray g_ArrString; UINT __cdecl ThreadProc(LPVOID lpParameter) { int startIdx = (int ...
- Java并发之线程间的同步协作与通信协作
1,Monitor监视器与syncrhoized实现原理 1.1:Monitor Monitor是一个同步工具,相当于操作系统中的互斥量(mutex),即值为1的信号量. 它内置与每一个Object对 ...
- vc++高级班之多线程篇[6]---线程间的同步机制①
①.线程同步的必要性: int g_Num = 0; UINT __cdecl ThreadProc(LPVOID lpParameter) { for (int idx = 0; idx &l ...
- linux线程间同步方式总结梳理
线程间一般无需特别的手段进行通信,由于线程间能够共享数据结构,也就是一个全局变量能够被两个线程同时使用.只是要注意的是线程间须要做好同步! 使用多线程的理由: 1. 一个是和进程相比,它是一种非常&q ...
- Linux线程间同步的几种方式
信号量 信号量强调的是线程(或进程)间的同步:"信号量用在多线程多任务同步的,一个线程完成了某一个动作就通过信号量告诉别的线程,别的线程再进行某些动作(大家都在sem_wait的时候,就阻塞 ...
- linux线程间同步方式汇总
抽空做了下linux所有线程间同步方式的汇总(原生的),包含以下几个: 1, mutex 2, condition variable 3, reader-writer lock 4, spin loc ...
- Linux线程的信号量同步
信号量和互斥锁(mutex)的区别:互斥锁只允许一个线程进入临界区,而信号量允许多个线程同时进入临界区. 不多做解释,要使用信号量同步,需要包含头文件semaphore.h. 主要用到的函数: int ...
- linux 线程间发送信号
线程间通过 pthread_kill(thid,signo)给指定的thid线程发送signo信号. 创建线程与线程屏蔽字顺序 1. pthread_create(); pthread_sigm ...
随机推荐
- 常用方法 DataTable转换为Entitys
备注:摘自网上 有附地址 public static List<T> DataTableToEntities<T>(this DataTable dt) where T : c ...
- JMeter的基本使用
什么是Jmeter JMeter是Apache基于Java开发的压力测试工具,通俗的说,你想知道你的接口有多猛,你的服务器是否耐揍,这个家伙可以用数据告诉你.原来学过JMeter的基本使用,发现想不起 ...
- 使用MeadCo's ScriptX控件做WEB打印
官方网址:http://www.meadroid.com/scriptx/index.asp MeadCo's ScriptX控件有两种使用方式,一种是做为免费版本使用,一种是做为收费版本使用,免费版 ...
- The Five Qualities You Need in a Partner
The Five Qualities You Need in a Partner Things I Never Considered Before Getting Married (But Shoul ...
- Python 使用scapy 时报:ImportError: cannot import name 'NPCAP_PATH' 解决
解决办法:下载源码 https://github.com/secdev/scapy 下载完成后解压后里面有个scapy文件夹,把这个文件夹替换\Lib\site-packages\ 下的scapy 整 ...
- Vue日常开发问题
1.sh: webpack-dev-server: command not found 我的公众号:
- Kafka集群管理工具kafka-manager
一.kafka-manager简介 kafka-manager是目前最受欢迎的kafka集群管理工具,最早由雅虎开源,用户可以在Web界面执行一些简单的集群管理操作.具体支持以下内容: 管理多个集群 ...
- Xcodebuild稳定性测试go脚本
[本文出自天外归云的博客园] 简单封装下xcodebuild test命令,写一个执行xcode测试的go程序,可以设定单case执行次数,也可以二次组装调用进行多个case的测试,代码如下: pac ...
- paxos(mysql)
https://web.stanford.edu/~ouster/cgi-bin/papers/OngaroPhD.pdf https://raft.github.io/raft.pdf 如何浅显易懂 ...
- 003-Python3-基础语法-运行方式、代码基础要求、运算符[算数运算符、比较运算符、赋值运算符、位运算符、逻辑运算符、成员运算符、身份运算符]、运算符优先级
一.基础语法 参看地址:https://www.runoob.com/python3/python3-tutorial.html 1.1.运行方式 1.文件方式 编写一个hello.py文件, pri ...