2013-10-30 32 views
1

我正在制作服务,该服务正在监听登录事件。如果发生此事件,我的应用程序应该启动一个新线程,它将完成这项工作。如何在事件发生时启动线程并正确关闭句柄

我的问题是,如何在每次登录事件发生时启动一个新线程,并在线程完成工作后正确关闭它的句柄。我的问题是,我不知道会发生多少登录事件,所以我不能用户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 

有人可以帮我吗?

谢谢!

+0

你需要等待线程完成?如果没有,在验证['CreateThread']之后,在下一行*上使用'CloseHandle(hThread)'(http://msdn.microsoft.com/en-us/library/windows/desktop/ms682453(v = vs.85 ).aspx)没有返回NULL。无论如何,您需要关闭该句柄,或者在验证线程启动成功后立即关闭,或者在不再需要句柄之后立即关闭该句柄。 (注意:如果你使用的是C/C++运行库,你应该使用['_beginthreadex()'](http://msdn.microsoft.com/en-us/library/kdzttdcb(v = vs。 90).aspx),btw)。 – WhozCraig

+0

我认为你应该使用线程池,而不是在每次登录时创建一个新线程。 – Matt

+0

@WhozCraig:其实我不需要等待线程完成。非常感谢你。发表您的评论作为answear,所以我可以接受它。 – kampi

回答

0

如果你可以使用C++ 11(开始VS2010),你的使用条件变量,会为你

做的工作条件变量的想法是: 一个变量,它允许线程comunicate在一起。 如果你通知它,你发送一个信号给其他线程上它

如果你做cv.wait(...)对它,你等待其他线程发出信号,sonething已happennend,然后你测试你的再次条件。

下面是一个例子

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

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

Client.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(); 
}; 

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

问我,如果您有任何疑问,

希望帮助

相关问题