我想知道是否有一种方法可以在C++ (或C#)中实现信号量,任何可以提供帮助的库。我试着使用OpenMP,但我没有办法真正阻塞线程,相反,我不得不忙于等待它们,当我没有足够数量的线程时,这会导致死锁。所以首先,我在寻找一个可以让我阻塞/产生/杀死我的线程的库。
其次,有没有已经实现了信号量的库?
最后,当我被介绍到信号量的上下文时,我发现它非常有用(也许我错了?)但我没有看到很多库(如果有的话)实现它。我熟悉OpenMP,看过英特尔的TBB,C#线程。但在所有这些函数中,我都没有明确地看到信号量。那么信号量不像我想的那么实用吗?或者是因为它们很难实现?或者是我没有意识到?
附注:
信号量可以跨平台实现吗?因为它们可能与操作系统有关。
发布于 2011-05-14 16:50:05
发布于 2011-05-14 22:20:57
第一个建议是使用boost。所有艰苦的工作都已经完成了。
如果你想看看它是如何实现的,它应该是这样的(虽然这是一个粗略的草图,但我相信通过一些研究可以优化它)。基本上,信号量是由三件事构建的:
下面是简单的版本:
#include <pthread.h>
// Need an exception safe locking class.
struct MutexLocker
{
MutexLocker(pthread_mutex_t& m) :mutex(m)
{ if (pthread_mutex_lock(&mutex) != 0) {throw int(1); }}
~MutexLocker()
{ if (pthread_mutex_unlock(&mutex) != 0) {throw int(1); }}
private:
pthread_mutex_t& mutex;
};
class Semaphore
{
public:
Semaphore(int initCount = 0)
: count(initCount)
, waitCount(0)
{
if (pthread_mutex_init(&mutex, NULL) != 0)
{ throw int(1);
}
if (pthread_cond_init(&cond, NULL) != 0)
{ pthread_mutex_destroy(&mutex);
throw int(2);
}
}
void wait()
{
MutexLocker locker(mutex);
while(count == 0)
{
++waitCount;
if (pthread_cond_wait(&cond, &mutex) != 0)
{ throw int(2);
}
// A call to pthread_cond_wait() unlocks the mutex and suspends the thread.
// It does not busy wait the thread is suspended.
//
// When a condition variable receives apthread_cond_signal() a random thread
// is un-suspended. But it is not released from the call to wait
// until the mutex can be reacquired by the thread.
//
// Thus we get here only after the mutex has been locked.
//
// You need to use a while loop above because of this potential situation.
// Thread A: Suspended waiting on condition variable.
// Thread B: Working somewhere else.
// Thread C: calls signal() below (incrementing count to 1)
// This results in A being awakened but it can not exit pthread_cond_wait()
// until it requires the mutex with a lock. While it tries to
// do that thread B finishes what it was doing and calls wait()
// Thread C has incremented the count to 1 so thread B does not
// suspend but decrements the count to zero and exits.
// Thread B now aquires the mutex but the count has been decremented to
// zero so it must immediately re-suspend on the condition variable.
// Note a thread will not be released from wait until
// it receives a signal and the mustex lock can be re-established.
--waitCount;
}
--count;
}
void signal()
{
// You could optimize this part with interlocked increment.
MutexLocker locker(mutex);
++count;
// This Comment based on using `interlocked increment` rather than mutex.
//
// As this part does not modify anything you don;t actually need the lock.
// Potentially this will release more threads than you need (as you don't
// have exclusivity on reading waitCount but that will not matter as the
// wait() method does and any extra woken threads will be put back to sleep.
// If there are any waiting threads let them out.
if (waitCount > 0)
{ if (pthread_cond_signal(&cond) != 0)
{ throw int(2);
}
}
}
private:
unsigned int count;
unsigned int waitCount;
pthread_mutex_t mutex;
pthread_cond_t cond;
};发布于 2011-05-14 16:36:19
在.NET中,BCL:System.Threading.Semaphore中存在一个实现。
对于Windows上的本机代码,请查看CreateSemaphore Function。如果您的目标是Linux,那么您可以找到维也纳理工大学here的信号量实现(我以前已经使用过它,并且工作正常)。
https://stackoverflow.com/questions/6000674
复制相似问题