In-depth introduction to Win32 Multi-Thread Programming (1)

Source: Internet
Author: User
Tags ranges vc runtime
From single-process and single-thread to multi-process and multi-thread is an inevitable trend in the development of the operating system. In that year, the DOS system was a single-task operating system, the best programmers can only implement the so-called "multi-task" by resident memory, while today's Win32 operating system can listen to music while programming while printing documents.
Understanding multithreading, synchronization, mutex, and other communication methods is a key part of understanding modern operating systems. When we are proficient in Win32 multi-threaded programming, it is also easy to understand and learn the multi-task control of other operating systems. Therefore, learning Win32 multithreading is important not only to understand Win32 itself, but also to learning and understanding other operating systems. A brief introduction to the basic concept of Win32 multi-threaded programming Introduction

From single-process and single-thread to multi-process and multi-thread is an inevitable trend in the development of the operating system. In that year, the DOS system was a single-task operating system, the best programmers can only implement the so-called "multi-task" by resident memory, while today's Win32 operating system can listen to music while programming while printing documents.

Understanding multithreading, synchronization, mutex, and other communication methods is a key part of understanding modern operating systems. When we are proficient in Win32 multi-threaded programming, it is also easy to understand and learn the multi-task control of other operating systems. Many programmers have never learned the well-known Operating System VxWorks in the field of embedded systems, but they can develop it immediately, probably thanks to their efforts in Win32 multithreading.

Therefore, learning Win32 multithreading is important not only to understand Win32 itself, but also to learning and understanding other operating systems.

  Processes and threads

First, I would like to explain the concepts and differences between processes and threads. This is a problem that many university teachers cannot clarify.

A process is a running activity of a program with certain independent functions. It is an independent unit for the system to allocate and schedule resources. A program is an ordered set of commands. It does not have any running meaning, but is a static entity. The process is different. It is the execution of a program on a certain dataset and a dynamic entity. It is created and runs due to scheduling. It is in the waiting status due to waiting for resources or events and is revoked due to task completion, it reflects all the dynamic processes of a program running on a certain dataset.

A thread is an entity of a process and the basic unit of CPU scheduling and scheduling. The thread cannot be executed independently. It must exist in the application and the application provides multiple thread execution control.

The relationship between a thread and a process is as follows: a thread belongs to a process and runs in the process space. The threads produced by the same process share the same memory space, when a process exits, all threads generated by the process are forcibly exited and cleared. A thread can share all resources of a process with other threads of the same process, but it basically does not have system resources, only a bit of information (such as program counters, a set of registers, and stacks) is required during running ).

According to the process and thread settings, the operating system is roughly divided into the following types:

(1) single process, single thread, MS-DOS is roughly this kind of operating system;

(2) multi-process, single-thread, most UNIX (and Unix-like Linux) are such operating systems;

(3) multi-process, multi-thread, Win32 (Windows NT/2000/XP, etc.), Solaris 2.x, and OS/2;

(4) single process and multi-thread. VxWorks is such an operating system.

The main benefits of introducing threads in the operating system are:

(1) creating and terminating a thread in a process is faster than creating or terminating a process;

(2) switching between threads within a process is faster than switching between processes, especially between user-level threads. In addition, the appearance of threads is due to the following reasons:

(1) Concurrent execution of concurrent programs is more effective in multiple processing environments. A concurrent program can create a process, and several concurrent program segments in the concurrent program can create several threads to execute these threads on different processing machines.

(2) Each process has an independent address space, and all threads in the process share the address space. In this way, the address space of the parent process must be copied by the child process in the parent-child process model.

(3) The thread is very effective in solving the customer/server model.

  Win32 process

1. inter-process communication (IPC)

Win32 processes can communicate with each other in the following ways:

(1) clipboard (Clip Board );

(2) Dynamic Data Exchange );

(3) Component Object Model (Component Object Model );

(4) file mapping );

(5) Mail slots );

(6) pipelines (pipes );

(7) Win32 socket (socket );

(8) Remote Procedure Call );

(9) wm_copydata message (wm_copydata message ).

2. Obtain Process Information

In Win32, you can use the Process status helper function provided in psapi. DLL to help us obtain process information.

(1) The enumprocesses () function can obtain the process ID. Its prototype is:

Bool enumprocesses (DWORD * lpidprocess, dword cb, DWORD * cbneeded );

Lpidprocess: an array of the DWORD type that is large enough to store the id value of the process;

Parameter CB: the maximum length of the array that stores the process id value. It is a DWORD type data;

Cbneeded: pointer to a DWORD type data, used to return the number of processes;

Function return value: if the call is successful, true is returned, and the ID values of all processes are stored in the array pointed to by the lpidprocess parameter. The number of processes is stored in the variable pointed to by the cbneeded parameter; if the call fails, false is returned.

(2) The getmodulefilenameexa () function can obtain the process file name through the process handle. Its prototype is:

DWORD getmodulefilenameexa (handle hprocess, hmodule, lptstr lpstrfilename, DWORD nsize );

Hprocess: The parameter that accepts the Process Handle. It is a handle variable;

Hmodule: pointer-type parameter. The value in this article is null;

The lpstrfilename parameter is a pointer of the lptstr type. It is used to receive the character array pointer passed by the main function to store the process name;

Parameter nsize: the length of the array referred to by lpstrfilename;

Function return value: if the call is successful, a DWORD type data greater than 0 is returned, and the process name corresponding to hprocess is stored in the array pointed to by the lpstrfilename parameter; if the call fails, returns 0.

You can use the following code to traverse the processes in the system and obtain the process list:

// Obtain the total number of processes
Enumprocesses (process_ids, sizeof (process_ids), & num_processes );
// Process Traversal
For (INT I = 0; I <num_processes; I ++)
{
// Obtain the Handle Based on the process ID
Process [I] = OpenProcess (process_query_information | process_vm_read, 0,
Process_ids [I]);
// Obtain the process file name through a handle
If (getmodulefilenameexa (process [I], null, file_name, sizeof (filename )))
Cout <FILENAME <Endl;
}
Win32 thread

Win32 schedules a thread Based on the thread priority (to achieve the purpose of preemptible multitasking) and the CPU time allocated to the thread. Many Win32 applications also use multithreading features, such as the task manager.

Essentially, a single processor can only execute one thread ("micro-serial") at a time "). The Win32 multitasking mechanism makes the CPU seem to be processing multiple tasks at the same time, implementing "macro parallel ". Its multi-thread scheduling mechanism is as follows:

(1) run a thread until it is interrupted or the thread must wait for a resource to be available;

(2) Save the description table (context) of the current execution thread );

(3) load the description table (context) of the next execution thread );

(4) If there is a thread waiting for execution, repeat the above process.

Threads under Win32 may have different priorities. The priority ranges from 0 ~ 31, a total of 32 levels, 31 indicates the highest priority, priority 0 is reserved by the system. They can be divided into two types: Real-time priority and variable priority:

(1) The real-time priority ranges from 16 to 31, which is the high-priority thread used by real-time programs, such as many monitoring applications;

(2) The variable priority ranges from 1 to 15. The priority of most programs is within this range .. To optimize the system response time, Win32 schedulers can dynamically adjust their priority during their execution.

Multithreading does bring many benefits to application development. However, multithreading is not used in any case. You must consider it based on the specific circumstances of the application. In general, multithreading can be considered in the following situations:

(1) Tasks in applications are relatively independent;

(2) Some tasks are time-consuming;

(3) tasks must have different priorities.

In addition, multithreading should be considered for some real-time system applications.

  Win32 core object

Win32 core objects include processes, threads, files, events, semaphores, mutex, and pipelines. The core objects may have more than one owner, or even cross-process objects. A set of Win32 APIs are closely related to core objects:

(1) waitforsingleobject, used to wait for the "activation" of the object. Its function prototype is:

DWORD waitforsingleobject (
Handle hhandle, // wait for the object handle
DWORD dwmilliseconds // Number of waiting milliseconds. Infinite indicates unlimited waiting.
);

Objects that can be the first parameter of waitforsingleobject include: Change Notification, console input, event, job, memory resource notification, mutex, process, semaphore, thread, and waitable timer.

If the waiting object is unavailable, the thread will be suspended until the available thread of the object is awakened. Waitforsingleobject has different meanings for different objects. For example, use waitforsingleobject (hthread ,...) It can be used to determine whether a thread ends. waitforsingleobject (hmutex ,...) It can be used to determine whether it can enter the critical section; while waitforsingleobject (hprocess ,... Wait for the end of a process.

There is also a waitformultipleobjects function corresponding to waitforsingleobject, which can be used to wait for multiple objects. Its prototype is:

DWORD waitformultipleobjects (DWORD ncount, const handle * phandles, bool bwaitall, DWORD dwmilliseconds );

(2) closehandle, used to close objects. Its function prototype is:

Bool closehandle (handle hobject );

If the function is successfully executed, true is returned; otherwise, false is returned. You can use the getlasterror function to further obtain the cause of the error.

  C Runtime Library

In VC ++ 6.0, there are two multi-threaded programming methods: one is to use the C Runtime Library and Win32 API functions, and the other is to use MFC, MFC has powerful support for multi-threaded development.
The standard C Runtime Library was launched in 1970, and there was no concept of multithreading at that time. Therefore, early designers of the C Runtime Library cannot consider making it support multi-threaded applications.
Visual c ++ provides two versions of the C Runtime Library: one version for single-threaded applications to call, and the other version for multi-threaded applications to call. There are two major differences between the multi-thread Runtime Library and the single-thread Runtime Library:

(1) A global variable similar to errno is set for each thread;

In this way, the correct error information can be obtained from each thread.

(2) Data Structures in multi-threaded databases are protected by synchronization mechanisms.

This avoids access conflicts.

The multi-thread Runtime Library provided by Visual C ++ is divided into static and dynamic link libraries, and each type of Runtime Library can be further divided into debug and release versions, therefore, Visual C ++ provides six runtime libraries. See the following table:

C Runtime Library Library files
Single thread (static link) Libc. Lib
Debug single thread (static link) Libcd. Lib
Multithread (static link) Libcmt. Lib
Debug multithread (static link) Libcmtd. Lib
Multithread (Dynamic Link) Msvert. Lib
Debug multithread (Dynamic Link) Msvertd. Lib

If you do not use the VC multi-threaded C Runtime Library to generate a multi-threaded program, you must perform the following operations:

(1) use the standard C library (based on a single thread) and only allow reentrant function sets for library calls;

(2) Use Win32 API Thread management functions, such as createthread;

(3) Use Win32 services (such as semaphores, entercriticalsection, and leavecriticalsection functions) to synchronize non-reentrant functions.

If the VC Runtime library function is called using the standard C library, the following error is prompted during the link stage of the program:

Error lnk2001: unresolved external symbol _ endthreadex
Error lnk2001: unresolved external symbol _ beginthreadex

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.