互斥量--linux多线程的运用
2015-12-29 15:37
417 查看
一、什么是互斥量
互斥量是另一种用于多线程中的同步访问方法,它允许程序锁住某个对象,使得每次只能有一个线程访问它。
二、linux下的互斥量函数
它们的意义就如它们的名字所示的那样,分别是初始化一个互斥量、对一个互斥量上锁、对一个互斥量解锁。成功时返回0,失败时返回错误代码,它们并不设置errno。
pthread_mutex_init函数中的参数mutexattr指定互斥量的属性,在这里我们并不关心互斥量的属性,所以把它设置为NULL,使用默认属性即可。同样的,pthread_mutex_lock和pthread_mutex_unlock都是原子操作,如果一个线程调用pthread_mutex_lock试图锁住互斥量,而该互斥量,又被其他线程锁住(占用),则该线程的pthread_mutex_lock调用就会阻塞,直到其他线程对该互斥量进行解锁,该线程才能获得该互斥量,pthread_mutex_lock调用才会返回。
注意,使用互斥量的默认属性,如果程序试图对一个已经加锁的互斥量调用pthread_mutex_lock,程序就会阻塞,而又因为拥有互斥量的这个线程正是现在被阻塞的线程,所以这个互斥量就永远不会被解锁,也就是说,程序就会进入死锁的状态。在使用时要多加注意,确保在同一个线程中,对加锁的互斥再次进行加锁前要对其进行解锁。
三、一个简单例子的运用。
本例程中,进程含有两个线程,两个线程分别通过lock和unlock互斥量来相互制约运行,代码如下:
程序运行结果如下:
例程解析:
(1).程序(主线程)首先通过pthread_mutex_init函数创建了一个work_mutex互斥量,接着又创建一个thread_function线程,并且thread_function线程一创建后,就进行pthread_mutex_lock互斥量,所以除非主线程有解锁动作(pthread_mutex_unlock),不然thread_function线程就一直停留在此来等待获得锁资源。我们通过主线程和子线程来回解锁两次来观察互斥量的运用,因此设了一个全局变量num来观察。
(2).程序(主线程)创建完thread_function线程后,立马锁将work_mutex互斥量锁住,因此由(1)分析,thread_function线程停留在pthread_mutex_lock(&work_mutex)语句。因此程序(主线程)继续运行打印出lock1,程序(主线程)打印完lock1后,通过pthread_mutex_unlock将互斥量进行解锁,并紧接着打印出unlock1,然后sleep一段时间,这里sleep一段时间,主要是为了给thread_function线程有足够时间获得锁资源。由于程序(主线程)将互斥量解锁释放了,则thread_function线程获得锁资源,因此thread_function线程开始执行,打印出num值,和wait...,并通过sleep停止5s钟。
(3).thread_function线程开始打印出num值至sleep(5)后这段时间,程序(主线程)运行到pthread_mutex_lock(&work_mutex)语句,由于这个时候的锁资源被thread_function线程获得,因此程序(主线程)一直停留在此处,等待获得锁资源。
(4).当thread_function线程sleep(5)后,执行pthread_mutex_unlock(&work_mutex),将锁资源释放然后sleep一段时间,这里sleep一段时间,主要是为了给程序(主线程)有足够时间获得锁资源,则这时程序(主线程)获得锁资源继续运行,而thread_function线程又执行到pthread_mutex_lock(&work_mutex)语句,由于此时锁资源被程序(主线程)获得,所以thread_function线程又停留到此处。
(5).接下去反复(3)、(4)步骤,直至打印出finsh。
互斥量是另一种用于多线程中的同步访问方法,它允许程序锁住某个对象,使得每次只能有一个线程访问它。
二、linux下的互斥量函数
int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr); int pthread_mutex_lock(pthread_mutex_t *mutex); int pthread_mutex_unlock(pthread_mutex_t *mutex); int pthread_mutex_destroy(pthread_mutex_t *mutex); </span>
它们的意义就如它们的名字所示的那样,分别是初始化一个互斥量、对一个互斥量上锁、对一个互斥量解锁。成功时返回0,失败时返回错误代码,它们并不设置errno。
pthread_mutex_init函数中的参数mutexattr指定互斥量的属性,在这里我们并不关心互斥量的属性,所以把它设置为NULL,使用默认属性即可。同样的,pthread_mutex_lock和pthread_mutex_unlock都是原子操作,如果一个线程调用pthread_mutex_lock试图锁住互斥量,而该互斥量,又被其他线程锁住(占用),则该线程的pthread_mutex_lock调用就会阻塞,直到其他线程对该互斥量进行解锁,该线程才能获得该互斥量,pthread_mutex_lock调用才会返回。
注意,使用互斥量的默认属性,如果程序试图对一个已经加锁的互斥量调用pthread_mutex_lock,程序就会阻塞,而又因为拥有互斥量的这个线程正是现在被阻塞的线程,所以这个互斥量就永远不会被解锁,也就是说,程序就会进入死锁的状态。在使用时要多加注意,确保在同一个线程中,对加锁的互斥再次进行加锁前要对其进行解锁。
三、一个简单例子的运用。
本例程中,进程含有两个线程,两个线程分别通过lock和unlock互斥量来相互制约运行,代码如下:
<span style="font-size:18px;">#include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <string.h> #include <pthread.h> #include <semaphore.h> void *thread_function(void *arg);//线程函数 pthread_mutex_t work_mutex; //定义一个互斥量 #define WORK_SIZE 1024 char work_area[WORK_SIZE]; int time_to_exit = 0; int num=0; int main() { int res; pthread_t a_thread; void *thread_result; res = pthread_mutex_init(&work_mutex, NULL); if (res != 0) { perror("Mutex initialization failed"); exit(EXIT_FAILURE); } res = pthread_create(&a_thread, NULL, thread_function, NULL); if (res != 0) { perror("Thread creation failed"); exit(EXIT_FAILURE); } pthread_mutex_lock(&work_mutex); printf("lock1\n"); sleep(1); pthread_mutex_unlock(&work_mutex); printf("unlock1\n"); sleep(1); pthread_mutex_lock(&work_mutex); printf("lock2\n"); sleep(1); pthread_mutex_unlock(&work_mutex); printf("unlock2\n"); sleep(1); pthread_mutex_lock(&work_mutex); printf("finsh\n"); pthread_mutex_destroy(&work_mutex); exit(EXIT_SUCCESS); } void *thread_function(void *arg) { while(num<2) { pthread_mutex_lock(&work_mutex); printf("num=%d\n",++num); printf("wait..."); sleep(5); pthread_mutex_unlock(&work_mutex); sleep(1); } pthread_exit(0); } </span>
程序运行结果如下:
例程解析:
(1).程序(主线程)首先通过pthread_mutex_init函数创建了一个work_mutex互斥量,接着又创建一个thread_function线程,并且thread_function线程一创建后,就进行pthread_mutex_lock互斥量,所以除非主线程有解锁动作(pthread_mutex_unlock),不然thread_function线程就一直停留在此来等待获得锁资源。我们通过主线程和子线程来回解锁两次来观察互斥量的运用,因此设了一个全局变量num来观察。
(2).程序(主线程)创建完thread_function线程后,立马锁将work_mutex互斥量锁住,因此由(1)分析,thread_function线程停留在pthread_mutex_lock(&work_mutex)语句。因此程序(主线程)继续运行打印出lock1,程序(主线程)打印完lock1后,通过pthread_mutex_unlock将互斥量进行解锁,并紧接着打印出unlock1,然后sleep一段时间,这里sleep一段时间,主要是为了给thread_function线程有足够时间获得锁资源。由于程序(主线程)将互斥量解锁释放了,则thread_function线程获得锁资源,因此thread_function线程开始执行,打印出num值,和wait...,并通过sleep停止5s钟。
(3).thread_function线程开始打印出num值至sleep(5)后这段时间,程序(主线程)运行到pthread_mutex_lock(&work_mutex)语句,由于这个时候的锁资源被thread_function线程获得,因此程序(主线程)一直停留在此处,等待获得锁资源。
(4).当thread_function线程sleep(5)后,执行pthread_mutex_unlock(&work_mutex),将锁资源释放然后sleep一段时间,这里sleep一段时间,主要是为了给程序(主线程)有足够时间获得锁资源,则这时程序(主线程)获得锁资源继续运行,而thread_function线程又执行到pthread_mutex_lock(&work_mutex)语句,由于此时锁资源被程序(主线程)获得,所以thread_function线程又停留到此处。
(5).接下去反复(3)、(4)步骤,直至打印出finsh。
相关文章推荐
- Vmware 安装CentOS7时连不上网问题的解决
- 启动HDFS遇到问题
- Linux下mysql5.7安装
- linux消耗CPU的shell脚本
- Centos7-NFS server - 笔记
- Desktop Entry,关于Linux如何创建桌面快捷方式
- 在阿里云的CentOS环境中安装django
- linux系统dist-upgrade和upgrade的区别
- Synergy工具 共享Windows系统电脑Linux系统电脑 鼠标键盘
- synergy在Windows和Linux下使用全攻略(多台PC共享一套键盘鼠标)
- CentOS7的VmWare tool的安装
- linux 利用export 更新系统环境变量
- Linux流量监控工具 - iftop
- 注意windows和linux下文件编码问题!
- Linux iperf 用法介绍
- Linux和Windows文件编码格式区别
- Linux ntp配置
- 系统登录与退出
- linux下面C 利用openssl的AES库加密,解密
- Curl命令