Linux 线程编程2.0——线程同步-互斥锁
当我们需要控制对共享资源的存取的时候,可以用一种简单的加锁的方法来控制。我们可以创建一个读/写程序,它们共用一个共享缓冲区,使用互斥锁来控制对缓冲区的存取。
函数 pthread_mutex_init()用来生成一个互斥锁。其函数原型如下:
#include<pthread.h>
int pthread_mutex_init(pthread_mutex_t *restrict mutex,const pthread_mutexattr_t *restrict attr);
第一个参数是互斥变量的地址,第二个参数设置互斥变量的属性,大多数情况下.选择默认属性,则传入空指针 NULL。
Pthread_mutex_lock()函数声明开始用互斥锁上锁,此后的代码直至调用 pthread_mutex_ unlock()为止,均被上锁,即同一时间只能被一个线程调用执行。当一个线程执行到 pthread_mutex_lock()处时,如果该锁此时被另一个线程使用,那么此线程被阻塞,线程一直阻塞知道另一个线程释放此互斥锁。这两个函数原型是:
int pthread_mutex_lock(pthread_mutex_t *mutex);
int pthread_mutex_unlock(pthread_mutex_t *mutex);
两个函数的参数都是互斥变量的地址。函数执行成功返回 0,否则返回错误号。
互斥锁使用很方便,但是有一个缺点是使用互斥锁的过程中很有可能会出现死锁:两个线程试图同时占有两个资源,并按不同的次序锁定相应的互斥锁,例如两个线程都需要锁定互斥锁 l 和互斥锁 2,A 线程锁定了互斥锁 l,B 线程了锁定互斥锁 2,此时如果 A 线程在解除互斥锁 l 之前又去锁定互斥锁 2,而 B 恰好又需要去锁定互斥锁 l,这时就出现了死锁。看起来像是绕口令,通俗一点的来解释:线程 A 和线程 B 都需要独占使用 2 个资源,但是他们都分别先占据了一个资源,然后有相互等待另外一个资源的释放,这样的形成了一个死锁。此时我们可以使用函数 pthread_mutex_trylock(),它是函数 pthread_mutex_lock()的非阻塞函数,当它发现死锁不可避免时,它会通过 errno 返回 EBUSY,我们可以针对死锁做出相应的处理。Pthread_mutex_try_lock()的函数原型是:
int pthread_mutex _trylock( pthread_mutex_t*mutex);
当互斥锁不再使用的时候,应当释放互斥变量,函数 pthread _mutex.destory()用来释放一个互斥变量。
代码:
#include <stdio.h>
#include <pthread.h>
#include <unistd.h> char buffer[];
int buffer_has_data=;
pthread_mutex_t mutex; void write_buffer (char *data)
{
/* 锁定互斥锁*/
pthread_mutex_lock (&mutex);
if (buffer_has_data == )
{
sprintf( buffer, "%s", data);
buffer_has_data=;
}
/* 打开互斥锁*/
pthread_mutex_unlock(&mutex);
} void read_buffer(void)
{
while(){
/* 锁定互斥锁*/
pthread_mutex_lock(&mutex);
if(buffer_has_data == )
{
printf("Read buffer, data = [%s]\n", buffer);
buffer_has_data=;
}
/* 打开互斥锁*/
pthread_mutex_unlock(&mutex);
sleep();
}
} int main ( int argc, char **argv )
{
char input[];
pthread_t reader;
/* 用默认属性初始化一个互斥锁对象*/
pthread_mutex_init( &mutex, NULL );
pthread_create(&reader, NULL, (void *)(read_buffer), NULL);
while( )
{
scanf( "%s", input );
write_buffer( input );
}
return ;
}
Linux 线程编程2.0——线程同步-互斥锁的更多相关文章
- 网络编程并发 多进程 进程池,互斥锁,信号量,IO模型
进程:程序正在执行的过程,就是一个正在执行的任务,而负责执行任务的就是cpu 操作系统:操作系统就是一个协调.管理和控制计算机硬件资源和软件资源的控制程序. 操作系统的作用: 1:隐藏丑陋复杂的硬件接 ...
- Linux多线程编程——多线程与线程同步
多线程 使用多线程好处: 一.通过为每种事件类型的处理单独分配线程,可以简化处理异步事件的代码,线程处理事件可以采用同步编程模式,启闭异步编程模式简单 二.方便的通信和数据交换 由于进程之间具有独立的 ...
- Posix线程编程指南(3) 线程同步
互斥锁 尽管在Posix Thread中同样可以使用IPC的信号量机制来实现互斥锁mutex功能,但显然semphore的功能过于强大了,在Posix Thread中定义了另外一套专门用于线程同步的m ...
- Linux/Unix编程中的线程安全问题【转】
转自:http://blog.csdn.net/zhengzhoudaxue2/article/details/6432984 在目前的计算机科学中,线程是操作系统调度的最小单元,进程是资源分配的最小 ...
- Posix线程编程指南(4) 线程终止
线程终止方式 一般来说,Posix的线程终止有两种情况:正常终止和非正常终止.线程主动调用pthread_exit()或者从线程函数中return都将使线程正常退出,这是可预见的退出方式:非正常终止是 ...
- Linux多线程(三)(同步互斥)
1. 线程的同步与互斥 1.1. 线程的互斥 在Posix Thread中定义了一套专门用于线程互斥的mutex函数.mutex是一种简单的加锁的方法来控制对共享资源的存取,这个互斥锁只有两种状态(上 ...
- python并发编程之多进程(二):互斥锁(同步锁)&进程其他属性&进程间通信(queue)&生产者消费者模型
一,互斥锁,同步锁 进程之间数据不共享,但是共享同一套文件系统,所以访问同一个文件,或同一个打印终端,是没有问题的, 竞争带来的结果就是错乱,如何控制,就是加锁处理 part1:多个进程共享同一打印终 ...
- Posix线程编程指南(1) 线程创建与取消
线程创建 1.1 线程与进程 相对进程而言,线程是一个更加接近于执行体的概念,它可以与同进程中的其他线程共享数据,但拥有自己的栈空间,拥有独立的执行序列.在串行程序基础上引入线程和进程是为了提高程序的 ...
- linux应用编程之进程间同步
一.描述 在操作系统中,异步并发执行环境下的一组进程,因为相互制约关系,进而互相发送消息.互相合作.互相等待,使得各进程按一定的顺序和速度执行,称为进程间的同步.具有同步关系的一组并发进程,称为合作进 ...
随机推荐
- springboot2.0动态多数据源切换
摘要:springboot1.x到springboot2.0配置变化有一点变化,网上关于springboot2.0配置多数据源的资料也比较少,为了让大家配置多数据源从springboot1.x升级到s ...
- python使用xlrd读取excel数据时,整数变小数的解决办法
python使用xlrd读取excel数据时,整数变小数: 解决方法: 1.有个比较简单的就是在数字和日期的单元格内容前加上一个英文的逗号即可.如果数据比较多,也可以批量加英文逗号的前缀(网上都有方法 ...
- 第四篇、Python文件处理
1.文件操作 1) 文件操作流程 a. 打开文件,得到文件句柄并赋值给一个变量 b. 通过句柄对文件进行操作 c. 关闭文件 f=open('a.txt','r',encoding='utf-8') ...
- week0713.5 newspaper 安装问题
然后爆红说nltk==2.0.5 太老了 所以我们 把包下载下来将requirements文件中nltk==2.0.5改成3.3.0 然后 将包打包 然后安装这个包就OK 下载newpaper wge ...
- CSS 图像
CSS 图像 <上一节下一节> 通过CSS可以控制图像的大小和对齐方式. 图像大小 虽然在HTML中,img标签有属性height.width设置高和宽,在工作中却使用得非常少,通常使用C ...
- 加入EOS主网
[加入EOS主网] 根据之前的博文,可以直接在本地测试单节点网络.这里再给出一下.详情见[参考1]. alias cleos='docker exec -it eosio /opt/eosio/bin ...
- IP路由配置之---------配置PPP
实验设备:两台华三路由器,两台PC,一条V.35线 PPP是数据链路层的协议,链路层的协议有很多如帧中继fr等 实验一,PAP验证(是一种以明码传送用户名和密码的验证方式) 步骤一,在主验证方设置一个 ...
- cast
https://blog.csdn.net/seabeam/article/details/47841539 在UVM中经常可以看到$cast的身影,这是SV的build-in task之一,当然它还 ...
- 用java开发图形界面项目,如何实现从本地选择图片文件并以二进制流的形式保存到MySQL数据库,并重新现实到面板
- HDU 5734 Acperience(数学推导)
Problem Description Deep neural networks (DNN) have shown significant improvements in several applic ...