【发布时间】:2014-09-10 09:30:07
【问题描述】:
让我们假设没有为 C++ 提供信号量的库。我是这样写的:
#include <vector>
#include <Windows.h>
class Semaphore {
HANDLE mutexS; // provides mutex in semaphore rutines
std::vector<HANDLE> queue; // provides FIFO queue for blocked threads
int value; // semaphore's value
public:
Semaphore(int init=1);
~Semaphore();
void wait();
void signal();
};
Semaphore::Semaphore(int init) {
value = init;
queue = std::vector<HANDLE>();
mutexS = CreateMutex(0,0,0);
}
Semaphore::~Semaphore() {
CloseHandle(mutexS);
}
void Semaphore::signal() {
WaitForSingleObject(mutexS, INFINITE);
if (++value <= 0) {
HANDLE someOldThread = queue.front();
ResumeThread(someOldThread);
queue.erase(queue.begin());
CloseHandle(someOldThread);
}
ReleaseMutex(mutexS);
}
我想知道为什么这个 wait() 的实现不起作用:
void Semaphore::wait() {
WaitForSingleObject(mutexS, INFINITE);
if (--value < 0) {
HANDLE thisThread = GetCurrentThread();
queue.push_back(thisThread);
ReleaseMutex(mutexS);
SuspendThread(thisThread );
}
else
ReleaseMutex(mutexS);
}
这一个有效:
void Semaphore::wait() {
WaitForSingleObject(mutexS, INFINITE);
if (--value < 0) {
HANDLE thisThread = GetCurrentThread();
HANDLE alsoThisThread;
DuplicateHandle(GetCurrentProcess(), thisThread, GetCurrentProcess(), &alsoThisThread, 0, 0, DUPLICATE_SAME_ACCESS);
queue.push_back(alsoThisThread);
ReleaseMutex(mutexS);
SuspendThread(alsoThisThread);
}
else
ReleaseMutex(mutexS);
}
每种情况下究竟发生了什么?很长时间以来,我一直在努力解决它。等待的第一个实现,它不起作用,使我的程序阻塞(嗯,它可能永远阻塞一些线程)。第二个实现就像一个魅力。是什么赋予了 ?为什么我需要复制线程句柄并阻止重复?
【问题讨论】:
-
可能是因为你在
signal()的实现中调用了CloseHandle?我不太精通 WinAPI,但似乎只在线程完成时关闭线程才明智,而不是在它应该恢复时关闭。 -
你也应该稍后访问codereview,因为你的代码肯定可以改进很多。
-
否 - 如果我不 CloseHanlde(sameOldThread);结果是一样的。不是这样的:(谢谢
-
不是直接回答您的问题,但可以使用计数器、互斥体和条件变量 (msdn.microsoft.com/en-us/library/windows/desktop/…) 制作信号量。
-
如果您想要一个 C++ 信号量(假设尚不存在),为什么不在 Windows 信号量周围加上一个包装器呢?您已经在使用 Windows 互斥量,因此如果您想要一个真正的信号量,已经提供了一个。我问这个以防你编写代码不是为了有趣和实验。如果没有,请忽略我。
标签: c++ multithreading winapi semaphore