当运行来自服务可执行文件的工作线程和来自应用程序可执行文件的UI线程时,多线程在VC ++解决方案中如何工作

时间:2019-05-30 16:29:45

标签: c++ visual-c++

大家好,

我正在从事第一个C ++ / VC ++项目。想知道我当前的项目中多线程的使用情况。

为我提供了解决方案的概述。我知道这是Windows独立应用程序。要使用此应用程序,我们使用Windows安装程序,并在安装程序的末尾运行服务(其名称为mainserv.exe,此进程使用辅助线程在后台运行)。与此同时,我们还将在安装程序中运行另一个可执行文件(名称为DisplayUI.exe,此过程是在成功安装服务(mainserv.exe)后打开UI。)

从理论上讲,我理解此处使用多线程的目的是通过同时运行多个任务(使用mainserv.exe运行服务以及使用DisplayUI.exe运行应用程序)来提高性能。

我的理解正确吗?使用下面的代码,我可以说我的应用程序是多线程应用程序吗?

以下是我的mainserv.exe项目代码:

int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow)
{

        TCHAR servicePath[MAX_PATH];    
        GetModuleFileName(NULL, servicePath, sizeof(servicePath));

        Resource resource (APC_DALI_DEFAULT_REG_PATH, APC_INSTALL_PATH);
        TCHAR serviceDesc [MAX_PATH];
        resource.GetString(serviceDesc, IDS_SERVICE_DESCRIPTION);       


            if (IsServiceRegistered(APC_DALI_SERVICE_NAME) == FALSE)
            {
                RegisterService(servicePath, APC_DALI_SERVICE_NAME, APC_DALI_SERVICE_NAME, serviceDesc);
            }

            // TODO: Place code here.
            SERVICE_TABLE_ENTRY   DispatchTable[] = 
            { 
                {APC_DALI_SERVICE_NAME, (LPSERVICE_MAIN_FUNCTION) DaliServiceStart}, 
                {NULL, NULL} 
            }; 

            StartServiceCtrlDispatcher( DispatchTable);

return 0;
}

从avove函数中,我们如下所示调用DaliServiceStart:

void WINAPI DaliServiceStart (DWORD argc, LPTSTR *argv) 
{ 
    DWORD status; 
    DWORD specificError; 

PotHttp potData(REG_POT_PATH);

    DaliServiceStatus.dwServiceType        = SERVICE_WIN32; 
    DaliServiceStatus.dwCurrentState       = SERVICE_START_PENDING; 

    DaliServiceStatus.dwControlsAccepted   = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN ; 
    DaliServiceStatus.dwWin32ExitCode      = 0; 
    DaliServiceStatus.dwServiceSpecificExitCode = 0; 
    DaliServiceStatus.dwCheckPoint         = 0; 
    DaliServiceStatus.dwWaitHint           = 0; 

    DaliServiceStatusHandle = RegisterServiceCtrlHandler(APC_DALI_SERVICE_NAME, (LPHANDLER_FUNCTION)DaliServiceCtrlHandler); 

    if (DaliServiceStatusHandle == (SERVICE_STATUS_HANDLE)0) 
    { 
        return; 
    } 

    // Initialization code goes here. 
    status = DaliServiceInitialization(argc,argv, &specificError);  

    // Initialization complete - report running status. 
    DaliServiceStatus.dwCurrentState       = SERVICE_RUNNING; 
    DaliServiceStatus.dwCheckPoint         = 0; 
    DaliServiceStatus.dwWaitHint           = 0; 


    if (!SetServiceStatus (DaliServiceStatusHandle, &DaliServiceStatus)) 
    { 
        status = GetLastError(); 
    } 

potData.FireHeartbeat(LFC_SERVICE_STARTED);

    return; 
} 



DWORD DaliServiceInitialization(DWORD   argc, LPTSTR  *argv, DWORD *specificError) 
{ 

    DWORD dwThreadID = 0;

    //Reset the last error.
    SetLastError(0);

    //Create the worker thread
    g_hThread = CreateThread(NULL, 0,(LPTHREAD_START_ROUTINE) &worker_thread, NULL, 0, &dwThreadID);

    Sleep(0);

    return(0); 
} 

在上面的函数中,我们使用“ worker_thread”。下面是worker_thread定义:

DWORD WINAPI worker_thread (LPVOID pThreadParameter) 
{

    DWORD errStatus = ERROR_SUCCESS;   

    HANDLE hStopLoggingEvent = ::CreateEvent(FALSE, TRUE, FALSE, APC_STOP_LOGGING_EVENT_NAME);
    if(!hStopLoggingEvent)
    {
        assert("CreateEvent" == NULL);
    }

    HANDLE hStopApplicationEvent = ::CreateEvent(0, TRUE, FALSE, APC_STOP_APPLICATION_EVENT_NAME);

    if (hStopApplicationEvent)
    {       
        HANDLE * pAllHandles = new HANDLE;

        assert(pAllHandles != NULL);

        if (pAllHandles)
        {            
            *pAllHandles = hStopApplicationEvent;

            CDaliPowerHandler powerHandler(FIREFLY_SERVICE_WINDOW_CLASS_NAME, FIREFLY_SERVICE_WINDOW_NAME);

            HWND hWnd = powerHandler.GetHwnd();

            SetTimer(hWnd, APC_DEFAULT_INTERVAL, 5000, NULL);
            SetTimer(hWnd, APC_HEARTBEAT_INTERVAL, 3600000, NULL);


            if (hWnd)
            {
                WaitForMessagesAndEvents(1, pAllHandles, 0, hWnd);
            }
            else
            {
                assert("worker_thread()" == NULL);
                //No hwnd
            }
        }
        delete [] pAllHandles;
    }
    else
    {
        assert("worker_thread()" == NULL);
    }

    if (hStopApplicationEvent)
    {
        CloseHandle(hStopApplicationEvent);
    }

    if (hStopLoggingEvent)
    {
        CloseHandle(hStopLoggingEvent);
    }

    return(errStatus);
}

我想对我想到的以下问题进行澄清?有人请帮助我理解并进一步进行操作。

  1. 在以下情况下,工作线程和UI线程是否相互通信? 工作线程已完成任务?

    如果是,则工作线程和主用户界面线程如何 彼此交流吗?

  2. 在我正在通过WinMain()函数进行的“ mainserv.exe”项目中 DaliServiceInitialization()-> worker_thread()。

    我理解WinMain()作为主线程。从这个我们 正在调用worker_thread()。

    因此,workerthread是否始终在主线程下工作并进行通信 与主线程?

  3. 并且如果工作线程有异常并且没有异常 处理机制,那么工作线程将终止并且将终止 主线程和进程也是如此?

  4. 并使用上面的代码创建工作线程来运行服务,并 UI线程打开应用程序,我可以说我的应用程序是 多线程应用程序?

0 个答案:

没有答案