簡體   English   中英

並發消息處理按時間順序

[英]concurrent message processing ordered chronologically

我想在性能方面優化用C ++編寫的消息解碼器。 解碼器完全按順序設計。 實際並行化的概念很簡單:

一旦新數據到達某個套接字,就告訴線程池運行另一個線程,該線程將對接收到的消息進行解碼。

在每個線程的末尾,將調用一個方法(即將發出Qt信號),並傳遞在處理過程中創建的對象。

我的問題是:處理過的消息的長度和復雜性各不相同,因此線程完成的順序可能與收到消息的順序不同。 換句話說,我需要在不使用線程安全容器的情況下就地進行序列化。

如何確保線程一完成,就以正確的時間順序調用上述方法,而不會在線程安全的容器中對其進行排隊?

我的第一個想法是創建與線程池中的線程數量一樣多的互斥鎖,然后使用每個互斥鎖將“完成的”信號從較舊的線程發送到較新的線程。

任何意見表示贊賞!

如果您確實不想使用諸如priority_queue或一系列預先保留的緩沖區之類的數據結構來阻塞線程,則可以執行以下操作:

  1. 將您的消息與指示其原始位置的索引配對,然后將其傳遞給線程池。
  2. 使用一個公共(例如全局,原子)計數器變量來指示最后處理的消息。
  3. 讓每個線程等待,直到該變量指示先前的消息已被處理。
  4. 傳遞產生的對象並增加計數器

代碼看起來像這樣:

struct MsgIndexed {
    size_t idx;
    Msg msg;
};

//Single thread that receives all messages sequentially
void threadReceive() {
    for (size_t i = 1; true ; i++)
    {
        Msg m = readMsg();
        dipatchMsg(MsgIndexed{i,m});
    }
}

std::atomic<size_t> cnt=0;
//multiple worker threads that work in parallel
void threadWork() {
    while (1) {
        MsgIndexed msg = waitforMsg();
        Obj obj = processMsg(msg.msg);

        //Just for demonstration purposes. 
        //You probably don't want to use a spinlock here, but e.g. a condition variable instead     
        while (cnt != (msg.idx - 1u)) { std::this_thread::yield(); } 

        forwardObj(obj);
        cnt++;
    }
}

請注意,這是一個效率很低的解決方案,因為您的工作線程在完成實際工作后仍然需要等待。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM