互斥量--linux多线程的运用

一、什么是互斥量

互斥量是另一种用于多线程中的同步访问方法,它允许程序锁住某个对象,使得每次只能有一个线程访问它。


二、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。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值