天天看点

【Linux多线程】线程同步之互斥锁

互斥锁概念:锁机制是同一时刻只允许一个线程执行一个关键部分的代码。

执行步骤说明

1. 初始化锁

int pthread_mutex_init(pthread_mutex_t *mutex,const pthread_mutex_attr_t *mutexattr);

其中参数 mutexattr 用于指定锁的属性(见下),如果为NULL则使用缺省属性。

互斥锁的属性在创建锁的时候指定,在LinuxThreads实现中仅有一个锁类型属性,不同的锁类型在试图对一个已经被锁定的互斥锁加锁时表现不同。当前有四个值可供选择:

(1)PTHREAD_MUTEX_TIMED_NP,这是缺省值,也就是普通锁。当一个线程加锁以后,其余请求锁的线程将形成一个等待队列,并在解锁后按优先级获得锁。这种锁策略保证了资源分配的公平性。

(2)PTHREAD_MUTEX_RECURSIVE_NP,嵌套锁,允许同一个线程对同一个锁成功获得多次,并通过多次unlock解锁。如果是不同线程请求,则在加锁线程解锁时重新竞争。

(3)PTHREAD_MUTEX_ERRORCHECK_NP,检错锁,如果同一个线程请求同一个锁,则返回EDEADLK,否则与PTHREAD_MUTEX_TIMED_NP类型动作相同。这样就保证当不允许多次加锁时不会出现最简单情况下的死锁。

(4)PTHREAD_MUTEX_ADAPTIVE_NP,适应锁,动作最简单的锁类型,仅等待解锁后重新竞争。

2. 阻塞加锁

int pthread_mutex_lock(pthread_mutex *mutex);

3. 非阻塞加锁

int pthread_mutex_trylock( pthread_mutex_t *mutex);

该函数语义与 pthread_mutex_lock() 类似,不同的是在锁已经被占据时返回 EBUSY 而不是挂起等待。

4. 解锁(要求锁是lock状态,并且由加锁线程解锁)

int pthread_mutex_unlock(pthread_mutex *mutex);

5. 销毁锁(此时锁必需unlock状态,否则返回EBUSY)

int pthread_mutex_destroy(pthread_mutex *mutex);

代码:

#include <stdio.h>
#include <pthread.h>
#include <sched.h>
#include <unistd.h>
 
//对临界区的保护问题
void *fun1(void *arg);
void *fun2(void *arg);
 
int buffer = 0;
pthread_mutex_t mutex;
int running = 1;
 
int main(void )
{
    pthread_t pt1;
    pthread_t pt2;
 
    pthread_mutex_init(&mutex,NULL);
 
    pthread_create(&pt1,NULL,fun1,(void*)&running);
    pthread_create(&pt2,NULL,fun2,(void*)&running);
 
    usleep(1000);
    running=0;
    pthread_join(pt1,NULL);
    pthread_join(pt2,NULL);
    pthread_mutex_destroy(&mutex);
    return 0;
}
 
void *fun1(void *arg)
{
    while(*(int *)arg)
    {
		//pthread_mutex_lock(&mutex);
		printf("in fun1 before add , buffer is : %d\n",buffer);
		usleep(2);
		buffer++;
		printf("in fun1 after sleep and add one ,now buffer is %d \n",buffer);
		//pthread_mutex_unlock(&mutex);
		usleep(2);
    }
}
 
void *fun2(void *arg)
{
    while(*(int *)arg)
    {
		//pthread_mutex_lock(&mutex);
		printf("in fun2 before add , buffer is : %d\n",buffer);
		usleep(2);
		buffer++;
		printf("in fun2 after sleep and add one ,now buffer is %d \n",buffer);
		//pthread_mutex_unlock(&mutex);
		usleep(2);
    }
 
}
           

gcc执行结果:

(1)添加互斥锁结果

【Linux多线程】线程同步之互斥锁

(2)删除互斥锁的结果

【Linux多线程】线程同步之互斥锁

继续阅读