[英]How to ensure object has only one thread
I have a following code: 我有以下代码:
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;
};
I want my class to perform behaviour like this: 我希望我的类能够执行这样的行为:
Service obj;
obj.start(); // new thread
obj.start(); // do nothing because thread already exists
Now I'm stuck on question which handle to cover by mutex: 现在我一直在质疑互斥锁覆盖哪个句柄:
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(...);
}
You can control the state of the thread handle hThread , if it's signaled then it means that the thread is terminated: 您可以控制线程句柄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
}
Note that the second parameter is the timeout and need to be set to zero for non-blocking call. 请注意,第二个参数是超时,需要将非阻塞调用设置为零。
You can simply check if hThread
is a valid handle or not: 您只需检查
hThread
是否是有效句柄:
if (hThread != NULL)
return;
else
hThread = CreateThread(...);
CreateThread
returns a valid handle if the thread is successfully created, so make sure you have proper handling after your call to CreateThread
. 如果成功创建了线程,
CreateThread
将返回有效句柄,因此请确保在调用CreateThread
后正确处理。 You will also need to ensure you initialise hThread
to NULL
in your constructor: 您还需要确保在构造函数中将
hThread
初始化为NULL
:
Service::Service() : hMutex(NULL), hThread(NULL) etc...
{
}
If you were using std::thread
instead, you could simply check whether the thread was joinable
: 如果您使用的是
std::thread
,则只需检查该线程是否joinable
:
class Service
{
public:
void start();
private:
std::thread thread;
};
Service::start()
{
if (thread.joinable())
return;
}
I would take the RAII way and create the thread in the constructor and close it in the destructor. 我将采用RAII方式并在构造函数中创建线程并在析构函数中关闭它。 The main advantages are that you can't forget to close the service(Even when there's an exception), and that the constructor can only be called once and only by one thread at a time.
主要的优点是你不能忘记关闭服务(即使有异常),并且构造函数一次只能被一个线程调用一次。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.