-2
#include <windows.h>
#include <iostream>
using namespace std;

int count = 0;

DWORD WINAPI Tf1 ( LPVOID n )
{
    HANDLE hEvent = OpenEvent ( EVENT_ALL_ACCESS , false, (LPCWSTR)"MyEvent" );
    if ( !hEvent ) { return -1; }
    // Loop through and wait for an event to occur
    for ( ;; )
    {
        // Wait for the Event
        WaitForSingleObject ( hEvent, INFINITE );
        count++;
        printf("In function1, Counter value: %d\n",count);
        //    No need to Reset the event as its become non signaled as soon as
        //    some thread catches the event.
        if( count > 7 ) return 0;
    }
    CloseHandle(hEvent);
    return 0;
}

DWORD WINAPI Tf2 ( LPVOID n )
{

    HANDLE hEvent = OpenEvent ( EVENT_MODIFY_STATE , false, (LPCWSTR)"MyEvent" );
    if ( !hEvent ) return -1; 

    for ( ;; )
    {
        if( count % 2 == 0) 
            SetEvent (hEvent);
        else
        {
            count++;
            printf("In function2, Counter value: %d\n",count);
        }
        //    No need to Reset the event as its become non signaled as soon as
        //    some thread catches the event.
        if( count > 7 ) return 0;
    }
    CloseHandle(hEvent);
    return 0;
}

int main()
{
    //    Create an Auto Reset Event which automatically reset to 
    //    Non Signalled state after being signalled
    HANDLE     hEvent = CreateEvent ( NULL , false , false , (LPCWSTR)"MyEvent" );
    if ( !hEvent ) return -1;
    //    Create a Thread Which will wait for the events to occur
    HANDLE mutex = CreateMutex(NULL, FALSE, NULL);

    DWORD Id;
    HANDLE hThrd1 = CreateThread ( NULL, 0, (LPTHREAD_START_ROUTINE)Tf1,0,0,&Id );
    HANDLE hThrd2 = CreateThread ( NULL, 0, (LPTHREAD_START_ROUTINE)Tf2,0,0,&Id );

    if ( !hThrd1 ) { CloseHandle (hEvent); return -1; }
    if ( !hThrd2 ) { CloseHandle (hEvent); return -1; }
    // Wait for a while before continuing....
    Sleep ( 1000 );
    // Give the signal twice as the thread is waiting for 2 signals to occur

    // Wait for the Thread to Die
    WaitForSingleObject ( hThrd1, INFINITE );
    WaitForSingleObject ( hThrd2, INFINITE );

    CloseHandle ( hThrd1 );
    CloseHandle ( hThrd2 );
    CloseHandle ( hEvent );

    system ( "PAUSE" );
    return 0;
}

O / P:

In function1, Counter value: 1
In function1, Counter value: 3
In function2, Counter value: 2
In function2, Counter value: 4
In function2, Counter value: 6
In function1, Counter value: 5
In function1, Counter value: 7
In function2, Counter value: 8

望ましいO/P:

In function1, Counter value: 1
In function2, Counter value: 2
In function1, Counter value: 3
In function2, Counter value: 4
In function1, Counter value: 5
In function2, Counter value: 6
In function1, Counter value: 7
In function2, Counter value: 8

私はスレッドの力を利用していないことを知っています。しかし、私の要件はこのようなものです。どうすればこれを達成できますか?

4

2 に答える 2

1

スレッドを次々に実行する場合は、各スレッドにIDを割り当て、共有トークンを使用できます。たとえば、各スレッドが1ずつ増加する変数を考えます。スレッドは、値がIdと等しい場合にのみトークンを取得できます。トークンが取得されると、スレッドはその本体を実行し、トークンを1つインクリメントして解放します。

コードを順次実行したい場合、スレッドを使用するポイントは何ですか?:)

于 2012-10-30T20:44:44.110 に答える
1

このコードには、競合状態を止めるものは何もありません。スレッドがシグナルと待機でピンポンを再生するように 2 つのイベントが必要になるか、クリティカル セクションでカウンターを保護します。

オプション1:

// Thread 1
{
    increment counter
    Signal event 2
    Wait on event 1
}

// Thread 2
{
    Wait on event 2
    increment counter
    Signal event 1
}

オプション 2: (既存のパラダイムを使用)

// Thread 1
{
    Wait on event
    Acquire mutex
    if count is even
        increment counter
    end
    Release mutex
}

// Thread 2
{
    Acquire mutex
    if count is even
        Signal event
    else
        increment counter
    end
    Release mutex
}

オプション 2 は、スレッド 2 では少し競争が激しいことに注意してください... スレッド 1 がイベントに応答している間、複数回スピンする可能性があります。その点で、イベントを完全に削除して、両方のスレッドをスピンアウトさせることもできます...それを回避しようとしている場合は、オプション 1 を使用してください。

インターロックされたインクリメントの使用など、他の方法もありますが、とにかく上記のいずれかを試してください。

于 2012-10-30T20:56:43.250 に答える