Windows core programming-Thread

Source: Internet
Author: User
A process consists of two parts: one is the process kernel object and the other is the address space. Likewise, a thread is composed of two parts:

• One is the kernel object of the thread, which is used by the operating system to manage the thread. The kernel object is also used by the system to store thread statistics.

• The other is the thread stack, which is used to maintain all function parameters and local variables required by the thread for code execution.

A process never executes anything. It is just a thread container. A thread is always created in a process environment, and its entire life cycle is in the process. If you have two or more threads running in a single process environment, the two threads will share a single address space. These threads can execute the same code and operate on the same data. These threads can also share the kernel object handle because the handle table depends on each process rather than each thread.
A thread is used to describe the running path in a process. Every time a process is initialized, the system creates a main thread. This thread starts running together with the startup code of the C/C ++ Runtime Library, start the code and call the entry point function (m a I n, w m a I n, wi n m a I n or W wi n m a I n ), continue to run until the start code of the C/C ++ Runtime Library calls e x I t p r o C E S. For many applications, this main thread is the only thread required by the application. However, processes can create more threads to help them perform their operations.

Multithreading has many advantages. It can make better use of the CPU and its computer resources, make the application interface and background operations at the same time, and provide more friendly user interfaces. however, improper use may cause unnecessary troubles. For example, Windows Explorer creates an independent thread for each folder window. It allows you to copy files from one folder to another and still view other folders on your system.
Createthread Function

Each thread must have an entry point function from which the thread starts to run. The entry point function of the main thread has been introduced earlier: m a I n, w m a I n, wi n m a I n or W wi n m a I n. If you want to create a secondary thread in your process, it must also be a entry point function, similar to the following:
The thread function must return a value that will become the exit code of the thread. This is similar to the principle of using the exit code of the main thread as the exit code of the process in the C/C ++ Runtime Library.

 

• Use function parameters and local variables whenever possible for thread functions (actually all your functions. When static variables and global variables are used, multiple threads can access these variables at the same time, which may damage the content of the variables. However, parameters and local variables are created in the thread stack, so they are unlikely to be damaged by another thread.


The previous section describes how to create the main thread of a process when calling the C r e a t e p r o c e s function. To create one or more auxiliary functions, you only need to have a running thread call C r e a t e t h r e a D:

 

 

Handle createthread (
Psecurity_attributes PSA,
DWORD cbstack,
Pthread_start_routine pfnstartaddr,
Pvoid pvparam,
DWORD fdwcreate,
Pdword pdwthreadid );

When C r e a t e t h r e a D is called, The system creates a thread kernel object.

The system allocates memory from the address space of the process for the stack of the thread. The process environment for running a new thread is the same as that for creating a thread. Therefore, the new thread can access all the handles of the kernel objects of the process, all the memory in the process, and the stacks of all other threads in the same process. This makes it very easy for multiple threads in a single process to communicate with each other.

Terminate the running of a thread

To terminate the running of a thread, use the following method:

• Thread function return (this method is recommended ).

• By calling the e x I t h r e a D function, the thread will undo it by itself (it is best not to use this method ).

• Threads in the same process or in another process call the Te r m I n a t e t h r e a D function (this method should be avoided ).

• Process containing threads stops running (this method should be avoided ).

Thread function return

Threads should always be designed in this form, that is, they can be returned when they want to terminate the operation. This is the only way to ensure that all thread resources are correctly cleared.

If the thread can return, the following items can be ensured:

• All C ++ objects created in the thread functions are correctly revoked through their undo functions.

• The operating system correctly releases the memory used by the thread stack.

• The system sets the exit code of the thread (maintained in the kernel object of the thread) as the return value of the thread function.

• The system will decrease the usage count of the thread kernel object.

Exitthread Function

The thread can call the e x I t h r e a D function to force the thread to terminate the operation:

VOID ExitThread(DWORD dwExitCode);

This function terminates the running of the thread and causes the operating system to clear all operating system resources used by the thread. However, C ++ resources (such as C ++ class objects) are not revoked.
Terminatethread Function

Calling the Te r m I n a t e t h r e a D function can also terminate the thread operation:

Bool terminatethread (
Handle hthread,
DWORD dwexitcode );

Unlike E x I t h r e a d, e x I t h r e a d always revokes the calling thread, te r m I n a t e t h r e a D can cancel any thread.
Note that the Te r m I n a t e t h r e a D function is a function that runs asynchronously, that is, it tells the system that you want the thread to terminate the operation, but when the function returns, the thread cannot be canceled. If You Need To Know exactly that the thread has been terminated, you must call wa I t f o r s I n g l e o B j e c t (Chapter 1) or similar functions, passing the thread handle. In addition, when the thread stops running, d l generally receives notifications. If the terminate thread is used to force the thread to terminate, d l will not receive the notification, which can prevent proper cleanup.
Undo the thread when the process stops running
E x I t p r o c e s and Te r m I n a T E P R o C E S functions can also be used to terminate thread running. The difference is that these threads will terminate all the threads in the terminated processes. In addition, because the entire process has been disabled, all resources used by the process must have been cleared. Of course, this includes the stacks of all threads. These two functions cause the remaining threads in the process to be forcibly revoked, just like calling te r m I n a t e t h r e a D from each remaining thread. Obviously, this means that the correct application clearing does not happen, that is, the C ++ object Undo function is not called, and the data is not transferred to the disk.
The operation that occurs when the thread stops running.

When the thread stops running, the following operations occur:

• All user objects owned by the thread are released. In wi n d o w s, most objects are owned by processes that contain threads that create these objects. However, a thread has two user objects, window and hook. When the thread stops running, the system will automatically undo any windows and uninstall any hooks created or installed by the thread. Other objects are revoked only when a thread-owning process stops running.

• The exit code of the thread is changed from s t I l _ a c t I v e to pass to e x I t h r e a D or TE r m I n a T E t h r e a D code.

• The status of the thread kernel object is changed to notified.

• If the thread is the last active thread in the process, the system regards the process as terminated.

• The usage count of the thread kernel object is reduced by 1.

When a thread stops running, the kernel object will not be automatically released until all unfinished references of the thread kernel object associated with it are closed.

Since a thread often needs to change its (or its process) Environment, wi n d o w s provides some functions so that the thread can easily reference its process kernel object, or reference its own thread kernel object:

Handle getcurrentprocess ();
Handle getcurrentthread ();

(You can also obtain the ID of the process and thread through corresponding functions)
Both of the above functions can return the pseudo handle of the Process calling the thread or the pseudo handle of the thread kernel object. These functions do not create a new handle in the process handling table. Also, calling these functions has no impact on the Use count of process or thread kernel objects. If c l o s e h a n d l e is called, the pseudo handle is passed as a parameter, then c l o s e h a n d l e will ignore the call of this function and return fa l s e.
Sometimes it is necessary to obtain the real handle of the thread rather than its pseudo handle. The so-called "real handle" refers to the handle used to clearly identify a unique thread. The pseudo handle of a thread is the handle of the current thread, that is, the handle of the thread that calls the function.
Convert a pseudo handle to a real handle. The d u p l I C A T E h a n d l e function can execute this conversion:

Bool duplicatehandle (
Handle hsourceprocess,
Handle hsource,
Handle htargetprocess,
Phandle phtarget,
DWORD fdwaccess,
Bool binherithandle,
DWORD fdwoptions );

You can usually use this function to create a new process-related handle using the kernel object related to another process.

It is also pointed out that d u p l I C A T E h a n d l e can be used to convert the pseudo handle of the process into the real handle of the process, as shown in the following code:

Handle hprocess;
Duplicatehandle (
Getcurrentprocess (), // handle of process that the Process
// Pseudo-handle is relative
Getcurrentprocess (), // process's pseudo-Handle
Getcurrentprocess (), // handle of process that the new, real,
// Process Handle is relative
& Hprocess, // will receive the new, real
// Handle identifying the process
0, // ignored because of duplicate_same_access
False, // new thread handle is not inheritable
Duplicate_same_access); // New Process Handle has same
// Access as pseudo-Handle

 

 

DWORD WINAPI ThreadFunc(PVOID pvParam){  DWORD dwResult = 0;  ...   return(dwResult);}

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.