线程的同步互斥机制(互斥锁)

一、线程的同步互斥

        临界区:访问共享资源的代码段

        临界资源:临界区中被读写的共享资源,即同时只能被一个进程访问的资源

        线程之间,如果要进行通信,需要引入同步互斥机制,避免产生竞态,保证任何时候都只有一个线程处理临界资源

二、互斥锁

2.1 工作原理

        对于要访问临界资源的线程,在访问前,都先执行申请上锁操作,若上锁成功,则进入临界区,访问临界区资源,直到退出临界区,解开互斥锁。若上锁失败,则线程进入休眠等待阶段,等待互斥锁被打开。

2.2 创建互斥锁

函数:pthread_mutex_init 

功能:创建并初始化一把互斥锁        

函数原型:

#include <pthread.h>
pthread_mutex_t fastmutex = PTHREAD_MUTEX_INITIALIZER;  //创建方式一
int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr);  //创建方式二

参数:

        pthread_mutex_t *mutex:存储申请以及初始化后的互斥锁

        pthread_mutexattr_t *mutexattr:互斥锁属性,可以定义互斥锁是用于进程还是线程。可以用pthread_mutexattr_init函数修改互斥锁属性,一般填NULL,代表用于线程

返回值:

        永远返回0;

2.3 上锁

函数:pthread_mutex_lock

功能:进行上锁,若有其他线程占用互斥锁,该函数会阻塞

函数原型:

#include <pthread.h>
int pthread_mutex_lock(pthread_mutex_t *mutex);

参数:

         pthread_mutex_t *mutex:指定要上的互斥锁

返回值:

        成功,返回0

        失败,返回非0

2.4 解锁

函数:pthread_mutex_unlock

功能:解开互斥锁

函数原型:

#include <pthread.h>
int pthread_mutex_unlock(pthread_mutex_t *mutex);

参数:

         pthread_mutex_t *mutex:指定要解开的互斥锁

返回值:

        成功,返回0

        失败,返回非0

2.5 销毁锁

函数:pthread_mutex_dsetroy

功能:销毁互斥锁

函数原型:

#include <pthread.h>
int pthread_mutex_destroy(pthread_mutex_t *mutex);

参数:

         pthread_mutex_t *mutex:指定要销毁的互斥锁

返回值:

         成功,返回0

        失败,返回非0

2.6 死锁

死锁出现的原因:拥有所资源的线程没有解开互斥锁,常有一下几种情况:

  1. 持有互斥锁的线程异常退出,没有释放锁资源
  2. 同一线程对一把互斥锁重复上锁
  3. 互斥锁交叉嵌套

示例代码(创建两个线程,一个线程负责打印,一个线程负责逆置)

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

//临界资源
char buf[] = "AAAA____BBBB";

//互斥锁变量  方式二
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

void* callback1(void* arg)
{
    while(1)
    {
        /******临界区************/
        //上锁
        pthread_mutex_lock(&mutex);

        printf("%s\n", buf);

        //解锁
        pthread_mutex_unlock(&mutex);
        /******临界区************/
    }
    pthread_exit(NULL);
}


void* callback2(void* arg)
{
    char temp = 0;

    while(1)
    {
        /******临界区************/
        //上锁
        pthread_mutex_lock(&mutex);

        for(int i=0; i<strlen(buf)/2; i++)
        {
            temp = buf[i];
            buf[i] = buf[strlen(buf)-1-i];
            buf[strlen(buf)-1-i] = temp;
        }

        //解锁
        pthread_mutex_unlock(&mutex);
        /******临界区************/
    }


    pthread_exit(NULL);
}


int main(int argc, const char *argv[])
{
    /*
    //创建互斥锁:方式一
    if(pthread_mutex_init(&mutex, NULL) != 0)
    {
        fprintf(stderr, "pthread_mutex_init failed __%d__\n", __LINE__);
        return -1;
    }
    */
                                                                                                                            

    pthread_t tid1, tid2;
    //创建线程:打印
    if(pthread_create(&tid1, NULL, callback1, NULL) != 0)
    {
        fprintf(stderr, "pthread_create failed\n");
        return -1;
    }
    pthread_detach(tid1);

    //创建线程:倒置
    if(pthread_create(&tid2, NULL, callback2, NULL) != 0)
    {
        fprintf(stderr, "pthread_create failed\n");
        return -1;
    }


    pthread_join(tid2, NULL);

    //销毁互斥锁
    pthread_mutex_destroy(&mutex);

    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_53478812/article/details/132111710