Mutex的滥用

对于Mutex和Semaphore这两种机制最多的解释为:

  • Mutex:用于线程间的互斥
  • Semaphore:用于线程间的同步

这个定义很准确,然而,在经典生产者消费者模型中却经常出现mutex滥用的例子,例如这样场景:一个生产者,一个消费者,多块缓存:buffer[BUFFER_SIZE],很多网上的实现为:

Semaphore s_full(0);
Sempahore s_empty(BUFFER_SIZE):
Mutex mutex;
int in_idx=0;
int out_idx=0;
<生产者>
while(true)
{
    s_empty.unsignal();
    mutex.lock();
    buffer.put(in_idx);
    in_idx = (in_idx + 1)%BUFFERIZE;
    mutex.unlock();
    s_full.signal();
}
<消费者>
while(true)
{
    s_full.unsignal();
    mutex.lock();
    buffer.get(out_idx);
    out_idx = (out_idx + 1)%BUFFERIZE;
    mutex.unlock();
    s_empty.signal();
}

其实代码逻辑上没错,但是mutex却是多余的,注意场景中semaphore的控制决定了两个线程不会同时操作同一处缓存,也就是说按照代码对buffer的访问并不需要互斥。另两种场景:一个buffer,一个生产者,一个消费者或者一个buffer,多个生产者,多个消费者这时也是不需要使用mutex互斥的。


但是:像 多个buffer,多个生产者,多个消费者  的情况,却需要对buffer互斥访问,如果是多个buffer,实际上就是需要保证对in_idx和out_idx的互斥访问,这种情况下我们可以对in_idx和out_idx的访问(get,set)放置于临界区内,而对buffer的操作(put,get)放置于临界区之外,可以提高并发率。代码如下(From Internet)

Semaphore s_full(0);
Sempahore s_empty(BUFFER_SIZE):
Mutex mutex;
int in_idx=0;
int out_idx=0;
int getEmptyIndex()
{
    rt = in_idx;
    in_idx = (in_idx + 1)%BUFFERIZE;
    return rt;
}
int getFullIndex()
{
    rt = out_idx;
    out_idx = (out_idx + 1)%BUFFERIZE;
    return rt;
}
<生产者>
while(true)
{
    s_empty.unsignal();
    mutex.lock();
    crt = getEmptyIndex;
    mutex.unlock();
    buffer.put(crt);
    s_full.signal();
}
<消费者>
while(true)
{
    s_full.unsignal();
    mutex.lock();
    crt = getFullIndex();
    mutex.unlock();
    buffer.get(crt);
    s_empty.signal();
}





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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值