Multithreading in the programming has a very important position, we in the actual development or job interview can always encounter multi-threading problem, the degree of understanding of multithreading from a side reflects the programmer's programming level.
In fact, the C + + language itself does not provide a multithreaded mechanism, but the Windows system provides us with the relevant APIs, which we can use for multithreaded programming. This article explains the knowledge of multithreading programming in the form of examples.
creating API functions for Threads
C + + code
- HANDLE CreateThread (
- __in Sec_attrs
- Securityattributes,
- __in ULONG
- StackSize, //initial stack size
- __in Sec_thread_start
- Startfunction, //thread function
- __in PVOID
- Threadparameter, //thread argument
- __in ULONG
- Creationflags, //creation option
- __out Pulong
- ThreadId //thread identifier
- );
Here we use only the third and fourth arguments, the third argument passes the address of a function, the new thread we want to specify, and the fourth parameter is the parameter pointer to the new thread.
Multithreaded Programming Example 1:
C + + code
- #include <iostream>
- #include <windows.h>
- Using namespace std;
- DWORD WINAPI Fun (lpvoid lpparamter)
- {
- While (1) {cout<<' fun display! ' <<endl; }
- }
- int main ()
- {
- HANDLE hthread = CreateThread (null, 0, fun, NULL, 0, NULL);
- CloseHandle (Hthread);
- While (1) {cout<<"main display!" <<endl; }
- return 0;
- }
We can see that the main thread (main function) and our own thread (fun function) are randomly executed alternately, but the output of two threads is too fast, making it difficult to see clearly that we can use the function sleep to pause the execution of the thread.
C + + code
- VOID WINAPI Sleep (
- __in DWORD dwmilliseconds
- );
Dwmilliseconds represents 1 per thousand seconds, so Sleep (1000); Represents a pause of 1 seconds.
Multithreaded Programming Example 2:
C + + code
- #include <iostream>
- #include <windows.h>
- Using namespace std;
- DWORD WINAPI Fun (lpvoid lpparamter)
- {
- While (1) {cout<<' fun display! ' <<endl; Sleep (1000);}
- }
- int main ()
- {
- HANDLE hthread = CreateThread (null, 0, fun, NULL, 0, NULL);
- CloseHandle (Hthread);
- While (1) {cout<<"main display!" <<endl; Sleep (2000);}
- return 0;
- }
Executing the above code, this time we can clearly see the interleaved output of the fun display! and main display! on the screen, we find that these two functions are actually running concurrently, The attentive reader may find that our program will output line breaks whenever the fun function and main function output, but we see that there is a time when the program output is wrapped, and sometimes there is no output line break, or even a two line break. What's going on? Now let's change the program to see.
Multithreaded Programming Example 3:
C + + code
- #include <iostream>
- #include <windows.h>
- Using namespace std;
- DWORD WINAPI Fun (lpvoid lpparamter)
- {
- while (1) {cout<<' fun display!\n '; Sleep (1000);}
- }
- int main ()
- {
- HANDLE hthread = CreateThread (null, 0, fun, NULL, 0, NULL);
- CloseHandle (Hthread);
- while (1) {cout<<"main display!\n"; Sleep (2000);}
- return 0;
- }
We run this program again and we find that this time, as we expected, correctly outputs what we want to output and the format is correct. Let's talk about why our program didn't run correctly before. Multi-threaded programs run concurrently, and if some resources are shared between multiple threads, we cannot guarantee that these resources will be used correctly, because resources are not exclusive at this time, so let's take an example.
Multithreaded Programming Example 4:
If there is a resource int a = 3
There is a thread function selfadd () that function is to make a + = A;
There is also a thread function selfsub () that function is to make a-= A;
We assume that the above two threads are in parallel, if Selfadd is executing, we want to have a programming 6, but at this point Selfsub get the chance to run, so a becomes 0, wait until Selfadd to execute the opportunity, a + = A, but at this time a is 0, Not as we expected to 6.
We go back to the previous example 2, where we can think of the screen as a resource, this resource is shared by two threads, added when the fun function outputs the fun display!, will output Endl (that is, empty the buffer and wrap, where we can not understand what the buffer), But at this point the main function does get the chance to run, when the fun function has not time to output a newline to the CPU to the main function, and then the main function directly after the fun display! output main display!, As for why sometimes the program will output two consecutive lines, the reader can use the same analysis method to analyze, here I do not speak more, left to the reader to think.
So why do we change instance 2 to instance 3 and run it correctly? The reason is that while multiple threads are running concurrently, there are some operations that must be one go and not allowed to break, so we see that instance 2 and instance 3 run differently.
So, is not the code of Example 2 we can not let it run correctly? The answer is, of course, I'll tell you how to get the code for instance 2 to work correctly. This involves multi-threaded synchronization issues. For a resource to be pooled by multiple threads can cause confusion in the program, our workaround is to allow only one thread to have exclusive access to the shared resource, which will solve the problem above.
C + + code
- handle createmutex (
- LPSECURITY_ATTRIBUTES lpMutexAttributes, &NBSP;&NBSP
- bool binitialowner , // initial owner
- lpctstr lpname // object name
-
The function is used to create an exclusive resource, the first parameter we do not use, can be set to NULL, the second parameter specifies whether the resource is initially attributed to the process that created it, and the third parameter specifies the name of the resource.
C + + code
- HANDLE Hmutex = CreateMutex (null,true,"screen");
This statement creates a resource called screen and belongs to the process that created it.
C + + code
- BOOL ReleaseMutex (
- HANDLE Hmutex //HANDLE to mutex
- );
The function is used to free an exclusive resource, and once the process releases the resource, the resource is no longer part of it, and if it is used again, it needs to be re-requested. The functions for requesting resources are as follows:
C + + code
- DWORD WaitForSingleObject (
- HANDLE Hhandle, //HANDLE to Object
- DWORD dwmilliseconds //time-out interval
- );
The first parameter specifies the handle of the requested resource, and the second parameter is generally specified as infinite, which means that if the resource is not requested, it is waiting for the resource if it is specified as 0, indicating that once the resource is not available, it can also specify how long to wait before returning, in 1 per thousand seconds. Well, it's time for us to solve the problem of instance 2, we can make some changes to example 2, such as the following example.
Multithreaded Programming Example 5:
C + + code
- #include <iostream>
- #include <windows.h>
- Using namespace std;
- HANDLE Hmutex;
- DWORD WINAPI Fun (lpvoid lpparamter)
- {
- While (1) {
- WaitForSingleObject (Hmutex, INFINITE);
- cout<<"Fun display!" <<endl;
- Sleep (1000);
- ReleaseMutex (Hmutex);
- }
- }
- int main ()
- {
- HANDLE hthread = CreateThread (null, 0, fun, NULL, 0, NULL);
- Hmutex = CreateMutex (NULL, FALSE, "screen");
- CloseHandle (Hthread);
- While (1) {
- WaitForSingleObject (Hmutex, INFINITE);
- cout<<"Main display!" <<endl;
- Sleep (2000);
- ReleaseMutex (Hmutex);
- }
- return 0;
- }
Running this code will give us the expected output.
A classic example of getting Started with C + + multithreaded programming