在C 中定义线程

Define thread in C++

本文关键字:线程 定义      更新时间:2023-10-16

如何使用_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退出之前完成,或者您可能不会看到输出。