互斥锁mutex简单应用

写了段小代码学习互斥锁的作用。
互斥锁的作用:在编程中,引入了对象互斥锁的概念,来保证共享数据操作的完整性。

思路是用2个线程对同一个内存位置buffer,进行写和读,为了防止2个线程同时对buffer进行修改,用同一把互斥锁来限制。
写操作简化为把buffer修改为’W’,读简化为把buffer修改为’R’。
在对buffer进行修改之前用pthread_mutex_lock()进行加锁,修改后pthread_mutex_unlock()解锁。
代码如下:

#include<stdio.h>
#include<pthread.h>
#include<unistd.h>

void reader_function(void);
void writer_function(void);
pthread_mutex_t mtx;    //声明互斥锁mtx
char buffer;

int main(void)
{
	pthread_mutex_init(&mtx, NULL); //用默认属性初始化一个互斥锁对象
	
	pthread_t reader;	//创建reader线程
	pthread_create(&reader, NULL, (void*) reader_function, NULL);
	
	writer_function();//运行writer
}

void writer_function(void)
{
	int i;
	for(i=0; i<2; i++)
	{
		pthread_mutex_lock(&mtx);	//对mtx上锁
		printf("Writer %d 已经对mtx上锁了. \r\n",i);
		buffer = 'W';
		printf("Writer %d 把buff修改为%c,\r\n",i, buffer);
		printf("Writer %d 解锁mtx. \r\n\n\n", i);
		pthread_mutex_unlock(&mtx);//解锁
		sleep(1);
	}
}


void reader_function(void)
{
	int i;
	for(i=0; i<2; i++)
	{
		pthread_mutex_lock(&mtx);	//对mtx上锁
		printf("Reader %d 已经对mtx上锁了. \r\n",i);
		buffer = 'R';
		printf("Reader %d 把buff修改为%c,\r\n",i, buffer);
		printf("Reader %d 解锁mtx. \r\n\n\n", i);
		pthread_mutex_unlock(&mtx);//解锁
		sleep(1);
	}
}

运行结果为:
在这里插入图片描述

进一步测试,把writer 的解锁注释掉,

void writer_function(void)
{
    int i;
    for(i=0; i<2; i++)
    {
        pthread_mutex_lock(&mtx);   //对mtx上锁
        printf("Writer %d 已经对mtx上锁了. \r\n",i);
        buffer = 'W';
        printf("Writer %d 把buff修改为%c,\r\n",i, buffer);
        //printf("Writer %d 解锁mtx. \r\n\n\n", i);
        //pthread_mutex_unlock(&mtx);//解锁
        sleep(1);
    }
}

运行结果如下:
在这里插入图片描述
可见,writer 0 修改了buffer后没有解锁mtx,而同线程的writer 1在sleep之后又对mtx加锁,造成死锁,线程一直挂起,reader 也因没办法加锁而一直被挂起。

再上面的基础上把reader 的加锁注释掉:

void reader_function(void)
{
	int i;
	for(i=0; i<2; i++)
	{
		//pthread_mutex_lock(&mtx);	//对mtx上锁
		//printf("Reader %d 已经对mtx上锁了. \r\n",i);
		buffer = 'R';
		printf("Reader %d 把buff修改为%c,\r\n",i, buffer);
		printf("Reader %d 解锁mtx. \r\n\n\n", i);
		pthread_mutex_unlock(&mtx);//解锁
		sleep(1);
	}
}

运行结果如下:
在这里插入图片描述
结果说明了writer 线程对mtx的加锁可以在reader 线程里解锁。

再把reader里的解锁注释掉:

void reader_function(void)
{
	int i;
	for(i=0; i<2; i++)
	{
		//pthread_mutex_lock(&mtx);	//对mtx上锁
		//printf("Reader %d 已经对mtx上锁了. \r\n",i);
		buffer = 'R';
		printf("Reader %d 把buff修改为%c,\r\n",i, buffer);
		//printf("Reader %d 解锁mtx. \r\n\n\n", i);
		//pthread_mutex_unlock(&mtx);//解锁
		sleep(1);
	}
}

运行结果如下
在这里插入图片描述

reader现在跟互斥锁没关系,在writer死锁一直挂起后,reader不受影响的运行,在这里可以看出多线程程序的优点。

小结:互斥锁可以保证同一资源在同一时间内只能被一个线程使用。
使用完资源后要记得解锁,先后调用2次加锁(中间没有解锁)会导致死锁,线程一直挂起,其他使用此锁的线程也会受到影响。
A线程加的锁能被B线程解锁。
对未加锁的互斥锁进行解锁操作没有意义。

猜你喜欢

转载自blog.csdn.net/qq_40541268/article/details/84287692