2014-10-01 70 views
-2

除了互斥体之外,还可以使用什么来锁定C++?处理器级别有什么可以使用的?C++是互斥体锁定共享资源的唯一方式

+2

“锁定”是什么意思? – 2014-10-01 03:46:37

+0

保护共享资源有“无锁”方法。 – imreal 2014-10-01 03:50:58

+0

请参阅[测试维基百科](http://en.wikipedia.org/wiki/Test-and-set)。 – kmac 2014-10-01 03:54:32

回答

0

您可以使用比较和交换,与此类似:

std::atomic_bool locked = false; 
bool f = false; 
... // spawn threads n' stuff 
do { 
    bool got_lock = atomic_compare_exchange_weak(locked, &f, true); 
    if (got_lock) { 
    ... // do stuff 
    locked = false; 
    } 
} 
while(!got_lock) 

我命名锁定的变量和概念got_lock,但没有真正锁定怎么回事。 atomic_compare_exchange_weak函数利用特殊的汇编指令来进行原子操作。

为了解它是如何工作的:它进入do while循环并立即尝试CAS。 CAS将锁定的值与f中包含的值进行比较,该值为false。当且仅当它们比较相等时,它将锁定到第三个参数(true)并返回true。否则,这意味着另一个线程已经被锁定为true,所以它返回false并且不会更改锁定的值。我们可以看到,如果线程获得锁定,它将进入if,做一些事情,然后释放锁定。如果它没有得到锁,它不会通过if,但它会被while循环反弹回来。它继续以非常快的while循环直到CAS调用成功。

所以,我写了评论“做的东西”,你保证只有一个线程可以一次。

0

如果您在操作系统下开发,那么您也可以使用信号量。与互斥信号量相比,可以用一定数量的初始值作为计数器。您启动信号量的值允许任何调用者获取资源或执行关键代码部分,直到值(信号量)大于零。当它降到零时,任何新的呼叫者将等待释放/释放信号量。而二进制信号量本身就是互斥量。

0

操作系统基元相对于锁具有一个关键优势,因为使用OS基元会将您的线程放入内核的等待队列中。当一个互斥锁被释放时,你的线程可以被操作系统自动唤醒并启动。如果你使用比较/交换类型检查,你有责任编写你的螺旋锁和适当的睡眠(否则当你没有锁,你会使用100%的处理器(或核心)等待它释放)。

Mutex擅长跨进程同步(这需要操作系统)。信号量非常相似,不同之处在于它允许并发访问关键部分(例如,允许4个线程仅从工作队列运行以优化多核处理器上的工作)。

您还有“CRITICAL_SECTION”MSDN LINK如果您只在同一进程中同步线程,则可以使用它。这会更快,因为您不需要系统调用来实现锁定。