我有一個類包裝器boost::asio::thread_pool m_pool。在包裝器的解構式中,我加入了所有執行緒:
ThreadPool::~ThreadPool()
{
m_pool.join();
cout << "All threads in Thread pool were completed";
}
我也有佇列方法將新任務添加到執行緒池:
void ThreadPool::queue(std::function<void()> task, std::string label)
{
boost::asio::post(m_pool, task);
cout << "In Thread pool was enqueued task: " << label;
}
如果boost::asio::post被另一個執行緒呼叫,當 thread_pool 正在等待加入解構式中的所有執行緒時會發生什么?
是否定義了這種行為?會發生什么?任務會完成嗎?我想可能不會。但我不確定。
uj5u.com熱心網友回復:
是的,可以在加入待處理時發布新的處理程式。join將一直等待,直到執行背景關系耗盡作業。這可能是無限期的。
事實上,它通常是不確定的,例如在網路服務器的情況下。一旦服務器停止偵聽并且所有連接的會話都關閉,執行背景關系通常只會“退出”。
換句話說,join()是一個同步/集合操作,而不是一個stop().
顯示/如何作業的最簡單示例:
住在科利魯
#include <boost/asio.hpp>
#include <iomanip>
#include <iostream>
using boost::asio::thread_pool;
// convenience
using namespace std::chrono_literals;
static auto now = std::chrono::steady_clock::now;
static auto start = now();
static inline void trace(auto const&... msg) {
std::cout << std::setw(5) << (now() - start) / 1ms << "ms - ";
(std::cout << ... << msg) << std::endl;
}
void do_loop(int const i, thread_pool::executor_type ex) {
std::this_thread::sleep_for(1s);
trace("work ", i);
if (i < 10)
post(ex, std::bind(do_loop, i 1, ex));
}
int main() {
boost::asio::thread_pool io;
post(io, std::bind(do_loop, 0, io.get_executor()));
trace("Start join");
io.join();
trace("Complete join");
}
這列印例如
0ms - Start join
1001ms - work 0
2001ms - work 1
3001ms - work 2
4002ms - work 3
5002ms - work 4
6002ms - work 5
7002ms - work 6
8003ms - work 7
9003ms - work 8
10003ms - work 9
11004ms - work 10
11004ms - Complete join
警告
請注意,如果第一個異步作業是從另一個執行緒發布的,您可能需要額外的作業來防止池過早加入。
如果沒有任何同步,您將無法判斷事物執行的順序:是否post 發生在join.
在這種情況下,您可以使用executor_work_guard(參見)。make_work_guard
同樣的警告適用于混合場景,其中一些異步呼叫鏈可能會終止,但不相關的執行緒仍在發布沒有同步的任務。這些操作發生的順序是不確定的(作業系統/實作定義),它可能會延長池的壽命。
再次
- 確保作業以保證任務仍將執行。
- 保留一個單獨的標志(例如 an
std::atomic_bool),表明池不再接受作業
這是否記錄在案
是的:
此函式阻塞,直到池中的執行緒完成。如果在 join() 之前未呼叫 stop(),則 join() 呼叫將等到池中沒有更多未完成的作業。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/482813.html
上一篇:如何處理:如果boost::asio::post無休止地重復,當boost::asio::thread_pool解構式被觸發時?
下一篇:在無限回圈中獨立運行3個異步任務
