_beginthread, _beginthreadex

本文详细介绍了C/C++中使用_beginthread和_beginthreadex函数进行线程创建的方法,包括参数说明、返回值解释及注意事项等关键信息,并对比了这两种函数的不同之处。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


start_address

Start address of a routine that begins execution of a new thread. For _beginthread, the calling convention is either __cdecl (for native code) or __clrcall (for managed code); for _beginthreadex, it is either __stdcall (for native code) or __clrcall (for managed code).

stack_size

Stack size for a new thread or 0.

Arglist

Argument list to be passed to a new thread or NULL.

Security

Pointer to a SECURITY_ATTRIBUTES structure that determines whether the returned handle can be inherited by child processes. If NULL, the handle cannot be inherited. Must be NULL for Windows 95 applications.

Initflag

Initial state of a new thread (0 for running or CREATE_SUSPENDED for suspended); use ResumeThread to execute the thread.

Thrdaddr

Points to a 32-bit variable that receives the thread identifier. Might be NULL, in which case it is not used.

If successful, each of these functions returns a handle to the newly created thread; however, if the newly created thread exits too quickly, _beginthread might not return a valid handle (see the discussion in the Remarks section). _beginthread returns -1L on an error, in which case errno is set to EAGAIN if there are too many threads, to EINVAL if the argument is invalid or the stack size is incorrect, or to EACCES in the case of insufficient resources (such as memory). _beginthreadex returns 0 on an error, in which case errno and _doserrno are set.

If startaddress is NULL, the invalid parameter handler is invoked, as described in Parameter Validation. If execution is allowed to continue, these functions set errno to EINVAL and return -1.

For more information about these and other return codes, see _doserrno, errno, _sys_errlist, and _sys_nerr.

For more information about uintptr_t, see Standard Types.

The _beginthread function creates a thread that begins execution of a routine at start_address. The routine at start_address must use the __cdecl (for native code) or __clrcall (for managed code) calling convention and should have no return value. When the thread returns from that routine, it is terminated automatically. For more information about threads, see Multithreading.

_beginthreadex resembles the Win32 CreateThread API more closely than _beginthread does. _beginthreadex differs from _beginthread in the following ways:

  • _beginthreadex has three additional parameters: initflag, security, and threadaddr. The new thread can be created in a suspended state, with a specified security (Windows NT only), and can be accessed using thrdaddr, which is the thread identifier.

  • The routine at start_address passed to _beginthreadex must use the __stdcall (for native code) or __clrcall (for managed code) calling convention and must return a thread exit code.

  • _beginthreadex returns 0 on failure, rather than -1L.

  • A thread created with _beginthreadex is terminated by a call to _endthreadex.

The _beginthreadex function gives you more control over how the thread is created than _beginthread does. The _endthreadex function is also more flexible. For example, with _beginthreadex, you can use security information, set the initial state of the thread (running or suspended), and get the thread identifier of the newly created thread. You are also able to use the thread handle returned by _beginthreadex with the synchronization APIs, which you cannot do with _beginthread.

It is safer to use _beginthreadex than _beginthread. If the thread generated by _beginthread exits quickly, the handle returned to the caller of _beginthread might be invalid or, worse, point to another thread. However, the handle returned by _beginthreadex has to be closed by the caller of _beginthreadex, so it is guaranteed to be a valid handle if _beginthreadex did not return an error.

You can call _endthread or _endthreadex explicitly to terminate a thread; however, _endthread or _endthreadex is called automatically when the thread returns from the routine passed as a parameter. Terminating a thread with a call to endthread or _endthreadex helps to ensure proper recovery of resources allocated for the thread.

_endthread automatically closes the thread handle (whereas _endthreadex does not). Therefore, when using _beginthread and _endthread, do not explicitly close the thread handle by calling the Win32 CloseHandle API. This behavior differs from the Win32 ExitThread API.

Note Note

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.

The operating system handles the allocation of the stack when either _beginthread or _beginthreadex is called; you do not need to pass the address of the thread stack to either of these functions. In addition, the stack_size argument can be 0, in which case the operating system uses the same value as the stack specified for the main thread.

arglist is a parameter to be passed to the newly created thread. Typically it is the address of a data item, such as a character string. arglist can be NULL if it is not needed, but _beginthread and _beginthreadex must be provided with some value to pass to the new thread. All threads are terminated if any thread calls abort, exit, _exit, or ExitProcess.

The locale of the new thread is inherited from its parent thread. If per thread locale is enabled by a call to _configthreadlocale (either globally or for new threads only), the thread can change its locale independently from its parent by calling setlocale or _wsetlocale. For more information, see Locale.

For mixed and pure code, _beginthread and _beginthreadex both have two overloads, one taking a native calling-convention function pointer, the other taking a __clrcall function pointer. The first overload is not application domain-safe and never will be. If you are writing mixed or pure code you must ensure that the new thread enters the correct application domain before it accesses managed resources. You can do this, for example, by using call_in_appdomain Function. The second overload is application domain-safe; the newly created thread will always end up in the application domain of the caller of _beginthread or _beginthreadex.

 

详情见:http://msdn.microsoft.com/zh-cn/library/kdzttdcb.aspx?appId=Dev10IDEF1&l=ZH-CN&k=k(FEOF);k(DevLang-

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值