用C ++定义线程

时间:2012-10-17 16:45:12

标签: c++ winapi

如何使用_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;
}

3 个答案:

答案 0 :(得分:5)

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

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

请勿将您传递的函数指针转换为_beginthread_beginthreadexa function pointer cast is a bug waiting to happen

答案 1 :(得分:4)

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

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

  • _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退出之前等待你的线程完成,否则你可能看不到输出。