如何在C ++中实现事件压缩

时间:2018-07-09 09:25:37

标签: c++ multithreading events compression

在我的应用程序中,我遇到了一系列Windows事件,我想压缩它们并用c ++处理唯一事件。

例如:事件W1,W2,W3,W4 ....,事件E1,E2等, 如果我在时间范围内仅获得W1系列,我想通过压缩相同系列的其余事件来仅处理一个事件。

#include <iostream>
#include <string>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <process.h>
#include <list>
#include <vector>
#include<Windows.h>
#include <future>
#include <fstream> 

static const char* WFEVENTNAME_EVENT1 = "Global\\WFEVENTNAME_EVENT1";
static const char* WFEVENTNAME_EVENT2 = "Global\\WFEVENTNAME_EVENT2";
static const char* WFEVENTNAME_EVENT3 = "Global\\WFEVENTNAME_EVENT3";
static const char* WFEVENTNAME_EVENT4 = "Global\\WFEVENTNAME_EVENT4";
static const char* WFEVENTNAME_EVENT5 = "Global\\WFEVENTNAME_EVENT5";
static const char* WFEVENTNAME_EVENT6 = "Global\\WFEVENTNAME_EVENT6";
static const char* WFEVENTNAME_EVENT7 = "Global\\WFEVENTNAME_EVENT7";
static const char* WFEVENTNAME_EVENT8 = "Global\\WFEVENTNAME_EVENT8";
static const char* WFEVENTNAME_EVENT9 = "Global\\WFEVENTNAME_EVENT9";
static const char* WFEVENTNAME_EVENT10 = "Global\\WFEVENTNAME_EVENT10";
static const char* WFEVENTNAME_EVENT11 = "Global\\WFEVENTNAME_EVENT11";
std::ofstream outfile;
typedef std::lock_guard<std::mutex> lockMutex;
typedef std::unique_lock<std::mutex> ulock;

class Handler1
{
public:
    bool ProcessMessage(std::string messageName)
    {
        printf("Processed Handler1\n");
        return true;
    }
};

class Handler2
{
public:
    bool ProcessMessage(std::string messageName)
    {
        printf("Processed Handler2\n");
        return true;
    }
};

class Handler3
{
public:
    bool ProcessMessage(std::string messageName)
    {
        printf("Processed Handler3\n");
        return true;
    }
};

class Handler4
{
public:
    bool ProcessMessage(std::string messageName)
    {
        printf("Processed Handler4\n");
        return true;
    }
};

class Handler5
{
public:
    bool ProcessMessage(std::string messageName)
    {
        printf("Processed Handler5\n");
        return true;
    }
};

class Handler6
{
public:
    bool ProcessMessage(std::string messageName)
    {
        printf("Processed Handler6\n");
        return true;
    }
};

unsigned _stdcall threadFuncToCollectSenderEvents(void* senderObject);
unsigned _stdcall threadFuncToProcessSenderEvents(void* senderObject);

class MessagingEventsNotifier
{
public:
    MessagingEventsNotifier()
    {
        _beginthreadex(0, 0, threadFuncToCollectSenderEvents, this, 0, 0);
        _beginthreadex(0, 0, threadFuncToProcessSenderEvents, this, 0, 0);
    }

    std::list<std::string> mySenderEvents;
    std::mutex myMutex;
    /// To notify to process the collected event
    std::condition_variable myConsumer;

    Handler1* myConnectionHandler;

    Handler2* myHandler2;

    Handler3* myLandmarkWorkflowHandler;

    Handler4* myHandler4;

    Handler5* myHandler5;

    Handler6* myHandler6;

    std::vector<HANDLE> myThreadHandles;
};

unsigned _stdcall threadFuncToCollectSenderEvents(void* senderObject)
{
    MessagingEventsNotifier *senderEventObject = static_cast<MessagingEventsNotifier*>(senderObject);

    while (true)
    {
        HANDLE hEvents[8];
        hEvents[0] = CreateEventA(NULL, false, false, WFEVENTNAME_EVENT3);
        hEvents[1] = CreateEventA(NULL, false, false, WFEVENTNAME_EVENT9);
        hEvents[2] = CreateEventA(NULL, false, false, WFEVENTNAME_EVENT5);
        hEvents[3] = CreateEventA(NULL, false, false, WFEVENTNAME_EVENT6);
        hEvents[4] = CreateEventA(NULL, false, false, WFEVENTNAME_EVENT1);
        hEvents[5] = CreateEventA(NULL, false, false, WFEVENTNAME_EVENT7);
        hEvents[6] = CreateEventA(NULL, false, false, WFEVENTNAME_EVENT2);
        hEvents[7] = CreateEventA(NULL, false, false, WFEVENTNAME_EVENT10);

        DWORD result = WaitForMultipleObjects(8, hEvents, false, INFINITE);

        lockMutex l(senderEventObject->myMutex);        
        if ((result - WAIT_OBJECT_0) == 0)
        {
            senderEventObject->mySenderEvents.push_back(WFEVENTNAME_EVENT3);
        }
        else if ((result - WAIT_OBJECT_0) == 1)
        {
            senderEventObject->mySenderEvents.push_back(WFEVENTNAME_EVENT9);
        }
        else if ((result - WAIT_OBJECT_0) == 2)
        {
            senderEventObject->mySenderEvents.push_back(WFEVENTNAME_EVENT5);
        }
        else if ((result - WAIT_OBJECT_0) == 3)
        {
            senderEventObject->mySenderEvents.push_back(WFEVENTNAME_EVENT6);
        }
        else if ((result - WAIT_OBJECT_0) == 4)
        {
            senderEventObject->mySenderEvents.push_back(WFEVENTNAME_EVENT1);
        }
        else if ((result - WAIT_OBJECT_0) == 5)
        {
            senderEventObject->mySenderEvents.push_back(WFEVENTNAME_EVENT7);
        }
        else if ((result - WAIT_OBJECT_0) == 6)
        {
            senderEventObject->mySenderEvents.push_back(WFEVENTNAME_EVENT2);
        }
        else if ((result - WAIT_OBJECT_0) == 7)
        {
            senderEventObject->mySenderEvents.push_back(WFEVENTNAME_EVENT10);
        }

        senderEventObject->myConsumer.notify_one();
    }

    return true;
}

unsigned _stdcall threadFuncToProcessSenderEvents(void* senderObject)
{
    MessagingEventsNotifier *senderEventObject = static_cast<MessagingEventsNotifier*>(senderObject);
    ulock unlockMutex(senderEventObject->myMutex);

    while (true)
    {
        senderEventObject->myConsumer.wait(unlockMutex);

        if (senderEventObject->mySenderEvents.size() <= 0)
        {
            continue;
        }

        senderEventObject->mySenderEvents.unique();

        for (std::list<std::string>::iterator it = senderEventObject->mySenderEvents.begin();
            it != senderEventObject->mySenderEvents.end(); ++it)
        {
            i++;
            std::string str = "Count = " + std::to_string(i) + "\n";
            outfile.write(str.c_str(), str.size());
            outfile.flush();

            printf("Processed Events Count: %d\n", i);

            std::string eventName = *it;
            if (eventName == WFEVENTNAME_EVENT3)
            {
                senderEventObject->myLandmarkWorkflowHandler->ProcessMessage(WFEVENTNAME_EVENT3);
                Sleep(10);
            }
            else if (eventName == WFEVENTNAME_EVENT9)
            {
                senderEventObject->myHandler2->ProcessMessage(WFEVENTNAME_EVENT9);
                Sleep(10);
            }
            else if (eventName == WFEVENTNAME_EVENT5)
            {
                senderEventObject->myHandler5->ProcessMessage(WFEVENTNAME_EVENT5);
                Sleep(10);
            }
            else if (eventName == WFEVENTNAME_EVENT6)
            {
                senderEventObject->myHandler5->ProcessMessage(WFEVENTNAME_EVENT6);
                Sleep(10);
            }
            else if (eventName == WFEVENTNAME_EVENT1)
            {
                senderEventObject->myConnectionHandler->ProcessMessage(WFEVENTNAME_EVENT1);
                Sleep(10);
            }
            else if (eventName == WFEVENTNAME_EVENT7)
            {
                senderEventObject->myConnectionHandler->ProcessMessage(WFEVENTNAME_EVENT7);
                Sleep(10);
            }
            else if (eventName == WFEVENTNAME_EVENT2)
            {
                senderEventObject->myHandler4->ProcessMessage(WFEVENTNAME_EVENT2);
                Sleep(10);
            }
            else if (eventName == WFEVENTNAME_EVENT10)
            {
                senderEventObject->myHandler6->ProcessMessage(WFEVENTNAME_EVENT10);
                Sleep(10);
            }
        }

        senderEventObject->mySenderEvents.clear();
    }
}

int main()
{
    MessagingEventsNotifier obj;

    for (int i = 1; i < 50; i++)
    {
        HANDLE handle1 = CreateEvent(NULL, 0, 0, WFEVENTNAME_EVENT10);
        SetEvent(handle1);
        Sleep(5);

        if (i % 2 == 0)
        {
            HANDLE handle2 = CreateEvent(NULL, 0, 0, WFEVENTNAME_EVENT3);
            SetEvent(handle2);
            Sleep(5);
        }

        if (i % 3 == 0)
        {
            HANDLE handle3 = CreateEvent(NULL, 0, 0, WFEVENTNAME_EVENT2);
            SetEvent(handle3);
            Sleep(5);
        }

        if (i % 5 == 0)
        {
            HANDLE handle3 = CreateEvent(NULL, 0, 0, WFEVENTNAME_EVENT6);
            SetEvent(handle3);
            Sleep(5);
        }

        if (i % 10 == 0)
        {
            HANDLE handle4 = CreateEvent(NULL, 0, 0, WFEVENTNAME_EVENT9);
            SetEvent(handle4);
            Sleep(5);
        }
    }

    HANDLE hEvent = CreateEventA(NULL, false, false, "SSSS");
    DWORD result = WaitForSingleObject(hEvent, INFINITE);
}

有两个线程:

  • 一个人将收集事件
  • 另一个将按顺序处理它们。

我的问题是:在处理过程中,我们可能会错过一些要收集的事件;如何处理这种情况?

我也想设计Windows事件机制和压缩。

请帮助我实现这种机制。

1 个答案:

答案 0 :(得分:0)

维护事件列表以及上次处理时间的时间戳。

遇到事件时,请在列表中进行搜索:

  • 如果找到,请检查是否已过所需时间,

    • 如果通过,请对其进行处理并更新其时间戳

    • 其他忽略

  • 如果找不到,请将其添加到带有时间戳的列表中并进行处理。