【问题标题】:I want to make the execution order of threads sequentially one after another我想使线程的执行顺序一个接一个
【发布时间】:2012-10-30 20:39:44
【问题描述】:
#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

我知道我没有利用线程的力量。但我的要求是这样的。我怎样才能做到这一点?

【问题讨论】:

  • 那为什么要使用线程呢?这个要求从何而来?
  • 线程用于并行行为,如果你想串行执行使用单个线程
  • 我想让 2 个线程按顺序执行(不是单线程)。控制从线程 1 到线程 2,然后是线程 1,然后是线程 2...顺便说一句,这是我的教授给我的一个小任务。 .
  • 不会再来了!这种“请告诉我如何完全滥用线程”现在比“浮点运算不准确”更频繁地出现。就像@EtiennedeMartel 所说的那样——这些垃圾来自哪个可悲的教科书/教程/页面?哦——教授。告诉你的教授。想出更好的任务!

标签: c++ c multithreading winapi


【解决方案1】:

在这段代码中没有任何东西可以阻止竞争条件。您要么需要两个事件,以便线程通过信号和等待进行乒乓球比赛,要么使用临界区保护您的计数器。

选项 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。

还有其他方法可以使用,包括使用互锁增量,但无论如何尝试上述方法之一。

【讨论】:

    【解决方案2】:

    如果你想一个接一个地执行一个线程,你可以为每个线程分配一个 Id 并使用一个共享令牌,比如说一个每个线程递增 1 的变量。一个线程只有在它的值等于时才能获取令牌是身份证获取令牌后,线程执行其主体,然后将令牌递增 1 并释放它。

    如果您想要顺序执行代码,那么使用线程有什么意义呢? :)

    【讨论】:

    • 我用互斥锁试过这个但没用..你能详细解释一下吗:)
    • 这里是伪:1-lock_token,2-compare_it_to_id,3a-release_if_not_equal_and_exit,3b-otherwise_execute_thread_body,4-increment_token,5-unlock_token
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-13
    • 1970-01-01
    相关资源
    最近更新 更多