Threads and Multi-threaded Programming
When I heard about the new social media app “Threads” of Meta, the first thing that came to my mind was, did some programmer or system engineer came up with the name? Although thread and multi-threaded programming is an important computing concept, many new programmers seem to be unaware of it. In this article, I shall touch on what are threads, multithreaded programming and other related concepts.
Processes
A process is an instance of a program running in a computer.
Threads
A thread of execution is the smallest sequence of programmed instructions that can be managed independently by a scheduler, which is typically a part of the operating system. Multiple threads allow a program to be divided into tasks that can operate independently from each other. A thread can execute any part of the application’s code, including a part currently being executed by another thread. All threads of a process share the virtual address space, global variables, and operating system resources of the process.
Context Switching
When switching from one thread to another, the operating system saves the current state of the thread by copying all registers onto the stack and save into a CONTEXT structure. The OS then points the processor at the memory of the other thread’s process, and restores the registers from the new thread’s CONTEXT structure.
Race condition
A bug in a multithreaded process where the code of thread A relies on thread B to complete some action, but where there is no synchronization between the two threads. The process works if thread B wins the race by completing its action before thread needs it, but the process fails if thread A wins the race.
Deadlock
A bug where the execution of thread A is blocked indefinitely waiting for thread B to perform some action, while thread B is blocked waiting for thread A. For example, two threads on opposite ends of a named pipe can become deadlocked if each thread waits to read data written by the other thread. A single thread can also deadlock itself.
Synchronization Objects
A synchronization object is an object whose handle can be specified in one of the wait functions to coordinate the execution of multiple threads. More than one process can have a handle to the same synchronization object, making interprocess synchronization possible.
Examples of synchronization object / concept:
Semaphore — A flag variable that is used to govern access to shared system resources.
Mutex — a synchronization object that allows one thread mutually exclusive access to a resource. Mutexes are useful when only one thread at a time can be allowed to modify data or some other controlled resource.
Critical section — The portion of the code that accesses a shared resource.
Event objects — A kernel object whose only purpose is to be signaled or nonsignaled.
Differences between Critical Section and Mutex:
Simple example of Thread Programming (C++):
#include <windows.h>
DWORD WINAPI ThreadFunc(LPVOID);
main( )
{
HANDLE hThread;
DWORD threadId;
hThread = CreateThread(NULL, 0, ThreadFunc, 0, 0, &threadid);
printf(“Thread Running”);
}
DWORD WINAPI ThreadFunc(LPVOID p)
{
//…………..
}
A very typical example of application that utilizes multi-threaded programming would be a web server like Apache Web Server or Microsoft IIS. Web servers are basically applications that listen constantly on port 80 (HTTP) and 443 (HTTPS) for requests. When there is a new incoming request, the web server shall create a new worker thread to service the request so that the main thread can continue to listen to other requests.
So that’s a bit-sized information on threads and multi-thread programming concepts. As I always said, having a solid understanding of concepts is important no matter what profession you are in. Only when you are able to understand how things work, and be curious enough to want to understand how things work, then you would have the tools to create new knowledge for the betterment of the world.