1

0から4までの数字をランダムな順序で取得することを期待していますが、代わりに、同期されていない混乱が発生しています

私は何を間違えますか?

#include <iostream>
#include <windows.h>
#include <process.h>

using namespace std;

void addQuery(void *v );

HANDLE ghMutex;

int main()
{
    HANDLE hs[5];
    ghMutex = CreateMutex( NULL, FALSE, NULL);         
    for(int i=0; i<5; ++i)
    {
        hs[i] = (HANDLE)_beginthread(addQuery, 0, (void *)&i);
        if (hs[i] == NULL) 
        {
            printf("error\n"); return -1;
        }
    }

    printf("WaitForMultipleObjects return: %d error: %d\n",
         (DWORD)WaitForMultipleObjects(5, hs, TRUE, INFINITE), GetLastError());


    return 0;
}

void addQuery(void *v )
{
    int t = *((int*)v);
    WaitForSingleObject(ghMutex, INFINITE);

    cout << t << endl;

    ReleaseMutex(ghMutex);
    _endthread();
}
4

2 に答える 2

6

ロックの共有変数を読み書きする必要があります。あなたはそれをロックの外で読んでいるので、ロックを無関係にしている。

ただし、共有変数はロックの保護なしで書き込んでいるループ変数であるため、それでも十分ではありません。はるかに良い例は次のように実行されます。

#include <iostream>
#include <windows.h>
#include <process.h>

using namespace std;

void addQuery(void *v );

HANDLE ghMutex;
int counter = 0;

int main()
{
    HANDLE hs[5];
    ghMutex = CreateMutex( NULL, FALSE, NULL);         
    for(int i=0; i<5; ++i)
    {
        hs[i] = (HANDLE)_beginthread(addQuery, 0, NULL);
        if (hs[i] == NULL) 
        {
            printf("error\n"); return -1;
        }
    }

    printf("WaitForMultipleObjects return: %d error: %d\n",
         (DWORD)WaitForMultipleObjects(5, hs, TRUE, INFINITE), GetLastError());


    return 0;
}

void addQuery(void *v)
{
    WaitForSingleObject(ghMutex, INFINITE);

    cout << counter << endl;
    counter++;

    ReleaseMutex(ghMutex);
    _endthread();
}

可能であれば、ミューテックスではなくクリティカルセクションを使用してください。使用が簡単で効率的だからです。ただし、ロッキングブロック内のコードのみを保護するという点で同じセマンティクスを持っています。

注:ジェリーは他のいくつかの問題を指摘していますが、私は高レベルの転送とシリアル化の問題に集中しました。

于 2011-10-20T19:51:34.847 に答える
-1

0synchronizationから4までの数字をランダムな順序で取得したいので、いくつかの問題があります。

問題は、変数がロックの外部に書き込まれ、スレッドの実行によってメソッドが呼び出されるiたびに、変更されたバージョンの変数を取得することです。そのため、すべての出力で値として表示される場合があります。addQueryi5

だから、これがこのシナリオの私の修正です。i関数のパラメーターで変数のアドレスを渡す代わりに、そのaddQuery値を渡す必要があります。それが役に立てば幸い:

#include <iostream>
#include <windows.h>
#include <process.h>

using namespace std;

void addQuery(void *v);

HANDLE ghMutex;

int main()
{
    HANDLE hs[5];
    ghMutex = CreateMutex(NULL, FALSE, NULL);
    for (int i = 0; i<5; ++i)
    {
        hs[i] = (HANDLE)_beginthread(addQuery, 0, (void *)i);

        if (hs[i] == NULL)
        {
            printf("error\n"); return -1;
        }
    }

    printf("WaitForMultipleObjects return: %d error: %d\n",
    (DWORD)WaitForMultipleObjects(5, hs, TRUE, INFINITE), GetLastError());


    return 0;
}

void addQuery(void *v)
{
    int t = (int)v;
    WaitForSingleObject(ghMutex, INFINITE);
    cout << t << endl;

    ReleaseMutex(ghMutex);
    _endthread();
}
于 2018-01-28T15:35:09.390 に答える