issue with Threadsafe singleton with semaphore

橙三吉。 提交于 2019-12-01 06:22:39

The problem is that call to WaitForMultipleObjects handles up to MAXIMUM_WAIT_OBJECTS which, at least in Visual Studio 2017, is 64.

Notice how your call to WaitForMultipleObjects to join threads returns WAIT_FAILED.

In order to wait for more objects one should, according to the documentation:

To wait on more than MAXIMUM_WAIT_OBJECTS handles, use one of the following methods:

  • Create a thread to wait on MAXIMUM_WAIT_OBJECTS handles, then wait on that thread plus the other handles. Use this technique to break the handles into groups of MAXIMUM_WAIT_OBJECTS.
  • Call RegisterWaitForSingleObject to wait on each handle. A wait thread from the thread pool waits on MAXIMUM_WAIT_OBJECTS registered objects and assigns a worker thread after the object is signaled or the time-out interval expires.

You don't need to write all of that code. The easiest way to implement a threadsafe singleton is to use Scott Meyer's singleton idiom:

class Singleton {
    int counter;
    mutable std::mutex counter_guard;
    Singleton() {}
public:
    Singleton(const Singleton&) = delete;
    Singleton(Singleton&&) = delete;
    Singleton& operator=(const Singleton&) = delete;
    Singleton& operator=(Singleton&&) = delete;

    static Singleton& instance() {
        static Singleton theInstance;
        return theInstance;
    }

    void setCounter(int newVal) {
        std::unique_lock<std::mutex> lock(counter_guard);
        counter = newVal;
    }  
    void incrementCounter() {
        std::unique_lock<std::mutex> lock(counter_guard);
        ++counter;
    }  
    int getCounter() const {
        std::unique_lock<std::mutex> lock(counter_guard);
        return counter;
    }  
};

An even easier way would be to use a std::atomic<int> type for the counter member variable. Then the mutex and lock guards can be omitted at all.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!