CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 14 of 14
  1. #1
    Join Date
    May 2015
    Posts
    538

    Timer function in multithreading

    Hi,

    I create a new process from parent process.

    Now I need to print the process info on the child process, every 5 mins.

    Im thinking of using the windows timer functionality with the call back. Is this ok, to call from the parent process, in the structure below. Ive not compiled the following is just pseudocode

    Code:
    void CALLBACK ResourceUtilLogFunction(HWND hwnd, UINT uMsg, UINT timerId, DWORD dwTime)
    {
    	printf("Hello\n");
    }
    
    int main ()
    {
    	STARTUPINFO si = {};
    	si.cb = sizeof si;
    
    	PROCESS_INFORMATION pi = {};
    	const TCHAR* target = _T("C:\\Windows\\WinSxS\\wow64_microsoft-windows-calc_31bf3856ad364e35_10.0.19041.1_none_6a03b910ee7a4073\\calc.exe");
    
    	if ( !CreateProcess(target, 0, 0, FALSE, 0, 0, 0, 0, &si, &pi) )
    	{
    		cerr << "CreateProcess failed (" << GetLastError() << ").\n";
    	}
    	else
    	{
    		FILETIME ftime, fsys, fuser;
    
    
    		SetTimer(NULL, 0, 1000 * 3, (TIMERPROC)& ResourceUtilLogFunction);
    
    		CloseHandle(pi.hProcess);
    		CloseHandle(pi.hThread);
    	}
    
    	cin.sync();
    	cin.ignore();
    
    	return 0;
    }

  2. #2
    Join Date
    Nov 2000
    Location
    Voronezh, Russia
    Posts
    6,632

    Re: Timer function in multithreading

    SetTimer says:
    When you specify a TimerProc callback function, the DispatchMessage calls the callback function instead of calling the window procedure when it processes WM_TIMER with a non-NULL lParam. Therefore, you need to dispatch messages in the calling thread, even when you use TimerProc instead of processing WM_TIMER.
    So, calling SetTimer is not enough to fire your callbacks. You need to start message pump looping. And find a way to break the loop to make your process quit nicely.

    As anyway this is about looping, a more straight approach would be to start a thread where a while loop waits for 5 minutes and then just executes whatever you need. To quit thread nicely, a stop event can be used as a waitable object. The main thread, after spawning your scheduler thread, just sleeps on getch() until any key pressed in the console window and sends the stop event before quitting. Tidy and simple.
    Best regards,
    Igor

  3. #3
    Join Date
    May 2015
    Posts
    538

    Re: Timer function in multithreading

    Thankyou very much for the reply and hints.
    I gave example a code which I tried to understand myself.

    In the legacy code, Im trying to change, I donot see a handle available for the process.

    There I can see the a process (A), is spanning another Process (B). using the createProcess

    I want to write a logging app, where , it prints the information on the process B every lets say 10sec

    I was thinking, if I can get the Parent Process A 's window handle, HANDLE handleA (I need to check, how to do that). In the case, can I start the SetTimer with handleA ?

    Code:
    struct {
    
    			int numThreads;
    } ProcessInfo;
    
    legacy_function 
    {
    
    
    
    		// Get the current Process window handle
    		// Do I need the current thread also ?
            HANDLE handleA = OpenProcess(
                 PROCESS_ALL_ACCESS,FALSE,ProcessIdA);
    			 
    		SetTimer(handleA , 0, 1000 * 3, (TIMERPROC)& ResourceUtilLogFunction);
    
    }
    
    
    void CALLBACK ResourceUtilLogFunction(HWND hwnd, UINT uMsg, UINT timerId, DWORD dwTime)
    { 
    	HANDLE hThreadSnap = INVALID_HANDLE_VALUE; 
    	THREADENTRY32 te32; 
    
    	// Take a snapshot of all running threads  
    	hThreadSnap = CreateToolhelp32Snapshot( TH32CS_SNAPTHREAD, 0 ); 
    	if( hThreadSnap == INVALID_HANDLE_VALUE ) 
    		return( FALSE ); 
    
    	// Fill in the size of the structure before using it. 
    	te32.dwSize = sizeof(THREADENTRY32 ); 
    
    	// Retrieve information about the first thread,
    	// and exit if unsuccessful
    	if( !Thread32First( hThreadSnap, &te32 ) ) 
    	{
    		printError( TEXT("Thread32First") );  // Show cause of failure
    		CloseHandle( hThreadSnap );     // Must clean up the snapshot object!
    		return( FALSE );
    	}
    
    	// Now walk the thread list of the system,
    	// and display information about each thread
    	// associated with the specified process
            int currNumThreads =0;
    	do 
    	{ 
    		if( te32.th32OwnerProcessID == dwOwnerPID )
    		{
    			_tprintf( TEXT("\n     THREAD ID      = 0x%08X"), te32.th32ThreadID ); 
    			_tprintf( TEXT("\n     base priority  = %d"), te32.tpBasePri ); 
    			_tprintf( TEXT("\n     delta priority = %d"), te32.tpDeltaPri ); 
    			currNumThreads++;
    		}
    	} while( Thread32Next(hThreadSnap, &te32 ) );
    
    
        ProcessInfo.numThreads = currNumThreads;
    	
    	WriteLogInfoToFile(ProcessInfo);
    	
    	_tprintf( TEXT("\n"));
    
    	//  Don't forget to clean up the snapshot object.
    	CloseHandle( hThreadSnap );
    	return( TRUE );
    }
    
    void WriteLogInfoToFile(ProcessInfo ProcessInfo)
    {
       // Open File 
       // Append the time and numThreads
    }
    My Question is :
    1. If i get the window handle of ProcessA, to start the timer, I think, i donot need to pump messages ?
    2. Do I need a mutex to write into the global variable, as the parent process, (ie A), might have mutiple threads accessing it.
    3. In the WriteLogInfoToFile, do I dont think, I need a mutex, it is just reading the info

    Let me know the comments please, as Im rusty with multithreading (in linux) and new to windows, so any comments and hints will be very helpful

    Thankyou very much
    pdk
    Last edited by pdk5; March 25th, 2025 at 05:06 AM.

  4. #4
    Join Date
    Nov 2000
    Location
    Voronezh, Russia
    Posts
    6,632

    Re: Timer function in multithreading

    I fail to understand why you so desperately need to use that SetTimer while you're new to Windows programming. SetTimer requires message pump be running in the same thread where SetTimer gets called. In other words, it is intended to be used in applications running their own windows, thus capable of dispatching window messages.

    You basically need two things: 1) periodical execution of your routine (achieved by plain while() loop) and 2) falling to sleep between routines (achieved by waiting on event handle for predefined timeout within the loop when event is used for waking the thread from sleep and informing the loop to break up). For initial implementation you may use plain Sleep() instead of waiting on handle.

    The part about writing to global variable of parent process looks unclear to me. Any process in Windows has isolated memory, and a process cannot access the memory of another process, no matter parent or what, unless it does some extremely exotic preparation for that. More than that, the address space is unique for every process, which means a variable in foreign process is not addressable, even in case the address somehow gets known outside the process.
    Best regards,
    Igor

  5. #5
    Join Date
    May 2015
    Posts
    538

    Re: Timer function in multithreading

    Thankyou very much Igor for taking time to help me with inputs and comments.

    1. I wanted to reuse the API of timer thinking (it is well established API and developer must have taken care of design issues), rather than reinventing the wheel, i thought I can just use the available API. But as you suggested if it not what you recommend, then I can look into the alternatives suggested by you. But I am bit cauticous of starting a new thread entirely for this purpose.

    2. Reg global variable: I was thinking putting handling of timers in the parent process. Then when using the SetTimer (in the parent process) I can pass value via global variable to the timer call back function. But parent process might have threads, which makes it difficult to handle a global variable.
    Last edited by pdk5; March 29th, 2025 at 09:13 AM.

  6. #6
    Join Date
    Nov 2000
    Location
    Voronezh, Russia
    Posts
    6,632

    Re: Timer function in multithreading

    Okay, as to the 1, I still don't know whether your application (parent or child) is capable of pumping messages. You never said a word about that.

    Besides that, what I gather from 2 is that you're still unsure where to place your monitoring logic. If you spawn a child process, its main thread can do the while loop without any additional thread that you're a bit cautious of. If you do not, the main process has no choice but spinning a separate thread. Cannot see why this could be a big deal. Not bigger than spawning a child process.

    BTW, I don't see why there should be parent-child relationships. Can't the monitor be launched independently? or as a service running in background? Should it necessarily be visible (in which case it might be a dialog app showing some grid or rendering graphics)? or it is okay just to write to some log file? or Windows Event Log? Not to mention that monitor and renderer can also run independently and separate from each other.

    All the options above will require different architecture and techniques, which means you cannot reuse 100% of the code in case the approach changes. Only you know what exactly you want to achieve and how much time and effort you're ready to invest into this. As you've already been advised in the other thread, start from something small and manageable, and you always can improve the result later.
    Best regards,
    Igor

  7. #7
    Join Date
    Nov 2000
    Location
    Voronezh, Russia
    Posts
    6,632

    Re: Timer function in multithreading

    A piece of code to demonstrate the wheel invention:

    Code:
    #include <windows.h>
    #include <stdio.h>
    
    
    void TimerProc();
    
    
    HANDLE stopEvent = NULL;
    DWORD  dwTimeout = 0;
    
    
    // make it 1 to see what happens inside
    #if 0
    #define LOG printf
    #else
    #define LOG (void)
    #endif
    
    
    DWORD WINAPI TimingLoop(LPVOID pVoid)
    {
    	DWORD dwRet = WAIT_TIMEOUT;
    
    
    	LOG("Entering %s\n", __FUNCTION__);
    
    
    	while (dwRet == WAIT_TIMEOUT)
    	{
    		dwRet = WaitForSingleObject(stopEvent, dwTimeout);
    		LOG("dwRet = %08x\n", dwRet);
    		if (dwRet == WAIT_TIMEOUT)
    		{
    			TimerProc();
    		}
    	}
    	LOG("Leaving %s\n", __FUNCTION__);
    	return 0;
    }
    
    
    DWORD StartTimer(DWORD aTimeout)
    {
    	if (stopEvent != NULL)
    	{
    		// already running
    		return ERR_ALREADY;
    	}
    	dwTimeout = aTimeout;
    	stopEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
    	
    	if (stopEvent != NULL)
    	{
    		DWORD  dwThreadId = 0;
    		HANDLE hThread = CreateThread(NULL, 0, TimingLoop, NULL, 0, &dwThreadId);
    		if (hThread == NULL)
    		{
    
    
    			CloseHandle(stopEvent);
    			stopEvent = NULL;
    			dwTimeout = 0;
    			return ERR_THREAD;
    		}
    		else
    			CloseHandle(hThread);
    	}
    	else
    		return ERR_EVENT;
    
    
    	return NO_ERR;
    }
    
    
    void  StopTimer()
    {
    	if (stopEvent == NULL)
    		return;
    
    
    	SetEvent(stopEvent);
    	Sleep(1);
    	CloseHandle(stopEvent);
    	stopEvent = NULL;
    	dwTimeout = 0;
    }
    
    
    void TimerProc()
    {
        
        LOG("Entering %s\n", __FUNCTION__);
    
    
        // your main logic goes here
        
        LOG("Leaving %s\n", __FUNCTION__);
    }
    Best regards,
    Igor

  8. #8
    Join Date
    May 2015
    Posts
    538

    Re: Timer function in multithreading

    Thankyou very much Igor, very helpful.

    Dont we need to use mutex when writting to "dwTimeout " global.(as other threads , in a huge multithreaded environment code might try to access/write this variable)
    Last edited by pdk5; March 31st, 2025 at 03:35 AM.

  9. #9
    Join Date
    Nov 2000
    Location
    Voronezh, Russia
    Posts
    6,632

    Re: Timer function in multithreading

    Quote Originally Posted by pdk5 View Post
    Dont we need to use mutex when writting to "dwTimeout " global.(as other threads , in a huge multithreaded environment code might try to access/write this variable)
    The code is just to give you an idea where to start with crafting your own timer-like functionality. As I said above, you know better what your requirements look like, so please suit yourself.

    A side note though is that mutex is not the only synchronisation primitive in Windows. As to me, critical sections look more natural in the role of resource guard in multi-threaded solution.


    MSDN: Critical Section Objects
    Best regards,
    Igor

  10. #10
    Join Date
    May 2015
    Posts
    538

    Re: Timer function in multithreading

    Thankyou very much Igor for the help.

    Yes, Im not much into windows multithreading. But I wanted to know if it is issue having global variable in multithreaded envrironment.

    Yes, I understand mutex is one of the ways to handle synchronisation (like semaphores etc)

    Thankyou very much to you that , I now understand to create own timer function. But my main concern with the SetTimer was passing the parameter. One way to avoid was to use a global variable. And I wanted to know the implications of using the global variable in the multithreaded environment.

    Thankyou very much for inputs and hints, were really helpful

  11. #11
    Join Date
    Nov 2000
    Location
    Voronezh, Russia
    Posts
    6,632

    Re: Timer function in multithreading

    To judge upon whether it's safe to use an unprotected global variable, first you're to answer whether your timer is intended to be concurrently used by several threads (which is what I really doubt, considering the initial task description). If the answer is yes, you need an access guard (mutex or critical section) to your key elements (event and timeout).

    Second question is whether you intend to run more than one timer simultaneously. If the answer is yes, you cannot use global variable and need to repack the timer solution into a C++ object (and then create as many as you like, remembering that one timer object means one thread). Yet again, if the first point was answered positively, your object is to include its individual guard as well.
    Best regards,
    Igor

  12. #12
    Join Date
    May 2015
    Posts
    538

    Re: Timer function in multithreading

    Thanks a lot for replying. As of now it is just used by one thread alone.

    But as the code base is huge, and if somebody at later point of time want to use , it may cause issues..So wanted to think about that scenario as well..

    Thanks a lot for reply with detailed info. I will try (if possible to modify your program for mutiple threads, or timers), and see if i can get a solution for just my own understanding

  13. #13
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,903

    Re: Timer function in multithreading

    If you're using Windows threads/processes instead of C++ multi-threading libraries, then I suggest 2 books:
    Windows System Programming by Johnson Hart
    https://www.amazon.co.uk/Windows-Pro...748/ref=sr_1_1

    Windows via C++ by Jeffrey Richter
    https://www.amazon.co.uk/Windows%C2%...9G/ref=sr_1_1?

    Note that these are about 15 years old so....
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  14. #14
    Join Date
    May 2015
    Posts
    538

    Re: Timer function in multithreading

    Thanks a lot kaud.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured