2

如何使用 启动线程_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;
}
4

3 回答 3

5

_beginthreadex需要一个使用__stdcall 调用约定的函数,而不是__cdecl默认的调用约定。要修复它,请使用__stdcall调用约定声明您的线程过程:

unsigned int __stdcall myFunction(void *arg)
{
    ...
}

不要强制转换您要传入的函数指针,_beginthread或者_beginthreadex函数指针强制转换是一个等待发生的错误

于 2012-10-17T16:47:11.137 回答
4

每个 Microsoft CRT 线程启动函数的函数原型要求是:

您还应该了解两者之间的差异。

  • _beginthread:分配一个新线程并调用作为参数传递的线程过程。使用此 API,线程创建参数有些受限。这个函数的返回值是一个uintptr_t,但实际上是一个HANDLE类型的Windows线程句柄。它必须转换为 HANDLE 变量才能在诸如 等函数中使用WaitForSingleObject。当线程过程通过正常的函数退出完成时,运行时会自动为您关闭线程句柄。这很重要。虽然这个函数像_beginthreadex一样返回一个线程句柄,但是可以想象线程的开始和结束在您可以对句柄执行任何操作之前(例如等待、挂起等)。一旦线程过程完成,RT 将关闭句柄,因此保存初始返回句柄的局部变量现在无效。

  • _beginthreadex:分配一个新线程并调用作为参数传递的线程过程。此版本允许对线程的创建方式进行更多控制,包括堆栈大小、初始挂起状态等。此函数的返回值是 uintptr_t,但实际上是 HANDLE 类型的 Windows 线程句柄。它必须转换为 HANDLE 变量才能在诸如 等函数中使用WaitForSingleObject。当线程过程通过正常的函数退出完成时,运行时不会自动为您关闭线程句柄。您有责任关闭此函数返回的线程句柄,并且一旦不再需要它就应该这样做

使用哪个:_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;
}
于 2012-10-17T17:03:24.510 回答
0

与上面的其他答案一样,不要忘记在 _tmain 退出之前等待线程完成,否则您可能不会看到任何输出。

于 2012-10-24T23:09:56.550 回答