首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >信号量实现

信号量实现
EN

Stack Overflow用户
提问于 2011-05-14 16:31:23
回答 4查看 4.1K关注 0票数 2

我想知道是否有一种方法可以在C++ (或C#)中实现信号量,任何可以提供帮助的库。我试着使用OpenMP,但我没有办法真正阻塞线程,相反,我不得不忙于等待它们,当我没有足够数量的线程时,这会导致死锁。所以首先,我在寻找一个可以让我阻塞/产生/杀死我的线程的库。

其次,有没有已经实现了信号量的库?

最后,当我被介绍到信号量的上下文时,我发现它非常有用(也许我错了?)但我没有看到很多库(如果有的话)实现它。我熟悉OpenMP,看过英特尔的TBB,C#线程。但在所有这些函数中,我都没有明确地看到信号量。那么信号量不像我想的那么实用吗?或者是因为它们很难实现?或者是我没有意识到?

附注:

信号量可以跨平台实现吗?因为它们可能与操作系统有关。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2011-05-14 16:50:05

有没有已经实现了这个功能的库?

对于C++,有多个多线程库,它们提供信号量实现:

  • Posix
  • Poco Thread
  • Tiny Threads

此外,您还可以使用Boost实现信号量。查看this

票数 6
EN

Stack Overflow用户

发布于 2011-05-14 22:20:57

第一个建议是使用boost。所有艰苦的工作都已经完成了。

如果你想看看它是如何实现的,它应该是这样的(虽然这是一个粗略的草图,但我相信通过一些研究可以优化它)。基本上,信号量是由三件事构建的:

  • A count
  • 条件变量(提供挂起)
  • 提供独占性以修改计数并等待条件的互斥锁。

下面是简单的版本:

代码语言:javascript
复制
#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;
};
票数 3
EN

Stack Overflow用户

发布于 2011-05-14 16:36:19

在.NET中,BCL:System.Threading.Semaphore中存在一个实现。

对于Windows上的本机代码,请查看CreateSemaphore Function。如果您的目标是Linux,那么您可以找到维也纳理工大学here的信号量实现(我以前已经使用过它,并且工作正常)。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6000674

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档