c++ - 如何在事件发生时启动线程并正确关闭他们的手

标签 c++ windows multithreading

我正在制作一项服务,它正在监听登录事件。如果发生此事件,我的应用程序应该启动一个新线程来完成工作。

我的问题是,我如何在每次登录事件发生时启动一个新线程,并在线程完成工作后正确关闭它的句柄。我的问题是,我不知道会发生多少登录事件,所以我不能使用 WaitForMultipleObjects,因为它的第一个参数是它应该等待的线程数。

while ( WaitForSingleObject( ghSvcStopEvent, 0 ) != WAIT_OBJECT_0 )
{
  DWORD dwEventFlags;
  BOOL bRes;

  // WTSWaitSystemEvent waits until a logon event ocurs
  bRes = WTSWaitSystemEvent( WTS_CURRENT_SERVER_HANDLE, WTS_EVENT_LOGON, &dwEventFlags );
  if ( dwEventFlags == WTS_EVENT_NONE )
  {
    ShowErrorText( "Cancelling waiting for logon event. Service shutting down.", 0, true );
  }
  if ( bRes )
  {
    // Someone has logged on
    HANDLE hThread = CreateThread( NULL, 0, ServiceWorkerThread, NULL, 0, &dwThreadID );
  }
  else
  {
    ShowErrorText( "WTSWaitSystemEvent failed.", GetLastError(), true );
  }
}//while

有人可以帮我吗?

谢谢!

最佳答案

如果你可以使用 C++11(从 VS2010 开始),你可以使用条件变量来完成这项工作

条件变量的思想是: 一个允许线程一起通信的变量。 如果你通知它,你就会向插入它的其他线程发送信号

如果您对它执行 cv.wait(...),您将等待其他线程发出信号表明某事已发生,然后您再次测试您的条件。

举个例子

服务器.h

#include <condition_variable>
#include <mutex>

class CServer
{
    std::condition_variable & cv;
    std::mutex & mut;
    bool & flag;
public:
    ~CServer(void);
    CServer::CServer(std::condition_variable & cv,
                     std::mutex & mut,
                     bool & flag);

    CServer::CServer(CServer &);
    int Notify();
    int DisplayNotification();

    std::condition_variable & getCondVar(){return cv;}
    std::mutex & getMutex(){return mut;}
    bool & getFlag(){return flag;}
};

服务器.cpp

#include "Server.h"
#include <iostream>
using namespace std;





CServer::~CServer(void)
{
}

CServer::CServer(std::condition_variable & cv_,
                 std::mutex & mut_,
                 bool & flag_):
cv(cv_),
mut(mut_),
flag(flag_)
{

}

CServer::CServer(CServer &toCopy):
cv(toCopy.getCondVar()),
mut(toCopy.getMutex()),
flag(toCopy.getFlag())
{
    flag=false;
    cout<<"Copy constructor"<<std::endl;
}

int CServer::Notify()
{
    {
        std::lock_guard<std::mutex> lk(mut);
        flag=true;
        std::cout << "ready for notfication"<<endl;
    }
    cv.notify_one();
    return 0;
}

int CServer::DisplayNotification()
{
    // wait for the worker
    {
        std::unique_lock<std::mutex> lk(mut);
        cv.wait(lk, [this]{return this->getFlag();});
    }
    cout<<"Notification displayed"<<endl;
    return 0;
}

客户端.h

#include <chrono>
#include "Server.h"
class CClient
{
    CServer & serv;
    std::chrono::seconds sleepTime;
    bool finishedWork;
public:
    CClient(CServer & serv, 
            std::chrono::seconds sleepTime);
    ~CClient(void);
    int work();
};

客户端.cpp

#include "Client.h"
#include <thread>
using namespace std;


CClient::CClient(CServer & serv_,
                 std::chrono::seconds sleepTime_):
serv(serv_),
sleepTime(sleepTime_),
finishedWork(false)
{
}


CClient::~CClient(void)
{
}

int CClient::work()
{
    this_thread::sleep_for(sleepTime);
    finishedWork=true;
    serv.Notify();
    return 0;
}

main.cpp

#include "Client.h"
#include <thread>
using namespace std;

int main()
{
    std::chrono::seconds sleepTime=std::chrono::seconds(10);

    //create client and server
    condition_variable cv;
    mutex mut;
    bool flag=false;

    CServer serv(cv,mut, flag);
    CClient cli(serv,sleepTime);

    //thread with the server
    thread thServ(&CServer::DisplayNotification,serv);

    ////thread with the client
    thread thCli (&CClient::work,cli);

    ////join threads
    thServ.join();
    thCli.join();
    return 0;
}

有问题可以问我

希望对你有帮助

关于c++ - 如何在事件发生时启动线程并正确关闭他们的手,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19691868/

相关文章:

windows - 从以管理员身份运行的 Inno Setup 安装程序为当前登录的用户安装应用程序

c - 线程程序问题

multithreading - 分发工作同步和fork-join并行编程方法之间有什么区别

ios - 事件指标多线程执行

c++ - 使用 C++ 中的 Luabind 在循环中创建的对象导致应用程序崩溃

c++ - 使用 getline 从文件读入字符串,然后将该字符串推回到 vector 上

c++ - 重载++ 运算符以将存储在数组中的值加 1?

c++ - 在 C++ 中,有没有办法在编译时更改函数原型(prototype)?

windows - 如何在 Windows 7 32 位上安装 MongoDB?

node.js - 无法使用 Windows 10 安装 firebase 工具 cli