簡體   English   中英

C++中多線程聯網通知的設計

[英]Design of multi-threaded networking notifications in C++

基本上,我的程序可以使用幾種操作模式,每種模式都需要初始化然后更新。 每種模式都有自己的配置結構。

在收到消息並確定其描述的模式后如何通知主線程進行初始化然后開始更新該模式? (我正在尋找在 C++17 中實現它的最佳方法的大綱)

澄清一下,它是一個守護程序應用程序。 初始化后,主線程的唯一工作就是進行模式更新所需的計算。 網絡是使用 Boost.Asio 在單獨的工作線程上完成的。 我還期望(因為我也在編寫客戶端程序)模式更改的頻率會很低(最大~10hz),所以我想避免使用隊列,因為模式是為了控制一個機器人,隊列會增加延遲。

假設您的主線程可以在啟動主代碼之前等待網絡下載完成,您可以使用std::condition_variable

你的主線程這樣做:

std::condition_variable cv;
std::mutex mut;
bool networkOperationCompleted;
Config globalconfig;

int main()
{
     // initialize whatever kicks off the network thread

     std::unique_lock<std::mutex> lck(mut);
     while (networkOperationCompleted == false)
     {
         cv.wait();
     }
}

同時,您的網絡線程執行以下操作:

extern std::condition_variable cv;
extern std::mutex mut;
extern bool networkOperationCompleted;
extern Config globalconfig;

void background_task()
{

     Config config;
     DownloadTheConfig(&config);
     {
         std::unique_lock<std::mutex> lck(m);
         globalConfig = config;
         networkOperationComplete = true;
         cv.notify_all();
     }
}
 

我最終選擇了這樣的東西:

class config
{
public:
    using empty = std::monostate;

    struct modeA
    {
        ...
    };

    struct modeB
    {
        ...
    };

    template<typename T, typename Lambda>
    void handle(Lambda&& handler) const
    {
        if (std::holds_alternative<T>(storage))
        {
            handler(std::get<T>(storage));
        }
    }

    void clear()
    {
        storage = empty{};
    }

private:
    std::variant<empty, modeA, modeB> storage;
};

config server::pop_cfg()
{
    std::unique_lock lock{cfg_mutex};
    config copy{cfg};
    cfg.clear();
    return copy;
}

int main()
{
    ...

    mode* mode;
    while (true)
    {
        config cfg = server.pop_cfg();
        
        cfg.handle<config::empty>([&](...) {
            mode->update();
        });
        
        cfg.handle<config::modeA>([&](config::modeA cfg) {
            mode = new ModeA(cfg);
        });
        
        cfg.handle<config::modeB>([&](config::modeB cfg) {
            mode = new ModeB(cfg);
        });
    }
}

暫無
暫無

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

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