实施关键部分 [英] Implementing critical section

查看:94
本文介绍了实施关键部分的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

什么方式更好更快地创造关键的部分?

通过二进制信号,sem_wait和sem_post之间。结果
或用原子操作:

 的#include<&sched.h中GT;虚空critical_ code(){
    静态挥发布尔锁= FALSE;    //进入临界区
    而(!__ sync_bool_compare_and_swap(安培;锁,假的,真正的)){
        SCHED_YIELD();
    }    // ...    //离开临界区
    锁定= FALSE;
}


解决方案

不管你用什么方法,你的code表现最差的问题已经无关什么类型你使用的锁定,但事实上,你锁定code,而不是数据。

随着中说,没有理由推出自己的自旋锁这样。要么使用 pthread_spin_lock 如果你想要一个自旋锁,否则的pthread_mutex_lock sem_wait (用二进制信号量),如果你想有一个锁争用时可以产生到其他进程。你写的code是在最严重的是如何使用 SCHED_YIELD 两全其美的。到 SCHED_YIELD 的通话将确保锁在那里有两个锁争用和CPU负载的情况下等待至少几毫秒(也可能是整个调度时间片),它会燃烧100%的CPU时,有争论,但没有CPU负载(由于锁定持有人被挡在IO,例如)。如果你想要得到任何的自旋锁的好处,你需要定纺未做任何系统调用。如果你想要的任何屈服CPU的好处,你应该是使用适当的同步原语将使用(在Linux上) futex的(或同等学历)操作产生完全相同,直到锁可用 - 无短和不再

和如果碰巧所有参加在你的头上,甚至不考虑如何编写自己的锁。

What way is better and faster to create a critical section?

With a binary semaphore, between sem_wait and sem_post.
Or with atomic operations:

#include <sched.h>

void critical_code(){
    static volatile bool lock = false;

    //Enter critical section
    while ( !__sync_bool_compare_and_swap (&lock, false, true ) ){
        sched_yield();
    }

    //...

    //Leave critical section
    lock = false;
}

解决方案

Regardless of what method you use, the worst performance problem with your code has nothing to do with what type of lock you use, but the fact that you're locking code rather than data.

With that said, there is no reason to roll your own spinlocks like that. Either use pthread_spin_lock if you want a spinlock, or else pthread_mutex_lock or sem_wait (with a binary semaphore) if you want a lock that can yield to other processes when contended. The code you have written is the worst of both worlds in how it uses sched_yield. The call to sched_yield will ensure that the lock waits at least a few milliseconds (and probably a whole scheduling timeslice) in the case where there's both lock contention and cpu load, and it will burn 100% cpu when there's contention but no cpu load (due to the lock-holder being blocked in IO, for instance). If you want to get any of the benefits of a spin lock, you need to be spinning without making any syscalls. If you want any of the benefits of yielding the cpu, you should be using a proper synchronization primitive which will use (on Linux) futex (or equivalent) operations to yield exactly until the lock is available - no shorter and no longer.

And if by chance all that went over your head, don't even think about writing your own locks..

这篇关于实施关键部分的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆