如何使用WINAPI事件用c解决生产者 - 消费者++?(How to solve Producer

2019-09-26 07:32发布

我需要解决在C生产者 - 消费者问题++使用基本同步对象 - 事件,我已经写了这个代码

static int g_x = 0;
HANDLE hEvent1;

HANDLE aThread[2];
DWORD ThreadID;

//tread 1
void Producer()
{
    for (int i = 0; i < 100; ++i)
    {
        WaitForSingleObject(hEvent1, INFINITE);
        g_x = i;
        SetEvent(hEvent1);
    }
}
//thread 2
void Consumer()
{
    for (;;)
    {
        WaitForSingleObject(hEvent1, INFINITE);
        SetEvent(hEvent1);
    }
}

int createthreads() {
    hEvent1 = CreateEvent(NULL, FALSE, TRUE, NULL);

    // Create worker threads
    aThread[0] = CreateThread( NULL, 0, (LPTHREAD_START_ROUTINE)Producer, NULL,  0, &ThreadID);
    aThread[1] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)Consumer, NULL, 0, &ThreadID);
}
int main() {
    createthreads();
}

此代码不能正常工作:我有无限循环我怎样才能解决这个代码在控制台号码来获得从099

Answer 1:

你需要另一个事件syncronize这两个线程。 我设立两个事件的初始状态FALSE ,我送一个启动事件生产者线程上的main
这样,您就可以控制何时以及如何处理已启动。

和Offtopic, createthreads必须返回一个值。

static int g_x = 0;
HANDLE hEvent1;
HANDLE hEvent2;

HANDLE aThread[2];
DWORD ThreadID;

//tread 1
void Producer()
{
    for (int i = 0; i < 100; ++i)
    {
        WaitForSingleObject(hEvent1, INFINITE);
        g_x = i;
        SetEvent(hEvent2);
    }
}
//thread 2
void Consumer()
{
    for (;;)
    {
        WaitForSingleObject(hEvent2, INFINITE);
        SetEvent(hEvent1);
    }
}

int createthreads() {
    hEvent1 = CreateEvent(NULL, FALSE, FALSE, NULL);
    hEvent2 = CreateEvent(NULL, FALSE, FALSE, NULL);

    // Create worker threads
    aThread[0] = CreateThread( NULL, 0, (LPTHREAD_START_ROUTINE)Producer, NULL,  0, &ThreadID);
    aThread[1] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)Consumer, NULL, 0, &ThreadID);
    return 0;
}
int main() {
    createthreads();
    SetEvent(hEvent1);
}


Answer 2:

存在许多方式来实现这一任务,一个可能的 - 需要使用事件对 - 2个事件。

struct EventPair 
{
    HANDLE hLowEvent, hHighEvent;

    ~EventPair()
    {
        if (hHighEvent) CloseHandle(hHighEvent);
        if (hLowEvent) CloseHandle(hLowEvent);
    }

    EventPair()
    {
        hLowEvent = 0, hHighEvent = 0;
    }

    DWORD Create()
    {
        return (hLowEvent = CreateEvent(NULL, FALSE, FALSE, NULL)) &&
            (hHighEvent = CreateEvent(NULL, FALSE, FALSE, NULL)) ? NOERROR : GetLastError();
    }
};

struct SharedData : EventPair 
{
    int _x;
    bool _quit;

    SharedData()
    {
        _x = 0;
        _quit = false;
    }

    static DWORD WINAPI _Producer(void* This)
    {
        reinterpret_cast<SharedData*>(This)->Producer();
        ExitThread(0);
    }

    void Producer()
    {
        for (int i = 0; ; )
        {
            _x = i++;
            if (i == 100)
            {
                _quit = true;
            }
            SetEvent(hLowEvent);
            if (_quit)
            {
                return;
            }
            WaitForSingleObject(hHighEvent, INFINITE);
        }
    }

    static DWORD WINAPI _Consumer(void* This)
    {
        reinterpret_cast<SharedData*>(This)->Consumer();
        ExitThread(0);
    }

    void Consumer()
    {
        for(;;) 
        {
            WaitForSingleObject(hLowEvent, INFINITE);
            DbgPrint("%u\n", _x);
            if (_quit)
            {
                return;
            }
            SetEvent(hHighEvent);
        }
    }
};

void testPC()
{
    SharedData sd;
    if (!sd.Create())
    {
        HANDLE hThreads[2] = {};
        if (hThreads[0] = CreateThread(0, 0, SharedData::_Producer, &sd, 0, 0))
        {
            if (hThreads[1] = CreateThread(0, 0, SharedData::_Consumer, &sd, 0, 0))
            {
                WaitForMultipleObjects(2, hThreads, TRUE, INFINITE);
                CloseHandle(hThreads[1]);
            }
            else
            {
                sd._quit = true;
                SetEvent(sd.hHighEvent);
                WaitForSingleObject(hThreads[0], INFINITE);
            }
        }
        CloseHandle(hThreads[0]);
    }
}


文章来源: How to solve Producer-Consumer using winapi events in c++?