|< Windows Process & Threads Programming 1 | Main | Windows Process & Threads Programming 3 >| Site Index | Download |


 

 

 

 

MODULE T1

PROCESSES AND THREADS: Win32/WINDOWS APIs

Part 2: Story And Program Examples

 

 

 

 

 

What do we have in this Module?

  1. More Detail on Windows Processes and Threads

  2. Windows Task Manager

  3. Programs that are running

  4. Processes that are running

  5. Performance measures

  6. Viewing Network performance

  7. Monitoring Sessions

  8. Windows Handle and Kernel Objects

  9. Multitasking

  10. Scheduling

  11. Scheduling Priorities

  12. Priority Class

  13. Priority Level

  14. Base Priority

 

 

 

 

 

 

 

 

 

My Training Period: yy hours. Before you begin, read some instruction here.

 

 

 

The expected abilities:

  • Able to understand from zero ground about a process and thread implementation in Windows OSes.

  • Able to understand various terms used in the process and thread discussion.

  • Able to understand process scheduling and scheduler.

  • Able to use Windows Task Manager to view and control processes.

  • Able to understand Synchronization.

  • Able to understand various object used to synchronize multiple threads such as Mutex, Semaphore and Timer.

  • Able to understand and differentiate between multitasking and multithreading.

  • Able to understand various Inter-process communications among processes mechanisms such as Remote Procedure Call (RPC), Pipes and Windows Sockets.

More Detail on Windows Processes and Threads

 

Again, an application consists of one or more processes.  A process, in the simplest terms, is a running program. A thread is the basic unit to which the operating system allocates processor time. A thread can execute any part of the process code, including parts currently being executed by another thread. One or more threads run in the context of the process. A fiber is a unit of execution that must be manually scheduled by the application. Fibers run in the context of the threads that schedule them. A job object allows groups of processes to be managed as a unit. Job objects are namable, securable, sharable objects that control attributes of the processes associated with them. Operations performed on the job object affect all processes associated with the job object.

 

------------------------------------------------------------A break------------------------------------------------------------------

 

The Windows Task Manager

 

To invoke the Task Manager, press Ctrl + Alt + Del keys.  Most of the processes (programs/applications) are Windows components and executed as Windows Services that normally set during the Windows installation, instead of normal program/application execution.  These services executed during the Windows startup.  You can use Windows Services Microsoft Management Console (MMC) snap-in to see the detail of the Windows Services (Start Programs Administrative Tools Services). The following figure is Windows task manager screen.

 

 

Windows Task Manager: Controlling Windows processes

 

Windows Task Manager provides information about programs and processes running on your computer. It also displays the most commonly used performance measures for processes.  You can use Task Manager to monitor key indicators of your computer's performance. You can see the status of the programs that are running and end programs that have stopped responding. You can also assess the activity of running processes using as many as fifteen parameters, and see graphs and data on CPU and memory usage.  In addition, if you are connected to a network, you can view network status and see how your network is functioning.  If you have more than one user connected to your computer, you can see who is connected, what they are working on, and you can send them a message.

 

Programs that are running

 

The Applications tab shows the status of the programs running on your computer.  On this tab, you can end, switch to, or start a program.

 

Processes that are running

 

The Processes tab shows information about the processes running on your computer.  For example, you can display information on CPU and memory usage, page faults, handle count, and a number of other parameters.

 

Performance measures

 

The Performance tab displays a dynamic overview of your computer's performance, including:

Graphs for CPU and memory usage.  Totals for the number of handles, threads, and processes running on your computer.  Totals, in kilobytes, for physical, kernel, and commit memory.

 

Viewing Network performance

 

The Networking tab displays a graphical representation of network performance. It provides a simple, qualitative indicator that shows the status of the network(s) that are running on your computer. The Networking tab is displayed only if a network card is present.  On this tab, you can view the quality and availability of your network connection, whether you are connected to one or more than one network.

 

Monitoring Sessions

 

The Users tab displays users who can access this computer, and session status and names. Client Name specifies the name of the client computer using the session, if applicable. Session provides a name for you to use to perform such tasks as sending another user a message or connecting to another user’s session.  The Users tab is displayed only if the computer you are working on has Fast User Switching enabled, and is a member of a workgroup or is a standalone computer. The Users tab is unavailable on computers that are members of a network domain.

 

For custom view, click the View menu Select Columns... submenu as shown below.

 

Windows Task Manager: Controlling processes

 

Tick and/or un-tick the required columns and click the OK button.

 

Windows Task Manager: Customizing the View coloumn

 

The following is an example of Task Manager with more columns displayed.

 

Windows Task Manager: Customizing the view column

 

------------------------------------------------------------A break------------------------------------------------------------------

 

Each Windows’s process provides the resources needed to execute a program. A process has a virtual address space, executable code, data, object handles, environment variables, a base priority, and minimum and maximum working set sizes. Each process is started with a single thread, often called the primary thread, but can create additional threads from any of its threads. All threads of a process share its virtual address space and system resources. In addition, each thread maintains:

  1. Exception handlers,

  2. A scheduling priority and

  3. .A set of structures the system will use to save the thread context until it is scheduled.

 

The thread context includes:

  1. The thread's set of machine registers,

  2. The kernel stack,

  3. A thread environment block and

  4. A user stack in the address space of the thread's process.

 

Microsoft® Windows® supports preemptive multitasking, which creates the effect of simultaneous execution of multiple threads from multiple processes. On a multiprocessor computer, the system can simultaneously execute as many threads as there are processors on the computer. Preempted  means a process is returning from kernel to user mode, but the kernel preempts it and does a context switch to schedule another process.

 

Windows Handle and Kernel Objects

 

Kernel object handles are process specific. That is, a process must either create the object or open an existing object to obtain a kernel object handle. The per-process limit on kernel handles is 230.  Any process can create a new handle to an existing kernel object (even one created by another process), provided that the process knows the name of the object and has security access to the object. Kernel object handles include access rights that indicate the actions that can be granted or denied to a process. An application specifies access rights when it creates an object or obtains an existing object handle. Each type of kernel object supports its own set of access rights. For example, event handles can have "set" or "wait" access (or both), file handles can have "read" or "write" access (or both), and so on. In the following illustration, an application creates an event object. The CreateEvent() function creates the event object and returns an object handle.

 

Application creating an event object

 

Figure 6

 

After the event object has been created, the application can use the event handle to set or wait on the event. The handle remains valid until the application closes the handle or terminates.  Most kernel objects support multiple handles to a single object. For example, the application in the preceding illustration could obtain additional event object handles by using the OpenEvent() function, as shown in the following illustration.

 

Application creating an event object with multiple handles

 

Figure 7

 

This method enables an application to have handles with different access rights. For example, Handle 1 might have "set" and "wait" access to the event, and Handle 2 might have only "wait" access. If another process knows the event name and has security access to the object, it can create its own event object handle by using OpenEvent(). The creating application could also duplicate one of its handles into the same process or into another process by using the DuplicateHandle() function. An object remains in memory as long as at least one object handle exists. In the following illustration, the applications use the CloseHandle() function to close their event object handles. When there are no event handles, the system removes the object from memory, as shown in the following illustration.

 

Application closing event object handles to remove object from memory

 

Figure 8

 

The system manages file objects somewhat differently from other kernel objects. File objects contain the file pointer, the pointer to the next byte to be read or written in a file. Whenever an application creates a new file handle, the system creates a new file object. Therefore, more than one file object can refer to a single file on disk, as shown in the next illustration.

 

Multiple file objects referring to a file on disk

 

Figure 9

 

Only through duplication or inheritance can more than one file handle refer to the same file object, as shown in the following illustration.

 

Two file handles refer to same file object

 

Figure 10

 

The following table lists each of the kernel objects, along with each object's creator and destroyer functions. The creator functions either create the object and an object handle or create a new existing object handle. The destroyer functions close the object handle. When an application closes the last handle to a kernel object, the system removes the object from memory.

 

Kernel object

Creator function

Destroyer function

Access token

CreateRestrictedToken(), DuplicateToken(), DuplicateTokenEx(), OpenProcessToken(), OpenThreadToken()

CloseHandle()

Change notification

FindFirstChangeNotification()

FindCloseChangeNotification()

Communications device

CreateFile()

CloseHandle()

Console input

CreateFile(), with CONIN$

CloseHandle()

Console screen buffer

CreateFile(), with CONOUT$

CloseHandle()

Desktop

GetThreadDesktop()

Applications cannot delete this object.

Event

CreateEvent(), OpenEvent()

CloseHandle()

Event log

OpenEventLog(), RegisterEventSource(), OpenBackupEventLog()

CloseEventLog()

File

CreateFile()

CloseHandle(), DeleteFile()

File mapping

CreateFileMapping(), OpenFileMapping()

CloseHandle()

Find file

FindFirstFile()

FindClose()

Heap

HeapCreate()

HeapDestroy()

Job

CreateJobObject()

CloseHandle()

Mailslot

CreateMailslot()

CloseHandle()

Memory resource notification

CreateMemoryResourceNotification()

CloseHandle()

Module

LoadLibrary(), GetModuleHandle()

FreeLibrary()

Mutex

CreateMutex(), OpenMutex()

CloseHandle()

Pipe

CreateNamedPipe(), CreatePipe()

CloseHandle(), DisconnectNamedPipe()

Process

CreateProcess(), OpenProcess(), GetCurrentProcess()

CloseHandle(), TerminateProcess()

Semaphore

CreateSemaphore(), OpenSemaphore()

CloseHandle()

Socket

socket(), accept()

CloseHandle()

Thread

CreateThread(), CreateRemoteThread(), GetCurrentThread()

CloseHandle(), TerminateThread()

Timer

CreateWaitableTimer(), OpenWaitableTimer()

CloseHandle()

Update resource

BeginUpdateResource()

EndUpdateResource()

Window station

GetProcessWindowStation()

Applications cannot delete this object.

 

Table 6

 

Multitasking

 

Multitasking means doing many tasks at the ‘same time’. For example, when preparing a document you may opening graphic program to edit and insert graphic into your document and opening spreadsheet to do some statistic calculation. At the same time, the operating system also doing many tasks at the background. As all the data need to be processed, they need to share all the system resources such as processor and memory. Hence, there need a proper control mechanism and management. A multitasking operating system divides the available processor time among the processes or threads that need it. The system is designed for preemptive multitasking; it allocates a processor time slice to each thread it executes. The currently executing thread is suspended when its time slice elapses, allowing another thread to run. When the system switches from one thread to another, it saves the context of the preempted thread and restores the saved context of the next thread in the queue.

The length of the time slice depends on the operating system and the processor. Because each time slice is small (approximately 20 milliseconds), multiple threads appear to be executing at the same time. This is actually the case on multiprocessor systems, where the executable threads are distributed among the available processors. However, you must use caution when using multiple threads in an application, because system performance can decrease if there are too many threads. From the process model views, all runnable software on a computer, including the OS itself, is organized into a number of sequential processes, or just processes for short.  As mentioned before, a process is just an executing program, including the current values of the program counter, registers and variables.  Conceptually each process has its own virtual processor.  In reality the real processor switches back and forth from process to process. In the following figure (a) we see a computer multitasking four programs in memory.  In (b) we see how this is abstracted into four processes, each with its own flow of control that is its own program control and each one running independent of the other ones.  In (c) we see that when viewed over an ample of time interval, all the processes have made progress, but at any given instant only one process is actually running.

 

 

Multitasking concept

 

Figure 11

 

Scheduling

 

The system scheduler controls multitasking by determining which of the competing threads receives the next processor time slice. The scheduler determines which thread runs next using scheduling priorities.

 

Scheduling Priorities

 

Threads are scheduled to run based on their scheduling priority. Each thread is assigned a scheduling priority. The priority levels range from zero (lowest priority) to 31 (highest priority). Only the zero-page thread can have a priority of zero. The zero-page thread is a system thread responsible for zeroing any free pages when there are no other threads that need to run.

The following figure shows how to set the process priority through Windows Task Manager.  Under the Processes tab Select any Image Name Right click your mouse button as shown below.

 

Windows Task Manager: Scheduler and process priority

 

The system treats all threads with the same priority as equal. The system assigns time slices in a round-robin fashion to all threads with the highest priority. If none of these threads are ready to run, the system assigns time slices in a round-robin fashion to all threads with the next highest priority. If a higher-priority thread becomes available to run, the system ceases to execute the lower-priority thread (without allowing it to finish using its time slice), and assigns a full time slice to the higher-priority thread. The priority of each thread is determined by the following criteria:

 

  1. The priority class of its process.

  2. The priority level of the thread within the priority class of its process.

 

The priority class and priority level are combined to form the base priority (can be seen in Windows Task Manager as shown below) of a thread.

 

Windows Task Manager: Scheduler and process priority

 

Priority Class

 

From Windows APIs, each process belongs to one of the following priority classes:

 

  1. IDLE_PRIORITY_CLASS

  2. BELOW_NORMAL_PRIORITY_CLASS

  3. NORMAL_PRIORITY_CLASS

  4. ABOVE_NORMAL_PRIORITY_CLASS

  5. HIGH_PRIORITY_CLASS

  6. REALTIME_PRIORITY_CLASS

 

For Windows NT:  BELOW_NORMAL_PRIORITY_CLASS and ABOVE_NORMAL_PRIORITY_CLASS are not supported.  By default, the priority class of a process is NORMAL_PRIORITY_CLASS. Use the CreateProcess() function to specify the priority class of a child process when you create it. If the calling process is IDLE_PRIORITY_CLASS or BELOW_NORMAL_PRIORITY_CLASS, the new process will inherit this class. Use the GetPriorityClass() function to determine the current priority class of a process and the SetPriorityClass() function to change the priority class of a process. Processes that monitor the system, such as screen savers or applications that periodically update a display, should use IDLE_PRIORITY_CLASS. This prevents the threads of this process, which do not have high priority, from interfering with higher priority threads. Use HIGH_PRIORITY_CLASS with care. If a thread runs at the highest priority level for extended periods, other threads in the system will not get processor time.

If several threads are set at high priority at the same time, the threads lose their effectiveness. The high-priority class should be reserved for threads that must respond to time-critical events. If your application performs one task that requires the high-priority class while the rest of its tasks are normal priority, use SetPriorityClass() to raise the priority class of the application temporarily; then reduce it after the time-critical task has been completed. Another strategy is to create a high-priority process that has all of its threads blocked most of the time, awakening threads only when critical tasks are needed. The important point is that a high-priority thread should execute for a brief time, and only when it has time-critical work to perform. You should almost never use REALTIME_PRIORITY_CLASS, because this interrupts system threads that manage mouse input, keyboard input, and background disk flushing. This class can be appropriate for applications that "talk" directly to hardware or those perform brief tasks that should have limited interruptions.

 

The Priority Level

 

The following are priority levels within each priority class

 

  1. THREAD_PRIORITY_IDLE

  2. THREAD_PRIORITY_LOWEST

  3. THREAD_PRIORITY_BELOW_NORMAL

  4. THREAD_PRIORITY_NORMAL

  5. THREAD_PRIORITY_ABOVE_NORMAL

  6. THREAD_PRIORITY_HIGHEST

  7. THREAD_PRIORITY_TIME_CRITICAL

 

All threads are created using THREAD_PRIORITY_NORMAL. This means that the thread priority is the same as the process priority class. After you create a thread, use the SetThreadPriority() function to adjust its priority relative to other threads in the process.  A typical strategy is to use THREAD_PRIORITY_ABOVE_NORMAL or THREAD_PRIORITY_HIGHEST for the process's input thread, to ensure that the application is responsive to the user. Background threads, particularly those that are processor intensive, can be set to THREAD_PRIORITY_BELOW_NORMAL or THREAD_PRIORITY_LOWEST, to ensure that they can be preempted when necessary. However, if you have a thread waiting for another thread with a lower priority to complete some task, be sure to block the execution of the waiting high-priority thread. To do this, use a wait function, critical section, or the Sleep() function, SleepEx(), or SwitchToThread() function. This is preferable to having the thread execute a loop. Otherwise, the process may become deadlocked, because the thread with lower priority is never scheduled.  To determine the current priority level of a thread, use the GetThreadPriority() function.

 

The Base Priority

 

The priority level of a thread is determined by both the priority class of its process and its priority level. The priority class and priority level are combined to form the base priority of each thread.  The following table shows the base priority levels for combinations of priority class and priority value.

 

 

Process Priority Class

Thread Priority Level

1

IDLE_PRIORITY_CLASS

THREAD_PRIORITY_IDLE

1

BELOW_NORMAL_PRIORITY_CLASS

THREAD_PRIORITY_IDLE

1

NORMAL_PRIORITY_CLASS

THREAD_PRIORITY_IDLE

1

ABOVE_NORMAL_PRIORITY_CLASS

THREAD_PRIORITY_IDLE

1

HIGH_PRIORITY_CLASS

THREAD_PRIORITY_IDLE

2

IDLE_PRIORITY_CLASS

THREAD_PRIORITY_LOWEST

3

IDLE_PRIORITY_CLASS

THREAD_PRIORITY_BELOW_NORMAL

4

IDLE_PRIORITY_CLASS

THREAD_PRIORITY_NORMAL

4

BELOW_NORMAL_PRIORITY_CLASS

THREAD_PRIORITY_LOWEST

5

IDLE_PRIORITY_CLASS

THREAD_PRIORITY_ABOVE_NORMAL

5

BELOW_NORMAL_PRIORITY_CLASS

THREAD_PRIORITY_BELOW_NORMAL

5

Background NORMAL_PRIORITY_CLASS

THREAD_PRIORITY_LOWEST

6

IDLE_PRIORITY_CLASS

THREAD_PRIORITY_HIGHEST

6

BELOW_NORMAL_PRIORITY_CLASS

THREAD_PRIORITY_NORMAL

6

Background NORMAL_PRIORITY_CLASS

THREAD_PRIORITY_BELOW_NORMAL

7

BELOW_NORMAL_PRIORITY_CLASS

THREAD_PRIORITY_ABOVE_NORMAL

7

Background NORMAL_PRIORITY_CLASS

THREAD_PRIORITY_NORMAL

7

Foreground NORMAL_PRIORITY_CLASS

THREAD_PRIORITY_LOWEST

8

BELOW_NORMAL_PRIORITY_CLASS

THREAD_PRIORITY_HIGHEST

8

NORMAL_PRIORITY_CLASS

THREAD_PRIORITY_ABOVE_NORMAL

8

Foreground NORMAL_PRIORITY_CLASS

THREAD_PRIORITY_BELOW_NORMAL

8

ABOVE_NORMAL_PRIORITY_CLASS

THREAD_PRIORITY_LOWEST

9

NORMAL_PRIORITY_CLASS

THREAD_PRIORITY_HIGHEST

9

Foreground NORMAL_PRIORITY_CLASS

THREAD_PRIORITY_NORMAL

9

ABOVE_NORMAL_PRIORITY_CLASS

THREAD_PRIORITY_BELOW_NORMAL

10

Foreground NORMAL_PRIORITY_CLASS

THREAD_PRIORITY_ABOVE_NORMAL

10

ABOVE_NORMAL_PRIORITY_CLASS

THREAD_PRIORITY_NORMAL

11

Foreground NORMAL_PRIORITY_CLASS

THREAD_PRIORITY_HIGHEST

11

ABOVE_NORMAL_PRIORITY_CLASS

THREAD_PRIORITY_ABOVE_NORMAL

11

HIGH_PRIORITY_CLASS

THREAD_PRIORITY_LOWEST

12

ABOVE_NORMAL_PRIORITY_CLASS

THREAD_PRIORITY_HIGHEST

12

HIGH_PRIORITY_CLASS

THREAD_PRIORITY_BELOW_NORMAL

13

HIGH_PRIORITY_CLASS

THREAD_PRIORITY_NORMAL

14

HIGH_PRIORITY_CLASS

THREAD_PRIORITY_ABOVE_NORMAL

15

HIGH_PRIORITY_CLASS

THREAD_PRIORITY_HIGHEST

15

HIGH_PRIORITY_CLASS

THREAD_PRIORITY_TIME_CRITICAL

15

IDLE_PRIORITY_CLASS

THREAD_PRIORITY_TIME_CRITICAL

15

BELOW_NORMAL_PRIORITY_CLASS

THREAD_PRIORITY_TIME_CRITICAL

15

NORMAL_PRIORITY_CLASS

THREAD_PRIORITY_TIME_CRITICAL

15

ABOVE_NORMAL_PRIORITY_CLASS

THREAD_PRIORITY_TIME_CRITICAL

16

REALTIME_PRIORITY_CLASS

THREAD_PRIORITY_IDLE

17

REALTIME_PRIORITY_CLASS

-7

18

REALTIME_PRIORITY_CLASS

-6

19

REALTIME_PRIORITY_CLASS

-5

20

REALTIME_PRIORITY_CLASS

-4

21

REALTIME_PRIORITY_CLASS

-3

22

REALTIME_PRIORITY_CLASS

THREAD_PRIORITY_LOWEST

23

REALTIME_PRIORITY_CLASS

THREAD_PRIORITY_BELOW_NORMAL

24

REALTIME_PRIORITY_CLASS

THREAD_PRIORITY_NORMAL

25

REALTIME_PRIORITY_CLASS

THREAD_PRIORITY_ABOVE_NORMAL

26

REALTIME_PRIORITY_CLASS

THREAD_PRIORITY_HIGHEST

27

REALTIME_PRIORITY_CLASS

3

28

REALTIME_PRIORITY_CLASS

4

29

REALTIME_PRIORITY_CLASS

5

30

REALTIME_PRIORITY_CLASS

6

31

REALTIME_PRIORITY_CLASS

THREAD_PRIORITY_TIME_CRITICAL

 

 Table 7

 

For Windows NT:  Values -7, -6, -5, -4, -3, 3, 4, 5, and 6 are not supported.

 

 

 

 

 

 

 

Further reading and digging:

 

  1. Microsoft C references, online MSDN.

  2. Microsoft Visual C++, online MSDN.

  3. ReactOS - Windows binary compatible OS - C/C++ source code repository, Doxygen.

  4. Linux Access Control Lists (ACL) info can be found atAccess Control Lists.

  5. For Multi bytes, Unicode characters and Localization please refer to Locale, wide characters & Unicode (Story) and Windows users & groups programming tutorials (Implementation).

  6. Structure, enum, union and typedef story can be found C/C++ struct, enum, union & typedef.

  7. Check the best selling C / C++ and Windows books at Amazon.com.

 

 

 

 

 

 

 |< Windows Process & Threads Programming 1 | Main | Windows Process & Threads Programming 3 >| Site Index | Download |