当我们需要控制对共享资源的存取的时候,可以用一种简单的加锁的方法来控制。我们可以创建一个读/写程序,它们共用一个共享缓冲区,使用互斥锁来控制对缓冲区的存取。 

  函数 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——线程同步-互斥锁的更多相关文章

  1. 网络编程并发 多进程 进程池,互斥锁,信号量,IO模型

    进程:程序正在执行的过程,就是一个正在执行的任务,而负责执行任务的就是cpu 操作系统:操作系统就是一个协调.管理和控制计算机硬件资源和软件资源的控制程序. 操作系统的作用: 1:隐藏丑陋复杂的硬件接 ...

  2. Linux多线程编程——多线程与线程同步

    多线程 使用多线程好处: 一.通过为每种事件类型的处理单独分配线程,可以简化处理异步事件的代码,线程处理事件可以采用同步编程模式,启闭异步编程模式简单 二.方便的通信和数据交换 由于进程之间具有独立的 ...

  3. Posix线程编程指南(3) 线程同步

    互斥锁 尽管在Posix Thread中同样可以使用IPC的信号量机制来实现互斥锁mutex功能,但显然semphore的功能过于强大了,在Posix Thread中定义了另外一套专门用于线程同步的m ...

  4. Linux/Unix编程中的线程安全问题【转】

    转自:http://blog.csdn.net/zhengzhoudaxue2/article/details/6432984 在目前的计算机科学中,线程是操作系统调度的最小单元,进程是资源分配的最小 ...

  5. Posix线程编程指南(4) 线程终止

    线程终止方式 一般来说,Posix的线程终止有两种情况:正常终止和非正常终止.线程主动调用pthread_exit()或者从线程函数中return都将使线程正常退出,这是可预见的退出方式:非正常终止是 ...

  6. Linux多线程(三)(同步互斥)

    1. 线程的同步与互斥 1.1. 线程的互斥 在Posix Thread中定义了一套专门用于线程互斥的mutex函数.mutex是一种简单的加锁的方法来控制对共享资源的存取,这个互斥锁只有两种状态(上 ...

  7. python并发编程之多进程(二):互斥锁(同步锁)&进程其他属性&进程间通信(queue)&生产者消费者模型

    一,互斥锁,同步锁 进程之间数据不共享,但是共享同一套文件系统,所以访问同一个文件,或同一个打印终端,是没有问题的, 竞争带来的结果就是错乱,如何控制,就是加锁处理 part1:多个进程共享同一打印终 ...

  8. Posix线程编程指南(1) 线程创建与取消

    线程创建 1.1 线程与进程 相对进程而言,线程是一个更加接近于执行体的概念,它可以与同进程中的其他线程共享数据,但拥有自己的栈空间,拥有独立的执行序列.在串行程序基础上引入线程和进程是为了提高程序的 ...

  9. linux应用编程之进程间同步

    一.描述 在操作系统中,异步并发执行环境下的一组进程,因为相互制约关系,进而互相发送消息.互相合作.互相等待,使得各进程按一定的顺序和速度执行,称为进程间的同步.具有同步关系的一组并发进程,称为合作进 ...

随机推荐

  1. java的环境配置

    java的安装 1,进入官网  https://www.oracle.com/index.html 2.Menu -> Downloads -> java ->  all Java ...

  2. python中 函数名加括号与不加括号

    加括号是返回函数的结果,不加括号相当于函数的调用.

  3. 1.微信小程序里如何设置当地时间?

    方法一: 1.效果图 2.wxml code: <!--pages/index/index.wxml--> <text>当前时间:{{time}}</text> & ...

  4. oracle用户的管理

    用户登陆 sql>conn 用户名/密码 给用户修改密码 如果给自己修改密码可以直接使用 sql>password 用户名; 如果给别人修改密码则需要具有dba的权限,或是拥有alter ...

  5. kudu导入文件(基于impala)

    kudu是cloudera开源的运行在hadoop平台上的列式存储系统,拥有Hadoop生态系统应用的常见技术特性,运行在一般的商用硬件上,支持水平扩展,高可用,集成impala后,支持标准sql语句 ...

  6. CentOS 7 无法yum安装解决方法

    1)下载repo文件 wget http://mirrors.aliyun.com/repo/Centos-7.repo 2)备份并替换系统的repo文件 .repo /etc/yum.repos.d ...

  7. Python 高阶函数map(),filter(),reduce()

    map()函数,接收两个参数,一个是函数,一个是序列,map()把传入的函数依次作用于序列的每个元素,并把结果作为新的序列返回: aa = [1, 2, 3, 4, 5] print("ma ...

  8. matlab中变量问题——readonly 索引超出矩阵维度 workspacefunc 215

    matlab程序运行过程中会出现如上提示,在网上检索未果,键入dbstop if error语句也无法定错误之处,就想这个错误不是一般的错误. 通过间隔打断点的方式最后定位错误为一句exist = f ...

  9. vscode的环境变量code

    vscode的安装路径 本质:vscode的安装路径/Applications/Visual Studio Code.app/Contents/Resources/app/bin 下面有code可执行 ...

  10. kettle学习笔记(二)——kettle基本使用

    一.子程序功能和启动方式介绍 Spoon.bat: 图形界面方式启动作业和转换设计器. Pan.bat: 命令行方式执行转换. Kitchen.bat: 命令行方式执行作业. Carte.bat: 启 ...