Thread Synchronization in Linux and Windows Systems, Part 4
August 05, 2019
This article will be useful for those who have never programmed applications with multiple threads but plan to do so in the future.
In Windows OS, TerminateThread returns TRUE in the case of successful termination. Starting out from this logic, let’s try to organize analogous functionality in Linux.
To start with, we will check if the thread is alive. To do so, we will send a zero signal. If a thread exists in the process and is being executed, then tkill will return 0. After that, we will call to the pthread_setcanceltype function with the PTHREAD_CANCEL_ASYNCHRONOUS parameter, and only after this we will try to terminate the thread by calling to the pthread_cancel function. There is a possible situation when the thread will still be executing for some time, and for this we will use the timed wait function pthread_timedjoin_np (there are five attempts in the example; each takes 1000 ms). After the thread is terminated, we will call to pthread_setcanceltype again with the PTHREAD_CANCEL_DEFERRED parameter. In case there are any errors, there will always be returned FALSE.
Any thread of the process calls the ExitProcess function.
If one of the threads calls to exit function (for Linux OS), or either ExitProcess or TerminateProcess (for Windows OS), then the whole process will be terminated. Likewise, if a thread receives a signal that the action consists in the process termination, this signal will terminate the whole process.
Let’s summarize it all. A correctly designed application shall not call to forceful thread termination functions. A recommended way is when the thread function returns. In case of a thread termination in Linux OS, a join will release links and system resources owned by the process. Proper allowance must be made for the fact that calling to join functions twice is incorrect (at its best there will be an error). If a thread is forcefully terminated for Windows OS, it is important to note that all nonsystem resources shall be cleaned up in any way. In Linux, there are pthread_cleanup_push and pthread_cleanup_pop functions for that.
Thread termination functions are recorded in Table 5.
pthread_setcanceltype, pthread_cancel, pthread_setcanceltype
Table 5. Thread termination functions.
To mitigate influence of interrupts, an OS provides a model that consists of in-parallel running processes. However, this model has its weak points related to interaction, availability of its own address space, etc.
On the other hand, it might be advantageous for applications to have several control threads within one process. As these threads belong to the same process, they use the shared address space on their own stack.
Threads may interact with each other using primitives such as semaphores, messages, etc. These primitives are necessary to make it impossible for simultaneous execution of two and more threads in critical sections. A thread can be in one of the following states: runnable or executing blocked. A thread can also interact with another thread using interaction primitives. Keep in mind that while using interaction primitives one should exercise caution to avoid errors and deadlocks.
In this article, we analyzed streaming API for Windows and Linux OS; presented event-based thread creation and synchronization interfaces; discussed functions for working with shared resources; and detailed thread termination ways.
Eduard Trunov is a software engineer at Auriga. He is responsible for developing new features for high-volume business applications on Linux. Prior to that, he was the pivotal .NET engineer on a project developing and supporting functional automated asset risk management systems for electrical devices. His professional interests include C, .NET, operating systems, and debugging.
This blog is fourth in a series of four, for part 1, click here, for part 2, click here, for part 3, click here.
List of references:
- Stevens, W. Richard. Advanced Programming in the UNIX Environment, 3rd Edition. / W. Richard Steven, Stephen A. Rago. - Spb.: Piter, 2018. –944 p.
- Russinovich, M. Windows Internals. 7th Edition. / M. Russinovich, D. Solomon, А. Ionescu, P. Yosifovich. - Spb.: Piter, 2018. - 944 p.
- Tanenbaum A. Modern Operating Systems. 4th Edition./ A. Tanenbaum , H. Bos. - Spb.: Piter, 2015. –1120 p.
- Love, R. Linux System Programming. 2nd Edition./ R. Love. - Spb.: Piter, 2014. –448 p.
- Richter J. Programming Applications for Microsoft Windows: Master the critical building blocks of 32-bit and 64-bit Windows-based applications. 4th Edition. / J. Richter. - М.: Publishing company «Russian editorship»; 2008. –720 p.
- Stevens, W. Richard. Unix Network Programming: Interprocess Communications. / W. Richard Stevens. - Spb.: Piter, 2003. –576 p.
- Linux man pages online [Electronic resource]. – URL: http://man7.org/linux/man-pages/
- Microsoft Docs [Electronic resource]. – URL: https://docs.microsoft.com/