2014-02-27 32 views
0

我需要一个不会阻塞线程的线程安全计数器。 (对于C11以前的工具。)在++/- 操作周围锁定互斥锁可以阻止它。所以我想出了这个,使用信号量。这是否明智?Posix信号作为线程安全计数器

#include <semaphore.h> 

class AtomicCounter { 
public: 
    AtomicCounter(unsigned int i=0) { sem_init(&m, 0, i); } 
    ~AtomicCounter() { sem_destroy(&m); } 

    operator unsigned int() { int a; sem_getvalue(&m, &a); return a; } 
    AtomicCounter& operator++() { sem_post(&m); return *this; } 
    AtomicCounter& operator--() { sem_trywait(&m); return *this; } 

private: 
    AtomicCounter(const AtomicCounter&); 
    AtomicCounter& operator=(const AtomicCounter&); 
    sem_t m; 
}; 

编辑 另一种需要支持的ARMv7和x86以及任何普通的编译器工作。

+0

你知道原子操作是内置于95%的处理器,对吧?只需使用一些有针对性的内联汇编。 –

+0

当你告诉它减少时,你的柜台是否可以做_nothing_?尝试等待可能会失败。除此之外,它看起来不错,但它不会超快。即使没有C11,你也应该能够使用原子增量/减量来牺牲一点便携性(但是如果你添加2或3个ifdef,你几乎可以覆盖所有重要的体系结构)。 – Damon

+0

找到一个支持大多数cpu类型的多平台库将是可爱的... – Liam

回答

1

我经常使用由Golubenco & Sarbu描述的方法的一个适应来解决这个问题。

这适用于gcc;我只在x84和amd64架构上尝试过。

本质上讲,你声明一些计数器宏或内联函数,如果C++,使用提供了安全的多线程/多核心递增,递减和测试内部函数编译器。

它并不完全具有纯粹的C++语义,这在我的用例中是确定的,因为我在C和C++之间共享了代码,但将其并入您的类中并不是很多努力。