On Windows multithreading

Source: Internet
Author: User

A thread is an execution unit in a process (at least one main thread per process), a process can have multiple threads, and a thread exists only in one process. Belong to a one-to-many relationship on a data relationship. The thread does not occupy system resources, and the resources it uses are all requested by the owning process to the system.

In multiprocessor, different threads can run on different CPUs at the same time, which can improve the efficiency of running the program. In addition, there are times when you have to use multithreading. For example, antivirus software, when killing the virus, it needs to scan the relevant disk files while showing the current scan progress and the problems found. If you put these jobs in one thread, you'll make the program look like it's stuck. In this case, divided into multiple threads, using different threads to accomplish different tasks, you can work together to achieve the desired effect.

APIs used to create threads:

HANDLE CreateThread (  lpsecurity_attributes lpthreadattributes,//indicates the security attribute of the creation thread, a pointer to the security_attributes struct, This parameter is generally set to null  size_t dwstacksize,//Specifies the stack size used by the thread, and if NULL, the same as the main thread stack  lpthread_start_routine lpstartaddress,// Specifies the thread function, which runs from the entrance of the function, which means that the thread terminates when the function is returned, and that the function belongs to the callback function. /* The thread callback function is defined as follows: DWORD  WINAPI  ThreadProc (    lpvoid  lpparameter); The return value of the function DWORD type, which has only one parameter, This parameter is given by the CreateThread function. The function name of the function can be arbitrarily defined. */  LPVOID lpparameter,//This parameter represents a parameter passed to a thread function, which enables a pointer to any data type,  DWORD dwcreationflags,//, indicating the state after the thread was created. The thread can be executed immediately after the thread is created, or the thread can be paused. If immediate execution is required, set to 0, if you want the thread to be in a paused state and set to create_suspened, you will need to call the ResumeThread function when the thread executes.  Lpdword lpthreadid//This parameter is used to return the thread ID of the newly created thread);

Try writing a multithreaded example with the following code:

#include <windows.h> #include <iostream>using namespace Std;dword WINAPI threadproc (lpvoid lpparam) {cout << "in ThreadProc" <<endl;return 0;} int main () {HANDLE hthread = CreateThread (null, 0, threadproc,null, 0, NULL);//code insertion at 1cout<< "in main" <<endl; CloseHandle (hthread); return 0;}

The results of operation 1 are as follows:

The results of Operation 2 are as follows:

In the first case, only "in main" was output, and the thread function we specified did not execute the output. This is because the main thread executes the first time slice that the CPU assigns to it, and the main thread finishes executing means the entire program is finished, and the newly created thread does not even have the opportunity to execute.

For this scenario, we can use the following API to make the newly created thread have the opportunity to execute its own thread function.

DWORD WaitForSingleObject (    HANDLE  hhandle,//The handle object to wait for    DWORD  dwmilliseconds//Specifies the number of milliseconds to wait for the timeout, if set to 0, is returned immediately, if set to infinite, it means waiting for the return of the thread function. INFINITE is a system-defined macro that is defined as follows: #define  INFINITE 0xFFFFFFFF);

If the function fails, returns wait_failed, returns WAIT_OBJECT_0 if the awaited object becomes fired, or returns wait_timeout if the wait time has ended before the wait object becomes the firing state.

We add the following statement at Code label 1:

WaitForSingleObject (Hthread, INFINITE);

The result of the operation is as follows:

For the second case, it may seem a bit dizzy at first glance, what is the output? In fact, two threads are interleaved when using the output stream buffers. Everyone adds data to the output buffer, so it is best to output the "hybrid" of the two threads to output data, not the data that a thread is going to output, nor the data that the B thread is going to output. What about this situation? Now that you can't use two threads at the same time, let's just use them separately.

You can use a critical section to resolve the problem. The critical section object is a critical_section data structure that the Windows operating system uses to protect critical code to ensure that shared resources under multithreading can be used correctly. At the same time, Windows allows only one thread to enter the critical section.

There are 4 functions for operating the critical section:

Initialize critical section

VOID  initializecriticalsection (    lpcritical  section  lpcriticalsection);

Enter the critical section

VOID  entercriticalsection (    lpcritical  section  lpcriticalsection);

Leave the critical section

VOID  leavecriticalsection (    lpcritical  section  lpcriticalsection);

Delete a critical section

VOID  deletecriticalsection (    lpcritical  section  lpcriticalsection);

The parameters of these 4 APIs are pointers to the critical_section struct.

At this point, we can modify the code to the following form:

#include <windows.h> #include <iostream>using namespace std; Critical_section g_cs;//defines the critical section object DWORD WINAPI ThreadProc (LPVOID lpparam) {entercriticalsection (&G_CS);//Enter the critical section cout << "in ThreadProc" <<endl; LeaveCriticalSection (&g_cs);//Leave the critical section return 0;} int main () {initializecriticalsection (&G_CS); HANDLE hthread = CreateThread (null, 0, threadproc,null, 0, NULL); EnterCriticalSection (&g_cs);cout<< "in main" <<endl; LeaveCriticalSection (&g_cs); WaitForSingleObject (Hthread, INFINITE); CloseHandle (hthread);D eletecriticalsection (&g_cs); return 0;}

At this point the execution results are as follows:



Sometimes, we may create more than one thread for other jobs, how do we reconcile them? The main point is two points: 1. When using public resources, remember to make them mutually exclusive. 2. Ensure that all work is done before exiting the program.

For the 2nd, there is an API that can wait for more than one specified handle:

  the DWORD WaitForMultipleObjects (DWORD  ncount,//is used to indicate the number of threads that you want the function to wait. This value needs to be between 1 and maximum_wait_objects. CONST HANDLE *lphandles,//The array pointer to the waiting thread handle bool  fwaitall,//indicates whether to wait for all threads to complete, and if set to true, waits for all DWORD  dwmilliseconds//wait timeout milliseconds, same as in WaitForSingleObject function);

Then, the code outlines for creating multiple threads are as follows:

Define a critical section; DWORD  WINAPI  threadproc (lpvoid  lpparam) {    Enter the critical section    to perform the desired operation in the shared resource;    There may be other operations in the non-critical area from the critical section;} int main () {    Initializes a critical section;    HANDLE Hthread[n] = {0};    for (int i = 0; i < N; ++i)    {        Hthread[i] = CreateThread (...);} WaitForMultipleObjects (N, Hthread, TRUE, INFINITE);//Some other operation for (i = 0; i < N; ++i) {    CloseHandle (hthread (i));} Delete critical section; return 0;}

Well, the knowledge of multithreading is extensive and profound, it is the first to share here.



On Windows multithreading

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.