0

スレッドを複数回呼び出して、変数が台無しになるという問題があります。私はスレッドが初めてなので、単純なものが欠けていると確信しています。

struct PARAMS
{
    time_t secondsAtStart;
};

DWORD WINAPI ProcessChange(void* parameter) {
    PARAMS* params = (PARAMS*)parameter;
    Sleep(3000);
    _tprintf(TEXT("Seconds: (%d)\n"), params->secondsAtStart);
    return 0;
}


void FileChanged(CString filename, CString action) {
    struct PARAMS *params = NULL;
    params = (struct PARAMS *)malloc(sizeof(PARAMS)+1);
    params->secondsAtStart = time(null);
    // I've also tried it this way.    
    //PARAMS params;
    //params.secondsAtStart = time(NULL);
    HANDLE hThread = CreateThread(NULL, 0, ProcessChange, &params, 0, NULL);
    // If I uncomment this, it works, but just one thread runs at a time.
    //WaitForSingleObject(hThread, INFINITE);
}

WaitForSingleObject のコメントを外さないと、secondsAtStart 変数が破損します。私が必要とする最終的な結果は、FileChanged が次々に 3 回呼び出された場合、最初の 2 回の実行では何もせず、最後の 1 回でアクションを実行することです。

ありがとう、ベン

4

1 に答える 1

1

関数のローカル変数、つまり自動ストレージの変数のアドレス(または参照)をスレッドに渡すと、スレッドが関数よりも長く存続する場合、未定義の動作が発生します。

コードでparamsは、動的ストレージのオブジェクトを指しますが、ポインター自体はローカル変数です。そのアドレス &paramsをスレッドに渡します。これは、スレッドが終了するのを待つことによって、ポインターがスレッドよりも長く存続することを保証する場合にのみ機能します。それ以外の場合は、未定義の動作が発生します。これは、印刷される無意味な値に非常に自然に現れます。

params代わりに合格&paramsすると問題が解決するはずです。(記述されたコードはメモリリークを引き起こすことにも注意してください。スレッドの終了freeに実際に割り当てられたスペースを確認する必要があります。)

于 2013-01-22T04:05:29.420 に答える