How multithreading works in VC++ solution when running worker thread from the service executable and UI thread from the application executable

  • Thread starter Thread starter bhavya internship
  • Start date Start date
B

bhavya internship

Guest
Hi All,


I am working on the first C++ / VC++ project. Wanted to know how multithreading is using in my current project.

I was given an overview of the solution. I got to know that it is the windows standalone application. To use this application we are using windows installer and at the end of the installer we are running the service (It's name is mainserv.exe and this process is running in the background using a worker thread). Along with this from the installer we are running one more executable (It's name is DisplayUI.exe and this process is to open the UI once the service (mainserv.exe) is installed successfully.)

Theoretically i understood that the purpose of using multithreading here is to improve the performance by running multiple tasks together (Running the service using mainserv.exe and running the application using DisplayUI.exe.

Is my understanding is correct? And with the below code can I say my application is Multithreaded application?

Below is my mainserv.exe project code:

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

From the avove function we are calling DaliServiceStart like as shown below:

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

In the above function we are using the "worker_thread". And below is the worker_thread definition:


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

I want clarifications for the below questions that arise in my mind? Someone please help me to understand and proceed further.


1. Does the worker thread and the UI thread communicate with each other when worker thread has finished it's task?

If it is yes, how the worker thread and Primary User Interface threads communicates with each other?

2. In my "mainserv.exe" project from the WinMain() function I am calling DaliServiceInitialization() -> worker_thread().

I Understood that WinMain() works as a primary thread. And from this we are calling the worker_thread().

So, Is workerthread alwasy works under primary thread and communicate with the primary thread?

3. And also if the worker thread has an exception and there is no exception handling mechanism, then is worker thread terminates and will terminate the process as well?

Thanks in advance.

Continue reading...
 
Back
Top