多线程的同步和互斥

多线程的同步和互斥

一、互斥锁的概念

为了实现线程对资源的合理访问,并且在访问的过程中不会出现线程竞争的情况,Linux系统就提供了一种实现互斥机制的方案,就是互斥锁

互斥锁的本质是一个二值信号量,任何一条线程要开始运行互斥区间的代码,都必须先获取互斥锁,如果其中一条线程抢先获取了互斥锁之后,其余线程就无法再次获取了,相当于给相关的资源加了把锁,直到使用者主动解锁,其余线程方可有机会获取这把锁。

二、互斥锁的使用

(1) 初始化互斥锁

可以看到,Linux系统中提供了一个叫做pthread_mutex_init函数接口,用户利用该函数就可以对互斥量进行初始化,注意:没有经过初始化的互斥量是不能直接使用的

互斥量的本质就是一个变量,变量的类型是pthread_mutex_t,要注意对该变量的赋值,需要赋值为PTHREAD_MUTEX_INITIALIZER,再去调用pthread_mutex_init()即可。

当然,除了调用函数接口实现互斥锁的初始化之外,用户也可以直接定义一个全局变量,这样其他线程都可以使用互斥锁,但是记得对变量进行初始化为PTHREAD_MUTEX_INITIALIZER。

(2) 上锁解锁操作

int pthread_mutex_lock(pthread_mutex_t *mutex);//上锁,失败则阻塞
int pthread_mutex_trylock(pthread_mutex_t *mutex);//尝试上锁,失败则退出
int pthread_mutex_unlock(pthread_mutex_t *mutex);//解锁

注意:不要在同一个线程中对已经上锁的互斥量重新上锁,这样会导致死锁出现,应该避免该情况出现,上锁之后应该在使用完资源后及时进行解锁。

(3)练习

练习:创建一个进程,在主线程中创建一个子线程,主线程和子线程都会使用相同的临界资源(全局变量),要求线程之前使用互斥锁实现资源的互斥访问。

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

//全局变量
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
int a =0;
//线程A
void *task(void *arg)
{
    //1.上锁
    pthread_mutex_lock(&mutex);
    //2.访问
    a=2;
    printf("I am thread,a=%d\n",a);
    //3.解锁
    pthread_mutex_unlock(&mutex);
}


int main()
{
    //1.创建线程
    pthread_t thread;
    pthread_create(thread,NULL,task,NULL);
    //2.初始化信号量
    pthread_mutex_init(&mutex,NULL);
    while(1)
    {
        //1.上锁
        pthread_mutex_lock(&mutex);
        //2.访问
        a=1;
        printf("I am main thread,a=%d\n",a);
        //3.解锁
        pthread_mutex_unlock(&mutex);
    }
    

    return 0;
}
posted @ 2025-04-10 22:08  骗人就变小狗  阅读(262)  评论(0)    收藏  举报