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应用编程之进程间同步
一.描述 在操作系统中,异步并发执行环境下的一组进程,因为相互制约关系,进而互相发送消息.互相合作.互相等待,使得各进程按一定的顺序和速度执行,称为进程间的同步.具有同步关系的一组并发进程,称为合作进 ...
随机推荐
- py目录
Python开发[第二篇]:初识Python Python开发[第三篇]:Python基本数据类型 Python开发[第四篇]:Python基础之函数 &&[4.1]算法递归 冒泡 ...
- Swift get和set方法以及只读属性(计算型属性,本身不保存数据,都是通过计算获得结果)
import UIKit class Person: NSObject { private var _name: String? var name: String? { get { return _n ...
- centos7 卸载 jdk
################ jdk 的安装 ###########################参考:https://www.cnblogs.com/Dylansuns/p/6974272.h ...
- PHP对接微信支付采坑
第一次做PHP商城项目对接微信支付接口,踩了N次坑,这也不对,那也不对,搞了很久,查了一些资料,终于实现了支付功能,小小总结一下,万一下次遇到就不用到处找资料了. 微信扫码支付 前期准备: 1.微信公 ...
- 修改CKplayer.js 源码解决移动端浏览器全屏不能限制快进的问题
原文地址:https://www.cnblogs.com/jying/p/9642445.html,转载请说明出处. 最近项目需要播放视频且限制未观看部分的快进功能,找了两款js插件ckplayer和 ...
- 关于extern的使用
学的时候不认真总结,用的时候就一堆bug. 上回也是调extern调了半天,今天又犯老毛病. data 比如说是要用到的的在main函数中不断刷新的量.那么这个unsigned int data 要写 ...
- C++中绝对值的运算
首先,输入-42333380005结果取出来的绝对值却是616292955. 开始我以为是long型的取值范围有问题,就把long型全部改为long long型的了,结果还是一样,就觉得绝对值这个函数 ...
- Log4J2用法
一. 关于Log4J 2015年5月,Apache宣布Log4J 1.x 停止更新.最新版为1.2.17. 如今,Log4J 2.x已更新至2.7. 官方网址:http://logging.ap ...
- python 内置元祖子类
a = (zhangsan,20,nv,123@163.com) 输出姓名 a[0] 输出年龄 a[1] 输出性别 a[2] ..... 这样写可读性非常低 使用 内置元祖子类 from collec ...
- jstl标准标签库 其他标签
url操作标签 import 将另一个页面的内容引入到这个页面上来, 与include指令的区别: 这个标签可以引入其他项目中甚至网络上的资源 <c:import url="被导入的路 ...