簡體   English   中英

如何測試我的阻塞隊列實際阻塞

[英]How to test my blocking queue actually blocks

我有一個阻塞隊列(我真的很難改變它的實現),我想測試它實際阻塞。 特別是,如果隊列為空,則pop方法必須阻塞,並且只要執行push就解除阻塞。 請參閱以下用於測試的偽C ++ 11代碼:

BlockingQueue queue; // empty queue

thread pushThread([] 
{ 
    sleep(large_delay);
    queue.push(); 
});

queue.pop();

顯然它並不完美,因為可能會發生整個線程pushThread被執行並在調用pop之前終止,即使延遲很大,延遲越大,我就越需要等待測試結束。

如何正確確保在調用push之前執行pop ,並且直到push返回為止?

如果不向BlockingQueue添加一些額外的狀態和接口,我不相信這是可能的。

證明就是這樣的。 你想要等到pop阻止閱讀線程。 但是沒有辦法區分它和即將執行pop的線程。 無論你在調用pop之前或之后放置什么,這都是正確的。

如果你真的想以100%的可靠性來修復它,你需要在隊列中添加一些狀態,由隊列的互斥鎖保護,這意味着“有人正在等待”。 然后, pop調用必須在它原子釋放互斥鎖之前更新該狀態,並在內部條件變量上進入休眠狀態。 push線程可以獲取互斥鎖並等待“有人在等待”。 要避免繁忙循環,您需要再次使用條件變量。

所有這些機器幾乎和隊列本身一樣復雜,所以也許你也想測試它......這種多線程代碼就像“代碼覆蓋”這樣的概念 - 甚至可以說是單元測試本身 - - 分解一下。 存在太多可能的操作交錯。

在實踐中,我可能會采用你原來的睡眠方法。

template<class T>
struct async_queue {
  T pop() {
    auto l = lock();
    ++wait_count;
    cv.wait( l, [&]{ return !data.empty(); } );
    --wait_count;
    auto r = std::move(data.front());
    data.pop_front();
    return r;
  }
  void push(T in) {
    {
      auto l = lock();
      data.push_back( std::move(in) );
    }
    cv.notify_one();
  }
  void push_many(std::initializer_list<T> in) {
    {
      auto l = lock();
      for (auto&& x: in) 
        data.push_back( x );
    }
    cv.notify_all();
  }
  std::size_t readers_waiting() {
    return wait_count;
  }
  std::size_t data_waiting() const {
    auto l = lock();
    return data.size();
  }
private:
  std::queue<T> data;
  std::condition_variable cv;
  mutable std::mutex m;
  std::atomic<std::size_t> wait_count{0};
  auto lock() const { return std::unique_lock<std::mutex>(m); }

};

或者某些。

在推送線程中,忙等待readers_waiting直到它通過1。

此時你有鎖並且在cv.wait之前都在cv.wait之內。 push

理論上,一個無限慢的讀者線程可能已經進入cv.wait並且仍然在你調用push時評估第一個lambda,但是一個無限慢的讀者線程與一個被阻塞的線程沒有什么不同......

然而,這確實涉及慢線程啟動等。

使用readers_waitingdata_waiting進行調試data_waiting的任何操作通常都是代碼味道。

您可以使用std::condition_variable來完成此任務。 cppreference.com的幫助頁面實際上顯示了一個非常好的cosumer-producer示例,它應該是您正在尋找的: http ://en.cppreference.com/w/cpp/thread/condition_variable

編輯:實際上,德語版的cppreference.com有一個更好的例子:-) http://de.cppreference.com/w/cpp/thread/condition_variable

暫無
暫無

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

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