Note that in my sample code I use a global variable ("count") incremented in the timer callback routine to test whether the timer has run long enough. I tried also to send an event (a signal) from the callback routine to the main program via SetEvent(). This does not work however as we must use then WaitForSingleObjectEx() in the main program. This problem is mentioned in the "Advanced Windows" book by J.Richter but the explication given by Richter is obviously not complete. The Microsoft documentation does not mention this problem clearly. In any case you must use a routine ending on "..Ex" (SleepEx()) in the main program to guarantee that the callback routine can be invoked. The routines ending on "..Ex" set the thread (in our case the main program) in an "alertable state". As said before not all "..Ex" routines can be used however.
No synchronization for the access to the global variable is necessary (in this sample program!) as the global variable counting the number of invocations is used by only one thread.
Programming with threads is one of the crucial techniques in real time systems. Although very similar in the concept, the APIs under Windows and Unix are completely different. Meanwhile threads are also part of some programming languages (see the libraries coming with Java, D etc) and of some portable libraries like wxWidgets.
Around 2001 the POSIX comittee released a concept called "Portable threads" (PThreads). These PThreads ca be used under Unix/Linux and Windows, although not all Windows C compilers offer libraries for PThreads. The newer GNU gcc compiler has such a library under Windows and under Linux.
My sample program threads2.c shows a simple portable solution for a common problem: how to wait for the termination of multiple threads in the main program. I use here simple mutexes in combination with the API call pthread_mutex_trylock(). My simple solution even does not lock any shared variables. Note that other solutions using pthread_join() don't work if you have to wait for multiple threads as these calls block.You will find an application using threads (POSIX and Windows) in my ZIP file for the TCP server tcpsrv4. A more general solution is described in my (German) article under "Real time systems". This solution uses queues for the communication between threads and between threads and the main program (the controlling thread). The chapter "Threads and synchronisation" under "Programming in D" shows sample programs in the language D - this language with its associated Phobos library is also portable between Windows and Linux.