线程同步——互斥锁

参考学习资料:进程线程互斥与同步

1. 互斥锁(互斥量)

1.1 变量类型:互斥锁类型

创建一把锁:

//变量类型       变量名
pthread_mutex_t mutex

1.2 互斥锁的特点

多个线程访问共享数据时是串行的,避免数据混乱。

1.3 互斥锁缺点

效率低(由于所有的并行都转串行,所以效率比较低)。

1.4 互斥锁使用步骤

  1. 创建互斥锁:
    pthread_mutex_t mutex;

     

  2. 初始化这把锁:

    pthread_mutex_init(&mutex,NULL);

    (可以理解为此时mutex=1,有一把锁可以用)

  3. 寻找共享资源:操作共享资源的代码之前加锁

    pthread_mutex_lock(&mutex);

    被lock和unlock锁住的代码段一般称为临界区,在避免资源冲突的前提下,临界区越小越好。(lock之后,可以理解为mutex--,即mutex=0,此时无可用锁)

  4. 解锁:

    pthread_mutex_unlock(&mutex)

    (解锁之后,mutex=1,有一把锁可以使用)

1.5 互斥锁相关函数

  1. 初始化互斥锁
    pthread_mutex_init(
    	pthread_mutex_t* mutex,    //互斥锁锁对象
    	const pthread_mutexattr_t* sttr  //初始化参数,一般默认NULL
    );
    

     

  2. 销毁互斥锁

    pthread_mutex_destroy(pthread_mutex_t *mutex);

     

  3. 加锁

    pthread_mutex_lock(pthread_mutex_t* mutex);

    加锁时,如果锁没有被锁上,当前线程会将这把锁锁上;如果锁被锁上了,当前线程阻塞,锁被打开之后,线程解除阻塞。

  4. 尝试加锁,失败返回,不阻塞

    pthread_mutex_trylock(pthread_mutex_t *mutex);

    锁没有锁上时,当前线程给这把锁加锁;锁上了,不会阻塞,而是直接返回。

    if(pthread_mutex_trylock(&mutex)==0)
    {
    	//尝试加锁,并且成功了
    	//访问共享资源
    }
    else{
    	//错误处理
        //或者稍等一会,再次尝试加锁
    }
    

     

  5. 解锁

    pthread_mutex_unlock(pthread_mutex_t* mutex);

    如果使用互斥锁,所有访问相同共享资源的线程都需要加锁和解锁。

2. 代码示例(C语言)

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <pthread.h>
#include <string.h>

#define MAX 10000
int number;
//创建一把互斥锁
pthread_mutex_t mutex; 
//线程处理函数 A
void* funcA_num(void* arg){
	int i=0;
	for(i=0;i<MAX;i++){
		//访问全局变量之前加锁
		//如果mutex被锁上了,线程阻塞在这一行 
		pthread_mutex_lock(&mutex); 
		int cur=number;
		cur++;
		number=cur;
		printf("Thread A, id = %lu, number = %d\n",pthread_self(),number);
		//操作完成之后,解锁 
		pthread_mutex_unlock(&mutex); 
		usleep(10);
	}
	return NULL;
} 
//线程处理函数 B
void* funcB_num(void* arg){
	int i=0;
	for(;i<MAX;i++){
		//访问全局变量之前加锁
		//如果mutex被锁上了,线程阻塞在这一行 
		pthread_mutex_lock(&mutex); 
		int cur=number;
		cur++;
		number=cur;
		printf("Thread B, id = %lu, number = %d\n",pthread_self(),number);
		//操作完成之后,解锁 
		pthread_mutex_unlock(&mutex); 
		usleep(10);
	}
	return NULL;
} 

int main(int argc, const char* argv[]){
	pthread_t p1,p2;
	//对互斥锁做初始化
	pthread_mutex_init(&mutex,NULL);
	//创建两个线程 
	pthread_create(&p1,NULL,funcA_num,NULL);
	pthread_create(&p2,NULL,funcB_num,NULL);
	//阻塞回收线程的资源 
	pthread_join(p1,NULL);
	pthread_join(p2,NULL);
	
	//释放互斥对象
	pthread_mutex_destroy(&mutex); 
	return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值