简体   繁体   English

这是 C++ 信号量吗?

[英]Is this a C++ Semaphore?

I have a thread-save-resource (a OpenCl-Command Queue to a device),but i want restrict the number of threads that have access to this ressource at the same time(i want to calculate on my cpu if the gpu command-queue is 'to full').我有一个线程保存资源(一个 OpenCl-Command 队列到一个设备),但我想限制同时访问这个资源的线程数量(如果 gpu 命令,我想在我的 CPU 上计算-队列“已满”)。 Unfortunately i'm relatively new to c++11 atomic operations.不幸的是,我对 c++11 原子操作比较陌生。 So i want to know if the following source code works as intended.所以我想知道以下源代码是否按预期工作。

class SpinSemaphore{
public:
    SpinSemaphore(int max_count):
       _cnt(0),
       _max_cnt(max_count){}

    bool try_lock(){
       bool run = true;
       while(run){
           int cnt = _cnt.load();
           if(++cnt > _max_cnt) return false;

           run = !std::atomic_compare_exchange_weak(&_cnt, &cnt,
            std::memory_order_acquire);
       }
       return true;
   }

void unlock(){
    --_cnt;
}

private:
   std::atomic<int>     _cnt;
   int              _max_cnt;
};

//

SpinSemaphore m(4);

void foo(){ //..
   if(m.try_lock()){//..
      my_queue.enqueueNDRangeKernel(/**/);
   }
   else
       //fallback

}

No, that won't behave as expected - consider the situation where 2 threads get to int cnt = _cnt.load();不,这不会像预期的那样运行 - 考虑 2 个线程到达int cnt = _cnt.load(); at the same time.同时。 They will both read the same value, and both set the counter to the same value, even though it might be that only 1 of them should've got though.它们都将读取相同的值,并且都将计数器设置为相同的值,即使可能只有其中 1 个应该有。

That might be considered an acceptably rare occurrence for you to ignore, apart from when you unlock, your count will become negative.这可能被认为是您可以忽略的罕见事件,除了解锁时,您的计数将变为负数。

might by a typo, but you use atomic_compare_exchange_weak() wrong可能是拼写错误,但您使用 atomic_compare_exchange_weak() 错了

what you need is你需要的是

do {
   old=_cnt.load();
   new=old+1;
   if (new > _max_cnt) return false;
} while (!_cnt.compare_exchange_weak(&old,new));

imagine obj.compare_exchange_weak(old,new) as an atomic-Compare_And_Swap()-function将 obj.compare_exchange_weak(old,new) 想象成一个原子 Compare_And_Swap() 函数

bool Compare_And_Swap() {
    if (obj == old) {
        obj = new;
        return true;
    }
    return false;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM