CreateThread: simple multi-thread programming, createthread
CreateThread simple multi-thread programming
Author: vpoetMail: 18200268879@163.com
During multi-task processing, we often use multithreading technology. multithreading is theoretically used by multiple thread colleagues to handle different jobs, however, this is only for multi-core CPUs, but for Single-core CPU multithreading, the method is often implemented: the CPU allocates time slices for each thread, so that each thread can be executed cyclically, but this time slice is very short, therefore, the only image is like multiple threads working at the same time.
This article mainly uses the windows API CreateThread function for multi-threaded demonstration.
First, let's take a look at the description of the CreateThread function on MSDN:
Parameter description:
LpThreadAttributes
[In] Pointer to
SECURITY_ATTRIBUTESStructure that determines whether the returned handle can be inherited by child processes. If
LpThreadAttributesIs NULL, the handle cannot be inherited.
This parameter determines whether the Sub-thread inherits the Security Attribute of the parent process. If it is NULL, it means it does not inherit. For more information about the SECURITY_ATTRIBUTES struct, see MSDN.
DwStackSize
[In] Specifies the initial commit size of the stack, in bytes. the system rounds this value to the nearest page. if this value is zero, or is smaller than the default commit size, the default is to use the same size as the calling thread. for more information, see Thread Stack Size.
This parameter specifies the thread stack size. If the value is zero, the default thread stack size is used.
LpStartAddress
[In] Pointer to the application-defined function of type
LPTHREAD_START_ROUTINETo be executed by the thread and represents the starting address of the thread. For more information on the thread function, see
ThreadProc.
This parameter specifies the thread function address. In other words, it is the thread function name.
LpParameter
[In] Specifies a single parameter value passed to the thread.
This parameter is the parameter passed to the thread function.
DwCreationFlags
[In] Specifies additional flags that control the creation of the thread. If the create_susponded flag is specified, the thread is created in a susponded state, and will not run until
ResumeThreadFunction is called. If this value is zero, the thread runs immediately after creation. At this time, no other values are supported.
This parameter is the creation identifier. If it is zero, the thread will be executed immediately after creation. If it is create_susponded, the thread will stop after creation.
LpThreadId
[Out] Pointer to a variable that sums es the thread identifier.
This parameter is the ID of the thread to be created. The thread ID is a number that uniquely identifies the thread.
Now let's write a simple multi-thread example:
#include <windows.h>#include "stdio.h"DWORD WINAPI ThreadOne(LPVOID lpParameter){printf("ThreadOne is Runing\n");Sleep(100);return 0;}int main(){HANDLE HOne;printf("***********************vpoet******************\n");HOne=CreateThread(NULL,0,ThreadOne,NULL,0,NULL);printf("ThreadOne Begin!\n");CloseHandle(HOne);printf("MainThread Over!\n");return 0;}
Running result:
Success! Is there any problem? The Sub-thread seems to have exited without running the main thread. What is the problem,
This indicates that after the sub-thread is enabled, the main thread has been executed and returned before it can be run.
At this time, the entire program will exit, and of course the sub-thread will no longer run.
So how should we control it,
Since the Sub-thread is too late to run, I will let the main thread run for a while and wait until the sub-thread finishes executing and then the main thread exits.
Does it make sense? Well, I think.
Then we
printf("MainThread Over!\n");
Add a code before
Sleep(1000)
Delay the main thread for 1 s to wait for the sub-thread to run. Because 1 s is enough for the sub-thread to complete execution, the program will exit normally after the sub-thread stops running.
The running result is as follows:
Check it out. It is normal to exit.
Of course, there are other methods to wait for the sub-thread to run normally and return the results. By the way, there is another HOne that hasn't been introduced yet,
Handle is actually a Handle object, just like a struct or class, but it is a kernel object
Self-maintenance. Why do we need CloseHand ()? Baidu encyclopedia says this:
Closes a kernel object. This includes file, file ing, process, thread, security, and synchronization objects. After CreateThread is successful, a handle of hThread will be returned, and the count of the kernel object is increased by 1. After CloseHandle, the reference count is reduced by 1. When it changes to 0, the system deletes the kernel object. If CloseHandle is not called after the thread is executed, the kernel object may be leaked during the process execution, which is equivalent to the handle leakage, but different from the memory leakage, this will inevitably have a negative impact on system efficiency to a certain extent. However, when the process stops and exits, the system automatically cleans up these resources.
Then we need to know when the thread exits and Close the thread handle when it exits.
Here we will introduce an API called WaitForSingleObject;
Here's MSDN:
In this case, the function is returned only in the following two cases:
1. When the specified object has a signal status
2. Wait for timeout
What does that mean? Don't worry. Let's look at the parameters again:
HHandle
[In] Handle to the object. For a list of the object types whose handles can be specified, see the following Remarks section.
If this handle is closed while the wait is still pending, the function's behavior is undefined.
This parameter is a handle object. If the handle is still WaitForSingleObject after it has been closed, this situation is undefined. What does undefined mean? It will have unexpected results, to put it bluntly, it is a major hidden BUG.
DwMilliseconds
[In] Specifies the time-out interval, in milliseconds. The function returns if the interval elapses, even if the object's state is nonsignaled. If
DwMillisecondsIs zero, the function tests the object's state and returns immediately. If
DwMillisecondsIs INFINITE, the function's time-out interval never elapses.
This parameter specifies the timeout interval. If the parameter is set to zero, the function returns immediately. If the parameter is set to INFINITE, the function waits.
In addition, the return value of this function has two major states:WAIT_OBJECT_0 The state of the specified object is signaled. indicates that when The handle is in a signal state
WAIT_TIMEOUT The time-out interval elapsed, and the object's state is nonsignaled.
Now let's remove the Code with 1 s latency of Sleep of the main function and add the following sentence after CreateThread:
WaitForSingleObject(HOne,INFINITE);
Now let's look at the running results:
Sure enough. Now I understand what WaitForSingleObject (HOne, INFINITE); means.