Linux线程同步之互斥体

Linux线程同步之互斥体

在学习之前已经了解了基本框架,那么现在就来学习一下细节操作

mutex锁的类型

PTHREAD_MUTEX_NORMAL(普通锁)

普通锁是互斥体默认属性。该怎用怎么用

正常使用实例:
#include<stdio.h>
#include<pthread.h>
#include<errno.h>
#include<stdlib.h>
#include<stdbool.h>
pthread_mutex_t mymutex;
int global=0;

void *thread_test(void *param){
	pthread_t threadID = pthread_self();
	printf("pthread start ,threadID:%d\n" , threadID);
	
	while(true){
		pthread_mutex_lock(&mymutex);
		printf("Mutex lock , global:%d\n" , global);
		global++;
		printf("Mutex unlock , global:%d\n" , global);
		pthread_mutex_unlock(&mymutex);
		sleep(1);
	}
	return NULL;
}
int main(int argc, const char *argv[])
{
	int i;
	pthread_mutexattr_t mutex_attr;
	pthread_mutexattr_init(&mutex_attr);
	pthread_mutexattr_settype(&mutex_attr, PTHREAD_MUTEX_NORMAL);
	pthread_mutex_init(&mymutex , &mutex_attr);

	pthread_t threadID[5];

	for( i =0 ; i < 5 ; i++ ){
		pthread_create(&threadID[i] , NULL , thread_test , NULL);
	}
	for(i =0 ; i < 5 ; i++ ){
		pthread_join(threadID[i] , NULL );
	}
	
	pthread_mutex_destroy(&mymutex );
	pthread_mutexattr_destroy(&mutex_attr);

	return 0;
}
加载打印:

​ 线程加入锁以后会对全局变量进行很好的保护。我没每一次使用对全局变量自增操作以后,由于它不是原子性的操作,汇编代码进行了多部处理,就会导致数据发生错乱。

​ 加入同步互斥锁机制以后,对全局变量数据很好的保护。

linux@linux:~/pthread$ ./a.out 
pthread start ,threadID:-1252107456
Mutex lock , global:0
Mutex unlock , global:1
pthread start ,threadID:-1243714752
Mutex lock , global:1
Mutex unlock , global:2
pthread start ,threadID:-1226929344
Mutex lock , global:2
Mutex unlock , global:3
pthread start ,threadID:-1235322048
Mutex lock , global:3
Mutex unlock , global:4
pthread start ,threadID:-1218536640
Mutex lock , global:4
Mutex unlock , global:5
Mutex lock , global:5
Mutex unlock , global:6
Mutex lock , global:6
Mutex unlock , global:7
Mutex lock , global:7
Mutex unlock , global:8
Mutex lock , global:8
Mutex unlock , global:9
Mutex lock , global:9
Mutex unlock , global:10
Mutex lock , global:10
Mutex unlock , global:11
Mutex lock , global:11
Mutex unlock , global:12
Mutex lock , global:12
Mutex unlock , global:13
Mutex lock , global:13
Mutex unlock , global:14
Mutex lock , global:14
Mutex unlock , global:15
单线程双重锁:
int main(int argc, const char *argv[])
{
	pthread_mutexattr_t mutex_attr;
	pthread_mutexattr_init(&mutex_attr);
	pthread_mutexattr_settype(&mutex_attr, PTHREAD_MUTEX_NORMAL);
	pthread_mutex_init(&mymutex , &mutex_attr);

	int ret = pthread_mutex_lock(&mymutex);
	printf("ret = %d\n" , ret);
	ret = pthread_mutex_lock(&mymutex);
	printf("ret = %d\n" , ret);
	
	
	pthread_mutex_destroy(&mymutex );
	pthread_mutexattr_destroy(&mutex_attr);
	return 0;
}

调试:

​ 发现程序被阻塞在了第一把锁上。如果将pthread_mutex_lock更换为trylock的话,会返回EBUSY=16错误码。

Starting program: /home/linux/pthread/a.out 
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/i386-linux-gnu/libthread_db.so.1".
ret = 0
^C
Program received signal SIGINT, Interrupt.
0xb7fdd424 in __kernel_vsyscall ()
(gdb) bt
#0  0xb7fdd424 in __kernel_vsyscall ()
#1  0xb7fb79e2 in __lll_lock_wait () at ../nptl/sysdeps/unix/sysv/linux/i386/i686/../i486/lowlevellock.S:144
#2  0xb7fb3267 in _L_lock_847 () from /lib/i386-linux-gnu/libpthread.so.0
#3  0xb7fb30a0 in __GI___pthread_mutex_lock (mutex=0x804a044 <mymutex>) at ../nptl/pthread_mutex_lock.c:79
#4  0x0804873d in main (argc=1, argv=0xbffff144) at 4_pthread_mutex.c:55

PTHREAD_MUTEX_ERRORCHECK(检错锁)

​ 使用lpthread_mutex_lock如果出错,会返回lEDEADLK = 35

​ 不会出现阻塞。

linux@linux:~/pthread$ ./a.out 
ret = 0
ret = 35

DEBUG:

单线程加两把锁

​ -----见上面的索引

多线程加锁

​ 如果程序出问题,多把锁都去强一把锁,没有进行锁保护会出现什么情况?

预先肯定是会被锁定的,所以我们使用检错锁。

pthread start ,threadID:-1252385984
ret = 0, -1252385984
pthread start ,threadID:-1243993280
pthread start ,threadID:-1235600576
pthread start ,threadID:-1227207872
pthread start ,threadID:-1218815168
EDEADLK , -1252385984
EDEADLK , -1252385984
EDEADLK , -1252385984

PTHREAD_MUTEX_RECURSIVE(嵌套锁)

使用该属性,可以对一把锁进行多重上锁,但是如果想进行别的线程,就需要把家的n把锁都要解除掉.

​ 如下程序,已经显示加了5把锁。

pthread start ,threadID:-1252951232
ret = 0, -1252951232
pthread start ,threadID:-1244558528
pthread start ,threadID:-1236165824
pthread start ,threadID:-1227773120
pthread start ,threadID:-1219380416
ret = 0, -1252951232
ret = 0, -1252951232
ret = 0, -1252951232
ret = 0, -1252951232
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值