多线程的互斥机制

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

#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
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值