在C 中定义线程
Define thread in C++
如何使用_beginthreadex()
启动线程,使其执行void myFunction(wchar_t *param);
?我尝试使用以下方式:
_beginthread(NULL, 0, myFunction, L"someParam", 0, &ThreadID);
但是存在汇编错误:
错误c2664:' beginThreadex':无法从'void( _cdecl *)(wchar_t *)'转换参数3。
我如何解决此错误?我似乎可以做_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;
}
_beginthreadex
需要一个使用 __stdcall
调用约定的函数,而不是默认的 __cdecl
调用约定。要修复它,请使用__stdcall
调用约定声明您的线程过程:
unsigned int __stdcall myFunction(void *arg)
{
...
}
不要将您传递到_beginthread
或_beginthreadex
的功能指针:函数指针铸造是一个错误等待发生的错误。
函数原型的函数原型要求每个Microsoft CRT线程启动功能是:
-
_BEGIGINTHREAD :
void __cdecl procname(void * arg);
-
_BEGIGINTHREADEX :
unsigned int __stdcall procname(void *arg);
您还应该意识到两者之间的差异。
-
_BEGINTHREAD :分配新线程并调用作为参数传递的线程过程。使用此API,线程创建参数有些限制。此函数的返回值是UINTPTR_T,但实际上是类型句柄的Windows线程句柄。必须将其施放到一个句柄变量中才能在
WaitForSingleObject
等功能中使用。这很重要。尽管此功能像_BeginThreadex一样返回线程句柄,但可以想到线程启动并完成,然后才能使用句柄(例如等待,悬挂等)。线程过程完成后,RT将关闭手柄,因此您的本地变量持有初始返回的手柄现在无效。 -
_BEGIGINTHREADEX :分配一个新线程并调用通过参数传递的线程过程。此版本可以大大控制线程的创建方式,包括堆栈大小,初始悬挂状态等。此功能的返回值是UINTPTR_T,但实际上是类型句柄的Windows线程句柄。必须将其施放到句柄变量中才能在诸如
WaitForSingleObject
等功能中使用。您有责任关闭此功能返回的线程句柄,并且应该立即这样做。
要使用的是:如果您不需要在等待功能等中使用线程句柄,并且没有特殊的线程创建需求(例如创建具有最初悬浮状态的线程),则使用_beginthread
。当您需要等待"线程句柄"时,请使用_beginthreadex
,对创建参数进行更精细的控制等。
编辑:op
的示例#include <windows.h>
#include <tchar.h>
#include <stdio.h>
#include <process.h>
unsigned int __stdcall MyThread(void *p)
{
_tprintf(_T("%sn"), 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;
}
与上面的另一个答案一样,别忘了等待线程在_tmain退出之前完成,或者您可能不会看到输出。
- 在销毁期间从另一个线程调用对象上调用方法是否未定义行为?
- C++多线程程序:变量定义为类成员的隔离错误
- 如何设置"this"线程的自定义名称?
- FFmpeg:使用自定义线程池进行并行编码
- glib:在另一个线程上处理自定义 GMainContext* 循环,不引发信号处理程序
- 自定义线程池的令人失望的性能
- 未定义的行为,具有setlocale和多线程
- 在C 中定义线程
- 在 C++ 中易变:我是否应该定义一个可能被几个线程更改的变量作为易失性
- openMP 在自定义容器中从 2 到 4 个线程执行二进制搜索时速度变慢
- 正在终止自定义标准::线程池
- C++自定义线程中创建 cef 对象
- 如何在 cocos2d-x 中的另一个线程中运行自定义网络代码
- 是否可以定义一个std::线程并在以后初始化它
- 如何以定义良好的线程安全方式将C++字符串传递给Java JNI
- 线程中的堆栈大小在C++中定义了什么
- 对Boost线程的未定义引用
- 在多线程应用程序中读写自定义映射时堆损坏
- 在Visual Studio 2010中定义线程
- 多线程使用用户定义的对象