如何确保对象只有一个线程
How to ensure object has only one thread
我有以下代码:
class Service {
public:
void start(); // creates thread which creates window and goes to message loop
void stop(); // sends WM_CLOSE message to thread window
private:
HANDLE hMutex;
HANDLE hThread;
HWND hWindow;
};
我希望我的 class 执行如下行为:
Service obj;
obj.start(); // new thread
obj.start(); // do nothing because thread already exists
现在我被互斥体覆盖哪个句柄的问题困住了:
void Service::start() {
// check if service is already running
if (/*!!*/) // what should I check: (hThread != NULL)? or (hWindow != NULL)?
return; // no need to create another thread
else
hThread = CreateThread(...);
}
您可以简单地检查 hThread
是否是一个有效的句柄:
if (hThread != NULL)
return;
else
hThread = CreateThread(...);
CreateThread
returns 如果线程成功创建,则为有效句柄,因此请确保在调用 CreateThread
后进行正确处理。您还需要确保在构造函数中将 hThread
初始化为 NULL
:
Service::Service() : hMutex(NULL), hThread(NULL) etc...
{
}
如果您使用的是 std::thread
instead, you could simply check whether the thread was joinable
:
class Service
{
public:
void start();
private:
std::thread thread;
};
Service::start()
{
if (thread.joinable())
return;
}
你可以控制线程句柄的状态hThread,如果它发出信号则意味着线程被终止:
DWORD result = WaitForSingleObject( hThread, 0);
if (result == WAIT_OBJECT_0) {
// the signal is sent and therefore the thread has been terminated
}
else {
// the signal is not sent and hThread is alive
}
注意第二个参数是超时时间,非阻塞调用需要设置为0。
你可以查看详细的reference
我会采用 RAII 方式,在构造函数中创建线程并在析构函数中关闭它。主要优点是您不会忘记关闭服务(即使出现异常),并且构造函数一次只能被一个线程调用一次。
我有以下代码:
class Service {
public:
void start(); // creates thread which creates window and goes to message loop
void stop(); // sends WM_CLOSE message to thread window
private:
HANDLE hMutex;
HANDLE hThread;
HWND hWindow;
};
我希望我的 class 执行如下行为:
Service obj;
obj.start(); // new thread
obj.start(); // do nothing because thread already exists
现在我被互斥体覆盖哪个句柄的问题困住了:
void Service::start() {
// check if service is already running
if (/*!!*/) // what should I check: (hThread != NULL)? or (hWindow != NULL)?
return; // no need to create another thread
else
hThread = CreateThread(...);
}
您可以简单地检查 hThread
是否是一个有效的句柄:
if (hThread != NULL)
return;
else
hThread = CreateThread(...);
CreateThread
returns 如果线程成功创建,则为有效句柄,因此请确保在调用 CreateThread
后进行正确处理。您还需要确保在构造函数中将 hThread
初始化为 NULL
:
Service::Service() : hMutex(NULL), hThread(NULL) etc...
{
}
如果您使用的是 std::thread
instead, you could simply check whether the thread was joinable
:
class Service
{
public:
void start();
private:
std::thread thread;
};
Service::start()
{
if (thread.joinable())
return;
}
你可以控制线程句柄的状态hThread,如果它发出信号则意味着线程被终止:
DWORD result = WaitForSingleObject( hThread, 0);
if (result == WAIT_OBJECT_0) {
// the signal is sent and therefore the thread has been terminated
}
else {
// the signal is not sent and hThread is alive
}
注意第二个参数是超时时间,非阻塞调用需要设置为0。
你可以查看详细的reference
我会采用 RAII 方式,在构造函数中创建线程并在析构函数中关闭它。主要优点是您不会忘记关闭服务(即使出现异常),并且构造函数一次只能被一个线程调用一次。