与互斥锁相关API
      互斥量(mutex)从本质上来说是一把锁,在访问共享资源前对互斥量进行加锁,在访问完成后释放互斥量上的锁。对互斥量进行加锁后,任何其他试图再次对互斥量加锁的线程将会被阻塞直到当前线程释放该互斥锁。如果释放互斥锁时有多个线程阻塞,所有在该互斥锁上的阻塞线程都会变成可运行状态,第一个变为可运行状态的线程可以对互斥量加锁,其他线程将会看到互斥锁依然被锁住,只能回去等待它重新变为可用。在这种方式下,每次只有一个线程可以向前运行。

在设计时需要规定所有的线程必须遵守相同的数据访问规则。只有这样,互斥机制才能正常工作。操作系统并不会做数据访问的串行化。如果允许其中的某个线程在没有得到锁的情况下也可以访问共享资源,那么即使其它的线程在使用共享资源前都获取了锁,也还是会出现数据不一致的问题。

互斥变量用pthread_mutex_t数据类型表示。在使用互斥变量前必须对它进行初始化,可以把它置为常量PTHREAD_MUTEX_INITIALIZER(只对静态分配的互斥量),也可以通过调用pthread_mutex_init函数进行初始化。如果动态地分配互斥量(例如通过调用malloc函数),那么在释放内存前需要调用pthread_mutex_destroy。
1. 创建及销毁互斥锁

#include <pthread.h>
int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr);
int pthread_mutex_destroy(pthread_mutex_t
*restrict mutex);
// 返回:若成功返回0,否则返回错误编号

要用默认的属性初始化互斥量,只需把attr设置为NULL。
2. 加锁及解锁

#include <pthread.h>
int pthread_mutex_lock(pthread_mutex_t *restrict mutex);
int pthread_mutex_trylock(pthread_mutex_t mutex);
int pthread_mutex_unlock(pthread_mutex_t *restrict mutex);
// 返回:若成功返回0,否则返回错误编号

如果线程不希望被阻塞,它可以使用pthread_mutex_trylock尝试对互斥量进行加锁。如果调用pthread_mutex_trylock时互斥量处于未锁住状态,那么pthread_mutex_trylock将锁住互斥量,不会出现阻塞并返回0,否则pthread_mutex_trylock就会失败,不能锁住互斥量,而返回EBUSY。

代码示例

#include<stdio.h>
#include<pthread.h>
//int pthread_create(pthread_t *restrict tidp, const pthread_attr_t *restrict attr, void *(*start_rtn)(void *), void *restrict arg);int g_data=0;
pthread_mutex_t mutex;//定义一个互斥量也就是锁void*func1(void *arg)
{int i;pthread_mutex_lock(&mutex);//给互斥量上锁for(i=0;i<5;i++){printf("t1 :%ld thread is created\n",(unsigned long)pthread_self());printf("t1:param is %d\n",*((int*)arg));}pthread_mutex_unlock(&mutex);//给互斥量解锁}void*func2(void *arg)
{pthread_mutex_lock(&mutex);//给互斥量上锁printf("t2 :%ld thread is created\n",(unsigned long)pthread_self());printf("t2:param is %d\n",*((int*)arg));pthread_mutex_unlock(&mutex);//给互斥量解锁}int main()
{int ret;int param=100;pthread_t t1;pthread_t t2;pthread_mutex_init(&mutex,NULL);//初始化互斥量ret=pthread_create(&t1,NULL,func1,(void*)&param);if(ret==0){printf("main:create t1 success\n");}ret=pthread_create(&t2,NULL,func2,(void*)&param);if(ret==0){printf("main:create t2 success\n");}printf("main : %ld \n",(unsigned long)pthread_self());pthread_join(t1,NULL);//用来等待进程t1退出pthread_join(t2,NULL);//用来等待进程t2退出pthread_mutex_destroy(&mutex);//销毁这把锁return 0;
}              

脚本可以这样写

CLC@Embed_Learn:~/xiancheng$ vi test.sh
CLC@Embed_Learn:~/xiancheng$ chmod +x test.sh
CLC@Embed_Learn:~/xiancheng$ ./test.sh
//其中test.sh中写入要运行的程序

实现进程t1满足条件退出代码

#include<stdio.h>
#include<pthread.h>
#include <stdlib.h>
//int pthread_create(pthread_t *restrict tidp, const pthread_attr_t *restrict attr, void *(*start_rtn)(void *), void *restrict arg);int g_data=0;//pthread_mutex_t mutex;void*func1(void *arg)
{printf("t1 :%ld thread is created\n",(unsigned long)pthread_self());printf("t1:param is %d\n",*((int*)arg));pthread_mutex_lock(&mutex);while(1){printf("t1 printf is %d\n",g_data++);sleep(1);if(g_data==3){pthread_mutex_unlock(&mutex);printf("t1 over==============================\n");//pthread_exit(NULL);exit(0);}}}void*func2(void *arg)
{printf("t2 :%ld thread is created\n",(unsigned long)pthread_self());printf("t2:param is %d\n",*((int*)arg));while(1){printf("t2 printf is %d\n",g_data);pthread_mutex_lock(&mutex);g_data++;   pthread_mutex_unlock(&mutex);sleep(1);}pthread_mutex_unlock(&mutex);
}int main()
{int ret;int param=100;pthread_t t1;pthread_t t2;pthread_mutex_init(&mutex,NULL);ret=pthread_create(&t1,NULL,func1,(void*)&param);if(ret==0){printf("main:create t1 success\n");}ret=pthread_create(&t2,NULL,func2,(void*)&param);if(ret==0){printf("main:create t2 success\n");}printf("main : %ld \n",(unsigned long)pthread_self());while(1){printf("main printf is %d\n",g_data);sleep(1);}pthread_join(t1,NULL);pthread_join(t2,NULL);pthread_mutex_destory(&mutex);return 0;
}

什么情况下造成死锁
      死锁 是指两个或两个以上的进程在执行过程中,由于竞争资源或彼此通信而造成的一种阻塞现象,无外力作用,他们都将无法再推进下去。(一般需要两个mutex)
代码示例

void*func1(void *arg)
{int i;pthread_mutex_lock(&mutex);sleep(1);pthread_mutex_lock(&mutex2);for(i=0;i<5;i++){printf("t1 :%ld thread is created\n",(unsigned long)pthread_self());printf("t1:param is %d\n",*((int*)arg));}pthread_mutex_unlock(&mutex);}void*func2(void *arg)
{pthread_mutex_lock(&mutex2);sleep(1);pthread_mutex_lock(&mutex);printf("t2 :%ld thread is created\n",(unsigned long)pthread_self());printf("t2:param is %d\n",*((int*)arg));pthread_mutex_unlock(&mutex);}

参考博文:https://www.cnblogs.com/xiehongfeng100/p/4620852.html

线程同步之互斥量加锁解锁 死锁相关推荐

  1. 1线程同步:互斥量,死锁

     1线程为什么要同步 A:共享资源,多个线程都可对共享资源操作. B:线程操作共享资源的先后顺序不确定. C:处理器对存储器的操作一般不是原子操作. 2互斥量 mutex操作原语 pthread_ ...

  2. linux操作系统之线程同步及互斥量

    (1)线程同步 1)线程同步:指一个线程发出某一个功能运行时,在运行还没有结束的时候,该调用不返回.同时其它线程为保证数据的一致性,不能调用该功能. 2)多个控制流共同操作一个共享资源的时候,都需要同 ...

  3. 并发编程概念、程序线程进程、线程同步、互斥量、读写锁、协程并发

    多线程: 多线程就是同时执行多个应用程序,需要硬件的支持 同时执行:不是某个时间段同时,cpu切换的比较快,所有用户会感觉是在同时运行 并发与并行: 并行(parallel):指在同一时刻,有多条指令 ...

  4. 线程同步之互斥量(互斥锁)

    1 同步的概念 所谓同步, 即同时起步,协调一致.不同的对象, 对"同步" 的理解方式略有不同. 如,设备同步,是指在两个设备之间规定一个共同的时间参考: 数据库同步, 是指让两个 ...

  5. 信号灯文件锁linux线程,linux——线程同步(互斥量、条件变量、信号灯、文件锁)...

    一.说明 linux的线程同步涉及: 1.互斥量 2.条件变量 3.信号灯 4.文件读写锁 信号灯很多时候被称为信号量,但个人仍觉得叫做信号灯比较好,因为可以与"SYSTEM V IPC的信 ...

  6. RTT的线程同步篇——互斥量

    野火RTT第20章互斥量 2018年12月29日 10:47 互斥量不能在中断服务程序中使用. 互斥量是特殊的二值信号量,其"特殊"在哪呢?互斥量不同于二值信号量的地方在于:互斥量 ...

  7. 线程同步之——互斥量及死锁问题

    互斥量:多个线程同时访问共享数据时可能会冲突,这跟信号的可重性是同样的问题.如 果两个线程都要把某个全局变量增加1,这个操作在某平台需要三条指令完成: 1. 从内存读变量值到寄存器 2. 寄存器的值加 ...

  8. Linux系统编程----16(线程同步,互斥量 mutex,互斥锁的相关函数,死锁,读写锁)

    同步概念 所谓同步,即同时起步,协调一致.不同的对象,对"同步"的理解方式略有不同.如,设备同步,是指在两 个设备之间规定一个共同的时间参考:数据库同步,是指让两个或多个数据库内容 ...

  9. linux线程同步(1)-互斥量

    一.概述                                                   互斥量是线程同步的一种机制,用来保护多线程的共享资源.同一时刻,只允许一个线程对临界区进行 ...

最新文章

  1. ES6中表达export default const是无效的
  2. Makefile_02:程序的编译和链接
  3. eclipse 提交git失败_简单10步教你使用eclipse整合gitee码云实现共享开发
  4. 02-CA/TA编程:aes demo
  5. 打印二叉搜索树的叶子结点_求孩子兄弟树叶子节点数目
  6. iphone-常用的对视图图层(layer)的操作
  7. eclipse设置java虚拟机内存大小_eclipse设置java虚拟机内存大小
  8. Codeforces 1103 E. Radix sum
  9. 【思维导图】nav_msgs/Odometry 消息的构成及订阅
  10. 绿盟科技网络安全威胁周报2017.02 请关注Microsoft Edge远程权限提升漏洞 CVE-2017-0002...
  11. php mysql 连接池_php 如何实现 数据库 连接池
  12. php微信jsapi支付案例,PHP实现微信支付(jsapi支付)流程
  13. 在网络世界中我们该如何保护我们的信息安全?
  14. java变量不声明可以直接使用吗_Java基础_变量的声明与使用
  15. 广东省计算机设计大赛文档,广东省大学生计算机设计大赛.doc
  16. switch组件设置大小
  17. FOC:在MCU上检验Clark和Park坐标变换是否正确
  18. 苹果电脑虚拟键盘怎么打开
  19. windows10 更换密码
  20. java游戏大唐双龙传后传,大唐龙凤传(大唐双龙传后续)

热门文章

  1. numpy——mgrid
  2. mysql重命名数据表称方式_在MySQL中,使用()重命名数据表。_学小易找答案
  3. 查询工资最低的3名员工的职工工号、姓名和收入_关于工资条,这6个常识必须掌握,事关你的权益!...
  4. php的类装载的步骤,设计PHP自动类装载功能
  5. codeforces 1017E
  6. hadoop二次排序
  7. 画像分析(3-3)标签建模-模型管理-新建关系
  8. xiaocms 关于搜索功能 添加搜索字段
  9. html调用静态json例子
  10. native的Socket向Android的LocalSocketServer发送汉字乱码的问题