多线程的互斥机制

来源:互联网 发布:阿里云自定义监控实例 编辑:程序博客网 时间:2024/06/06 00:59

互斥:任一时刻,只有一个线程进入临界区访问临界资源且访问时具有原子性。
互斥机制的实现:互斥锁。
虽然多个线程共享同一地址空间,使得多个线程之间可以很方便的进行通信,但是当多个线程访问同一临界资源时,很可能出现访问冲突的问题。所以此时就要引入同步与互斥机制(本篇主要讲解互斥机制)
来看下面的代码:

#include<stdio.h>#include<pthread.h>int g_val = 0;void* thread(void* _val){    int val = 0;    int count = 5000;    while(count--)    {        val = g_val;        printf("tid:%u,Mycount = %d\n",pthread_self(),val);        g_val = val+1;    }    return (void *)0;}int main(){    pthread_t tid1,tid2;    pthread_create(&tid1,NULL,thread,NULL);    pthread_create(&tid2,NULL,thread,NULL);    sleep(3);    void *val;    pthread_join(tid1,&val);    pthread_join(tid2,&val);    printf("g_val = %d\n",g_val);    return 0;}

再看看运行结果:
这里写图片描述
两个线程都对全局变量g_val进行了5000次的++操作,其值应该为10000,但是此时却为5246,这是因为创建的两个线程同时对临界资源访问时产生了干扰。为了避免这种情况,就要加入互斥锁(mutex).
互斥锁:保证共享资源数据的完整性。互斥锁主要用来保护临界资源,每个临界资源都由一个互斥锁来保护,任何时刻最多只能有一个线程访问该资源。线程必须先获得互斥锁才能访问临界资源,访问完临界资源后释放该锁。如果无法获得锁,线程会阻塞直到获得锁为止。
定义一个互斥锁:Mutex由pthread_mutex_t变量来定义。
(1)使用宏定义PTHREAD_MUTEX_INITIALIZER来初始化互斥锁:pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIZER
(2)int pthread_mutex_init(pthread_mutex_t *restrict mutex,const pthread_mutexattr_t *restrict attr);//attr:互斥锁的属性,一般使用默认值为NULL
加锁:int pthread_mutex_lock(pthread_mutex_t *mutex);//阻塞式
加锁:int pthread_mutex_trylock(pthread_mutex_t *mutex);//非阻塞式
解锁:int pthread_mutex_unlock(pthread_mutex_t *mutex);
销毁互斥锁:int pthread_mutex_destroy(pthread_mutex_t *mutex);

一个线程可以调用pthread_mutex_lock获得Mutex,如果这时另一个线程已经调用pthread_mutex_lock获得了该Mutex,则当前线程需要挂起等待(即阻塞式获得锁),直到另一个线程调用pthread_mutex_unlock释放Mutex,当前线程被唤醒,才能获得该Mutex并继续执行。

如果一个线程既想获得锁,又不想挂起等待,可以调用pthread_mutex_trylock,如果Mutex已经被另一个线程获得,这个函数会失败返回EBUSY,而不会使线程挂起等待(即非阻塞式获得锁)。

对上面的程序加入互斥锁:

#include<stdio.h>#include<pthread.h>pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIZER//定义一个互斥锁int g_val = 0;void* thread(void* _val){    int val = 0;    int count = 5000;    while(count--)    {        pthread_mutex_lock(&mutex);//加锁        val = g_val;        printf("tid:%u,Mycount = %d\n",pthread_self(),val);        g_val = val+1;        pthread_mutex_unlock(&mutex);//解锁    }    return (void *)0;}int main(){    pthread_t tid1,tid2;    pthread_create(&tid1,NULL,thread,NULL);    pthread_create(&tid2,NULL,thread,NULL);    sleep(3);    void *val;    pthread_join(tid1,&val);    pthread_join(tid2,&val);    pthread_mutex_destroy(&mutex);//销毁互斥锁    printf("g_val = %d\n",g_val);    return 0;}

这里写图片描述

0 0