Linux入门:线程同步与互斥(一)——互斥量
来源:互联网 发布:手机日记本软件 编辑:程序博客网 时间:2024/05/01 04:53
多个线程同时访问共享数据时可能会冲突。比如,两个线程都要把某个全局变量加1,这个操作需要三个指令才能完成:
1.从内存读变量值到寄存器
2.寄存器的值加1
3.将寄存器的值写回内存
由于给全局变量加1需要以上三步操作,而两个线程都要给它加1 的时候就可能在进行这三步操作的任意一步的时候被切出去,假设线程1 在给寄存器的值加1 之后刚想把寄存器的值的值写回内存的时候被切出去,此时它的上下文信息被保存;线程2开始操作这个全局变量,由于线程1还没有把加过之后的值写回内存,这时线程2 读到的仍然是全局变量的初始值,然后线程2就执行以上三步操作,完成之后又轮到线程1执行它自己的逻辑,此时它还原自己的上下文信息,将寄存器里的值写回内存,然而线程1和2各执行一次的操作值给全局变量加了1,没有达到我们预想的加2的效果。(什么情况下容易发生线程间切换:执行流由系统调用变为内核态,结束系统调用要切换回用户太的时候最容易触发线程间切换。用户态切换到内核态的三种方式:(1)系统调用,(2)异常,(3)外围设备的中断)
我们通过一个简单的程序来观察这一现象。
我们创建两个线程,各自把gCount的值累加5000次,正常情况下gCount的值应该等于10000:
#include <stdio.h>#include <pthread.h>//pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;int gCount = 0;void *thread_run(void *arg){int i = 0;int data = 0;while(i++ < 5000){//pthread_mutex_lock(&lock);data = gCount;printf("thread %lu count is:%d\n", data);gCount = data+1;//pthread_mutex_unlock(&lock);}}int main(){pthread_t id1, id2;pthread_create(&id1, NULL, thread_run, NULL);pthread_create(&id2, NULL, thread_run, NULL);pthread_join(id1, NULL);pthread_join(id2, NULL);//pthread_mutex_destroy(&lock); printf("main thread count is:%d\n", gCount);return 0;}
然而结果每次都不相同:对于多线程的程序,多个执行流非原子的去访问临界资源,但没有对临界资源加以保护,访问冲突的问题是很普遍的,解决的办法是引入互斥锁,获得锁的线程可完成“读—修改—写”的操作,然后释放锁给其他线程,没有获得锁的线程只能等待而不能访问共享数据,这样“读—修改—写”三步操作组成一个原子操作,要么都执行,要么都不执行,就算在执行到其中一步的时候被切出去,也是抱着锁被切出去,其他线程没有访问这个共享数据的权利。
互斥锁相当于二元信号量,只在线程中有效。
1.初始化互斥锁
2.加锁
3.解锁
4.销毁互斥锁
程序示例:
运行结果:
- Linux入门:线程同步与互斥(一)——互斥量
- Linux入门:线程同步与互斥(二)——条件变量
- Linux入门:线程同步与互斥(三)——信号量
- Linux入门:线程同步与互斥(四)——读写锁
- 线程同步与互斥(一)
- Linux互斥与同步应用(一):posix线程及线程间互斥
- linux线程互斥与同步---互斥锁
- linux线程同步与互斥
- linux线程互斥与同步
- Linux 线程同步与互斥
- linux线程互斥与同步---互斥锁
- Linux线程同步与互斥
- Linux线程同步与互斥
- Linux线程同步与互斥
- Linux之线程:同步与互斥
- linux线程互斥与同步
- Linux下线程互斥与同步
- linux线程3-互斥与同步
- 算法提高 c++_ch02_04
- JAVA字符集
- 关于函数中栈内存的分配问题追踪
- JAVA设计模式之单例模式[转]
- isset()和empty()的区别
- Linux入门:线程同步与互斥(一)——互斥量
- ios ipad里面调用系统相册图片不完整解决方法
- JAVA OOP第七章 集合框架
- ScrollView代码布局(SnapKit)带来的困扰
- ubuntu 安装caffe精简教程
- Git小结
- C语言fgetc()函数的返回值
- 懂商业的技术合伙人(7):怎样快速开发一个APP(2)
- layer中使用layer.open中content里面的元素追加事件,加不上