| |||||
|
|
Hi all, Today let's look at the topics of processes, threads and synchronization objects. First of all, what is the difference between a process and a thread. In strict bookish definition, a process is a unit of ownership, while a thread is a unit of execution. Synchronization objects are facilities provided by the OS, which help in synchronization of resource access as well as logical synchronization of execution paths.Process As said above, a process is a unit of ownership. This means a process is something which owns different resources. It owns it's own virtual memory address space, it owns different objects and handles, it owns threads and everything else that is required for it's work. A process does not execute, it just owns the executing threads.Whenever a process is spawned, system assigns it a 4 GB virtual memory address space (in a Win32 Environment), allocates a context for it and then starts it's main execution thread, which actually then starts the execution. The 4 GB address spaces is unique to the process in that, only this process sees this address space during the time when it's context is the current one in the system. The 4 GB is again divided into two parts, upper 2 GB is for the processes address space, and lower 2 GB (shared by all processes) actually houses all the device drivers. All processes in Windows have a unique process ID, a DWORD value which identifies that process at any given instance.A context, is a collection of all the process/thread related information which recognizes a process/thread at any particular instance. It's like a snap shot of a process/thread. It contains, all the register values, stack, etc, at any given time. So when the OS schedules a thread of a process, it actually loads it's context (all it's registers, stack and any other info) so that the thread becomes current thread and has all it's previous information (like next instruction pointer etc) with it. You should explore about thread scheduling and scheduling policies on your own.In Windows, you can spawn a process using CreateProcess() function. Find out the details of this function and it's parameters in MSDN. Thread A thread is a unit of execution. A thread is the one which has executable code which is executed (in it's time slice) by the processor. A process can have many threads, but should have at least one thread to survive. A thread also has a context, and always has an execution path. In Windows, you can launch a thread using many different ways (although at lower level, they all end up at the same place). The best way is to use the CreateThread() API (others are _beginthread() etc.). You should find out more about this API in MSDN. Threads can be worker thread, or UI thread. A UI thread also has a message loop etc, which processes windows messages and handles windows. You can find more details about these types in MSDN. Both the API's (CreateProcess() and CreateThread()) return handles to the respective objects, which you can use in different other API's (including synchronization API's).Synchronization Synchronization means controlling the flow of the execution paths of one or more threads. There are many synchronization objects and the API's provided by Windows to work with them. Some of these are:1. Event 2. Mutext 3. Semaphore 4. Timers 5. Critical Section 6. Waitable Timers etc. The API's are provided to create/delete and manage these objects. But the set of API's which are used to wait on these are same for all these objects. These are WaitForSingleObject() and WaitForMultipleObjects(). As the name suggests, these API's can be used to wait on a particular object unless it satisfies some condition. For example, you can use this API to wait on an event, unless it's triggered (SetEvent()). You can also wait on threads and processes (using their handles).The trigger conditions in these cases are termination of the thread/process. We will cover Events here, you should explore about other objects on your own, or I will try to cover these later if you want.Event Events, are synchronization objects, which trigger by changing their level. Any event has two levels, either it is set or reset. You can create an event using CreateEvent() API. Look at it's parameters in MSDN. An event can be manual reset, or auto reset. A manual event needs to be reseted again once it's set. An auto reset event is resetted as soon as it satisfies one condition (a thread waiting on this event is freed etc.). The CreateEvent() api returns an event handle which can be used in WaitForSingleObject() function. You can find out details about these functions in MSDN. You can set the state of a handle to set or reset using SetEvent() and ResetEvent() API's. You can destroy an event using CloseHandle().Usually you use the event as follows. Let's say you have two threads in your application. One of the thread (thread A) needs to wait while other thread (thread B) is say getting user input and putting it into a buffer. The thread A will then process this input buffer. You can now create an event (global) which will be available to both the thread. Thread A will wait for this event (WaitForSingleObject()), while thread B get's the user input and puts it into the buffer. After filling the buffer, thread B fires this event (SetEvent()), once the event is set, the WaitForSingleObject() API in thread A will return (it was blocked till now), and thread A will proceed to process the buffer. If the event was manual reset, it will stay set and any other threads who try to wait on it will get freed. This will happen unless you call ResetEvent(). If the event was auto reset, it will reset as soon as the WaitForSingleObject() returns. This operation is atomic, that means, as soon as WaitForSingleObject() is satisfied, the event is resetted, without any other thread getting a chance to get freed.Some Exercise: 1. Explore about other synchronization objects. 2. Find out about different parameters to CreateProcess() 3. Find out how parent-child relationship exists between processes being spawned by other processes, and how inheritable handles can be used by them.4. Explore how (if at all) synchronization objects can be used across different processes (above we saw it across different threads). 5. Find the difference between process ID and thread ID, explore all the parameters of CreateThread() API. I think this is enough for this week :) We will try to cover some other topic next week. Thanks, -Farooque
|