如何确保对象只有一个线程

How to ensure object has only one thread

本文关键字:对象 有一个 线程 确保 何确保      更新时间:2023-10-16

我有以下代码:

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;
};

我希望我的班级表现出这样的行为:

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的状态,如果发出信号,则表示线程终止:

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
}

请注意,第二个参数是超时,对于非阻塞调用,需要将其设置为零。

您可以检查详细的参考

您可以简单地检查hThread是否是有效句柄:

if (hThread != NULL)
    return;
else
    hThread = CreateThread(...);

如果成功创建线程,CreateThread将返回一个有效的句柄,因此请确保在调用CreateThread之后有正确的处理。您还需要确保在构造函数中将hThread初始化为NULL

Service::Service() : hMutex(NULL), hThread(NULL) etc...
{
}

如果您使用std::thread,您可以简单地检查线程是否为joinable:

class Service
{
public:
    void start();
private:
    std::thread thread;
};
Service::start()
{
    if (thread.joinable())
        return;
}

我会采用RAII的方式,在构造函数中创建线程,并在析构函数中关闭它。主要优点是,您不能忘记关闭服务(即使出现异常),并且构造函数一次只能调用一次,而且只能由一个线程调用。

相关文章: