Win32 Multi-thread creation method and basic usage

Source: Internet
Author: User

 

This section summarizes the APIs and basic usage frameworks provided by Win32 for creating multithreading.

Ref:

Msdn: http://msdn.microsoft.com/zh-cn/library/y6h8hye8 (V = vs.100)

Win32 Multi-thread creation methods include:

(1) createthread ()

(2) _ beginthread () & _ beginthreadex ()

(3) afxbeginthread ()

(4) cwinthread class

(1) createthread ()

Baidu Encyclopedia: http://baike.baidu.com/view/1191444.htm

Function prototype:

View plaincopy to clipboardprint?
01. Handle createthread (
02. lpsecurity_attributes lpthreadattributes,
03. DWORD dwstacksize,
04. lpthread_start_routine lpstartaddress,
05. lpvoid lpparameter,
06. DWORD dwcreationflags,
07. lpdword lpthreadid );
08 .}
Handle createthread (
Lpsecurity_attributes lpthreadattributes,
DWORD dwstacksize,
Lpthread_start_routine lpstartaddress,
Lpvoid lpparameter,
DWORD dwcreationflags,
Lpdword lpthreadid );
}

Header file: Windows. h

Createthread is the most basic API provided by Win32 to create a thread. It is used to create a thread on the main thread. Returns a handle (kernel object ).

Brief description of parameters:

Lpthreadattributes: Specifies the attributes of a thread. null indicates that the default settings are used. Dwstacksize: Specifies the thread stack size. The default value is 0. Windows dynamically increases the stack size as needed. Lpstartaddress: pointer to the thread function. Lpparameter: The parameter passed to the thread function. Dwcreationflags: indicates the thread flag. create_sureceivded indicates that a suspended thread is created, and 0 indicates that the thread is activated immediately after creation. Lpthreadid, the ID of the first thread (output parameter ).

Code for creating a thread:

View plaincopy to clipboardprint?
01. # include "stdafx. H"
02. # include
03.
04. DWORD winapi threadproc (lpvoid lpparam)
05 .{
06. printf ("sub thread started \ n ");
07. printf ("sub thread finished \ n ");
08. Return 0;
09 .}
10.
11. Int main (INT argc, char * argv [])
12 .{
13. DWORD threadid;
14. Handle hthread;
15. hthread = createthread (null, 0, threadproc, null, 0, & threadid); // create a thread
16.
17. Return 0;
18 .}
# Include "stdafx. H"
# Include

DWORD winapi threadproc (lpvoid lpparam)
{
Printf ("sub thread started \ n ");
Printf ("sub thread finished \ n ");
Return 0;
}

Int main (INT argc, char * argv [])
{
DWORD threadid;
Handle hthread;
Hthread = createthread (null, 0, threadproc, null, 0, & threadid); // create a thread

Return 0;
}
If the above code is used directly, there may be no output. This is because the main thread continues to run down after the sub-thread is created, the main code thread in the subthread may end before it can be executed. This requires another API for synchronization: waitforsingleobject ().

Waitformultipleobjects is also used to synchronize a set of kernel objects. (See http://msdn.microsoft.com/zh-cn/site/ms686360to get all the synchronization functions.

Waitforsingleobject prototype: DWORD winapi waitforsingleobject (_ in handle hhandle, _ in DWORD dwmilliseconds); the first parameter is the handle of the kernel object to be waited, the second parameter is to set the wait timeout time. It can be set to infinite, which means waiting until a signal is triggered.

After the kernel object is used, it usually needs to be closed. The closehandle () function is used, and the parameter is the kernel object handle.

Therefore, the following is an example of the most basic use of createthread:

View plaincopy to clipboardprint?
01. # include "stdafx. H"
02. # include
03.
04. DWORD winapi threadproc (lpvoid lpparam)
05 .{
06. printf ("sub thread started \ n ");
07. // todo: add your thread code here.
08. printf ("sub thread finished \ n ");
09. Return 0;
10 .}
11.
12. Int main (INT argc, char * argv [])
13 .{
14. DWORD threadid;
15. Handle hthread;
16. hthread = createthread (null, 0, threadproc, null, 0, & threadid); // create a thread
17.
18. waitforsingleobject (hthread, infinite );
19. closehandle (hthread); // close the Kernel Object
20.
21. Return 0;
22 .}
# Include "stdafx. H"
# Include

DWORD winapi threadproc (lpvoid lpparam)
{
Printf ("sub thread started \ n ");
// Todo: add your thread code here.
Printf ("sub thread finished \ n ");
Return 0;
}

Int main (INT argc, char * argv [])
{
DWORD threadid;
Handle hthread;
Hthread = createthread (null, 0, threadproc, null, 0, & threadid); // create a thread

Waitforsingleobject (hthread, infinite );
Closehandle (hthread); // closes the Kernel Object

Return 0;
}
(2) _ beginthread () & _ beginthreadex ()

Baidu Encyclopedia: http://baike.baidu.com/view/3029167.htm

Msdn: http://msdn.microsoft.com/zh-cn/library/kdzttdcb.aspx

Function prototype:

View plaincopy to clipboardprint?
01. uintptr_t _ beginthread (// native code
02. Void (_ cdecl * start_address) (void *),
03. Unsigned stack_size,
04. Void * Arglist
05 .);
Uintptr_t _ beginthread (// native code
Void (_ cdecl * start_address) (void *),
Unsigned stack_size,
Void * Arglist
);

Header file: process. h

Parameter description: The first parameter is the pointer of the thread function, the second parameter is the stack size, and the third parameter is the list of parameters to be passed to the thread function. The return value is also a thread handle (for more information, refer to msdn ).
Similarly, for synchronization of _ beginthread (), like createthread, The waitforsingleobject function can be used to disable kernel objects. In addition, the _ beginthread () thread function has no return value type. You can use _ endthread () to end the thread in the thread function.

The following is a basic example of using _ beginthread:

View plaincopy to clipboardprint?
01. # include "stdafx. H"
02. # include
03. # include
04.
05. Void _ cdecl threadproc (void * para)
06 .{
07. printf ("sub thread started \ n ");
08. // todo: add your thread code here.
09. printf ("sub thread finished \ n ");
10. _ endthread (); // can be omitted, which is implicitly called.
11 .}
12.
13. Int main (INT argc, char * argv [])
14 .{
15. Handle hthread = (handle) _ beginthread (threadproc, 0, null );
16.
17. waitforsingleobject (hthread, infinite );
18. closehandle (hthread );
19 .}
# Include "stdafx. H"
# Include
# Include

Void _ cdecl threadproc (void * para)
{
Printf ("sub thread started \ n ");
// Todo: add your thread code here.
Printf ("sub thread finished \ n ");
_ Endthread (); // can be omitted, which is implicitly called.
}

Int main (INT argc, char * argv [])
{
Handle hthread = (handle) _ beginthread (threadproc, 0, null );

Waitforsingleobject (hthread, infinite );
Closehandle (hthread );
} In addition, there is also a function _ beginthreadex (), which can be simply considered as a simplified version of _ beginthread (), so more often it is easier to use _ beginthread.
Note: An Important prompt is displayed in msdn, with the content "for an executable file linked with libcmt. lib, do not call the Win32 exitthread API; this prevents the run-time system from reclaiming allocated resources. _ endthread and _ endthreadex reclaim allocated thread resources and then call
Exitthread. ", simple translation means that for the link libcmt. lib executable program. Do not use the Win32 thread to exit the function (exitthread). This will prevent the system from recycling allocated resources during the runtime. Use _ endthread, it can recycle allocated thread resources and then call exitthread. This problem does not seem to mention createthread (), but it is actually related. This is often seen in some documents that "do not use createthread to create a thread, otherwise it will cause memory leakage.

Cause: Memory leakage of createthread (difference between createthread and _ beginthread)

Related Topics: http://wenku.baidu.com/view/adede4ec4afe04a1b071dea4.html http://www.cnblogs.com/whiteyun/archive/2011/06/02/2067742.html ....

1. _ beginthread also uses createthread to create a thread, but _ beginthread encapsulates it and stores related "Resources" through the local storage (TLS) of the thread) the parameters passed to the thread function are released when _ endthread is called.

2. Not all situations where createthread is used may have memory leakage. I have read many people's articles, only copyright (copyright belongs to the original author ).

We recommend that you replace createthread with _ beginthread to create a thread.

(3) afxbeginthread ():

Obviously, this is the afx Series Function in MFC, a global function that creates threads in MFC. Since it is not very easy to use MFC now, I will not talk about it here.

(4) cwinthread class:

Obviously, it is the class used to create threads in MFC.

Please add it!

(1) supplementary content:

The waitformultipleobjects cannot be used in _ beginthread.

Problem: when multiple threads are created using _ beginthread, waitformultipleobjects cannot be used for synchronization.

You can use the following example to test this problem:

View plaincopy to clipboardprint?
01. # include "stdafx. H"
02. # include
03. # include
04.
05. Void _ cdecl threadproc (void * para)
06 .{
07. printf ("sub thread started \ n ");
08. // todo: add your thread code here.
09. printf ("sub thread finished \ n ");
10. _ endthread (); // can be omitted, which is implicitly called.
11 .}
12.
13. Int main (INT argc, char * argv [])
14 .{
15. DWORD threadid;
16. Handle hthread [10];
17. For (INT I = 0; I <10; I ++)
18. hthread [I] = (handle) _ beginthread (threadproc, 0, null );
19.
20. waitformultipleobjects (10, hthread, true, infinite); // All threads cannot be synchronized!
21. For (INT I = 0; I <10; I ++ ){
22. closehandle (hthread );
23 .}
24 .}
# Include "stdafx. H"
# Include
# Include

Void _ cdecl threadproc (void * para)
{
Printf ("sub thread started \ n ");
// Todo: add your thread code here.
Printf ("sub thread finished \ n ");
_ Endthread (); // can be omitted, which is implicitly called.
}

Int main (INT argc, char * argv [])
{
DWORD threadid;
Handle hthread [10];
For (INT I = 0; I <10; I ++)
Hthread [I] = (handle) _ beginthread (threadproc, 0, null );

Waitformultipleobjects (10, hthread, true, infinite); // All threads cannot be synchronized!
For (INT I = 0; I <10; I ++ ){
Closehandle (hthread );
}
}
The expected result is that the program can output the message of the End of thread creation 10 times, but the actual running result cannot reach so many times. Why? This is because waitformultipleobjects cannot work properly here. The reason is:

_ Endthread () automatically calls closehandle to close the kernel object when the thread ends. This is easy to explain. If the kernel object is disabled in advance, waitformultipleobjects will return an error. Is there any method specifically used to synchronize the threads created by _ beginthread? As far as I know, it seems that there is no such thing! To solve this problem, you can call waitforsingleobject to synchronize data. Of course, you can also use other disguised methods. In addition, the closehandle mentioned above can be called no longer.

Conclusion: It seems that _ beginthread is not so easy to use. :)

Related Article

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.