13.线程互斥锁

当线程并发使用共享变量时,可能会产生不可预期的后果。为此,我们需要使用一定的手段来同步线程对共享变量的访问,互斥锁mutex就是一个解决办法。


下面的代码用于演示,多线程编程下不进行同步可能产生的问题。2个线程并发对全局变量进行递增操作50000次,我们预期该全局变量最终的值为100000,但是不同步的情况下,最终值基本不会是100000.


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

#define NLOOP 50000

int counter = 0;
pthread_mutex_t counter_mutex = PTHREAD_MUTEX_INITIALIZER;

void *doit(void *arg)
{
    int i, val, use_mutex = (int)arg;
    for(i = 0; i < NLOOP; i++)
    {
        // 访问counter前进行加锁
        // 当其它线程持有该锁的时候, 本线程会阻塞在这里直到锁可用
        if(use_mutex)
            pthread_mutex_lock(&counter_mutex);
        
        val = counter;
        printf("%x: %d\n", pthread_self(), val + 1);
        counter = val + 1;

        // 访问完毕解锁
        if(use_mutex)
            pthread_mutex_unlock(&counter_mutex);
    }    
    return NULL;
}

int main(int argc, char *argv[])
{
    pthread_t tid1, tid2;
    int use_mutex = 0;

    // 运行时传递任意一个参数,即表示使用互斥锁进行同步
    if(argc == 2)
        use_mutex = 1;

    // 创建2个线程来并发访问全局变量counter
    pthread_create(&tid1, NULL, doit, (void *)use_mutex);
    pthread_create(&tid2, NULL, doit, (void *)use_mutex);

    pthread_join(tid1, NULL);
    pthread_join(tid2, NULL);
    // 待2个线程结束后, 输出最终的counter值
    printf("final counter: %d\n", counter);
}

上述代码编译后运行,不加参数的情况下不会使用互斥锁同步,传递任意一个参数即使用互斥锁同步

我们发现,不同步的情况下结果介于[50000,10000]之间,同步的情况下结果为100000


最后,我们测试一下互斥锁带来的开销

不使用互斥锁的情况下,程序的运行时间如下

real	0m1.023s
user	0m0.064s
sys	0m0.304s

使用互斥锁

real	0m1.066s
user	0m0.076s
sys	0m0.280s

发现互斥锁上锁带来的开销并没有太大

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值