2016-11-23 34 views
1

我有一個類封裝了所有與使用Asio讀取和寫入通用流套接字相關的業務邏輯。我想添加一個標記,以便我的用戶知道他們是否可以從getter中檢索數據,或者我們是否仍在等待後端。如何通知我的用戶閱讀尚未完成?

這是如何正常完成的?寫入後將標誌設置爲繁忙,並在單獨的線程中在背景中進行讀取?該標誌將類似於PQisBusy

+0

定義一個事件,所以當資源可用時,給用戶一個回叫.... –

+0

這就是一種選擇,但現在我需要實現isBusy標誌。 – ruipacheco

+0

isBusy標誌是一種解決問題的方法,你需要做Pooling或long pooling這不是很好 –

回答

2

不知道您是否在尋找異步解決方案,如使用回調或輪詢方法。從問題看來你正在尋找一個輪詢方法,因爲你想要一個標誌,用戶可以檢查數據是否完全準備好。在這種情況下,只需定義一個變量和函數的類,.h文件中:

#include <atomic> 
#include <thread>  

class MySocket 
{ 
public: 
    ~MySocket(); 
    bool IsReady(); 
    void StartDataGather();  
private: 
    void GatherDataThread(); 
    static std::atomic<bool> _isReady; 
    std::thread _thread; 
} 

在您的.cpp文件:

#include "MySocket.h" 

static std::atomic<bool> MySocket::_isReady(false); // Default flag to false. 

MySocket::~MySocket() 
{ 
    // Make sure to kill the thread if this class is destroyed. 
    if (_thread.joinable()) 
     _thread.join(); 
} 

bool MySocket::IsReady() { return _isReady; } 

void MySocket::StartDataGather() 
{ 
    _isReady = false; // Reset flag. 

    // If your gather thread is running then stop it or wait for it 
    // to finish before starting it again. 
    if(_thread.joinable()) 
     _thread.join(); 

    // Start the background thread to gather data. 
    _thread = std::thread(GatherDataThread()); 
} 

void MySocket::GatherDataThread() 
{ 
    // This is your thread that gathers data. 
    // Once all of the data is gathered, do the following: 
    _isReady = true; 
} 

要使用此方法從您的客戶端類的外請執行下列操作:

MySocket mySock; 

mySock.StartDataGather(); 

while(!mySock.IsReady()) 
{ 
    // Do some other code here until data is ready. 
    // Once the MySocket::GatherDataThread() finishes it will 
    // set _isReady = true which will cause mySock.IsReady() to 
    // return true. 
} 

你現在有其他人可以檢查一個標誌,這是因爲std::atomic<>模板的線程安全的。以下使用C++ 11或更新版本-std=c++11

+0

爲什麼你讓_isReady是靜態的而不是實例變量? – ruipacheco

+0

如果有'MySocket'類的多個實例。我不知道你的代碼將如何使用,所以我不得不猜測幾件事情。如果可以有多個類的實例,並且'GatherDataThread'不需要共享資源,則可以刪除'static'。再次,這一切都取決於你想在你的代碼中做什麼。 – user2205930

+0

謝謝,這真是太棒了! – ruipacheco

0

如果用戶指的是庫的用戶,我會建議將異步方法的結果包裝在std::future或類似的線程同步機制中。您可以使用wait_for方法失敗並通知進程仍在進行,然後重試。

+0

你是指在std :: future中包裝asio :: async_read? – ruipacheco

+1

tbh我對boost asio不是很熟悉,但我認爲你的想法太低。你的庫的結果當然不是'async_read'的直接輸出嗎?在'async_read'回調條件滿足後,你可以提供'future'及其結果。 – yano