如何使用_beginthreadex()
启动线程,使其执行void myFunction(wchar_t *param);
?我试着用这个:
_beginthread(NULL, 0, myFunction, L"someParam", 0, &ThreadID);
但有编译错误:
错误C2664:' beginthreadex':无法将参数3从'void( _cdecl *)(wchar_t *)'转换为'unsigned int(__stdcall *)(void *)'。
我如何解决此错误?我好像能做_beginthread((void(*)(void*))myFunction, 0 , (void *)L"someParam");
。但是对于_beginthreadex()
这些演员似乎不起作用。做什么
我需要去做?
此代码不输出任何内容。怎么了?
unsigned int __stdcall myFunction( void *someParam )
{
printf("Hello world!");
return 0;
}
int _tmain(int argc, _TCHAR* argv[])
{
_beginthreadex(NULL, 0, myFunction, L"param", 0, NULL);
return 0;
}
答案 0 :(得分:5)
_beginthreadex
需要一个使用__stdcall
calling convention的函数,而不是__cdecl
调用约定,这是默认值。要修复它,请使用__stdcall
调用约定声明您的线程过程:
unsigned int __stdcall myFunction(void *arg)
{
...
}
请勿将您传递的函数指针转换为_beginthread
或_beginthreadex
:a function pointer cast is a bug waiting to happen。
答案 1 :(得分:4)
每个Microsoft CRT线程启动函数的函数原型要求是:
_beginthread :void __cdecl procname(void * arg);
_beginthreadex :unsigned int __stdcall procname(void *arg);
您还应该了解两者之间的差异。
_beginthread :分配一个新线程并调用作为参数传递的线程过程。使用此API,线程创建参数有些限制。此函数的返回值是uintptr_t,但实际上是HANDLE类型的Windows线程句柄。它必须强制转换为HANDLE变量,以便在WaitForSingleObject
等函数中使用。当线程过程通过正常的函数退出时,运行时会自动关闭线程句柄。 这很重要。虽然这个函数返回一个类似于_beginthreadex的线程句柄,但是可以想象线程在你可以对句柄做任何事情之前启动并完成(例如等待,挂起等)。一旦线程过程完成,RT将关闭句柄,因此保存初始返回句柄的局部变量现在无效。
_beginthreadex :分配一个新线程并调用作为参数传递的线程过程。此版本允许更多地控制线程的创建方式,包括堆栈大小,初始挂起状态等。此函数的返回值是uintptr_t,但实际上是HANDLE类型的Windows线程句柄。它必须强制转换为HANDLE变量,以便在WaitForSingleObject
等函数中使用。当线程过程通过正常的函数退出时,线程句柄 NOT 会自动关闭运行时。 您负责关闭此函数返回的线程句柄,并且应该在不再需要时立即执行此操作。
使用哪个:如果您不需要在Wait函数等中使用线程句柄,请使用_beginthread
,并且没有特殊的线程创建需求(比如创建具有初始挂起状态的线程) )。当您需要等待的线程句柄,更好地控制创建参数等时,请使用_beginthreadex
。
编辑:OP的样本
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
#include <process.h>
unsigned int __stdcall MyThread(void *p)
{
_tprintf(_T("%s\n"), p);
_tprintf(_T("Thread finishing!\n"));
return 0;
}
int _tmain(int argc, TCHAR *argv[])
{
HANDLE hThread = (HANDLE)_beginthreadex(NULL, 0, MyThread, _T("Hello, World!"), 0, NULL);
if (hThread != INVALID_HANDLE_VALUE)
{
WaitForSingleObject(hThread, INFINITE);
CloseHandle(hThread);
_tprintf(_T("Thread finished!\n"));
}
return 0;
}
答案 2 :(得分:0)
与上面的其他答案一样,不要忘记在_tmain退出之前等待你的线程完成,否则你可能看不到输出。