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 に答える