boost.asio 有兩種支援多執行緒的方式
第一種方式比較簡單:在多執行緒的場景下,每個執行緒都持有乙個io_context,並且每個執行緒都呼叫各自的io_context的run()方法。
另一種支援多執行緒的方式:全域性只分配乙個io_context,並且讓這個io_context在多個執行緒之間共享,每個執行緒都呼叫全域性的io_service的run()方法。
每個執行緒乙個 i/o service
讓我們先分析第一種方案:在多執行緒的場景下,每個執行緒都持有乙個io_context (通常的做法是,讓執行緒數和 cpu 核心數保持一致:hardware_concurrency() )。那麼這種方案有什麼特點呢?
在多核的機器上,這種方案可以充分利用多個 cpu 核心。
某個 socket 描述符並不會在多個執行緒之間共享,所以不需要引入同步機制。
在 event handler 中不能執行阻塞的操作,否則將會阻塞掉io_service所在的執行緒。
直接上**:
#include
#include
#include
#include
class
threadpool
//開啟執行緒池,乙個執行緒乙個i/o 服務
for(
int i =
0; i < size ; i++))
; runthread.
detach()
;// 使用 round-robin 的方式返回乙個 io_service
boost::asio::io_context &
getiocontext()
void
stop()
}private
: std::vector<:shared_ptr>> m_iocontextlist;
std::vector<:shared_ptr>> m_worklist;
size_t my_pool_size;
size_t m_io_context_pos;
//依次分配io_context
};
乙個 i/o service 與多個執行緒
另一種方案則是先分配乙個全域性io_context,然後開啟多個執行緒,每個執行緒都呼叫這個io_context的run()方法。這樣,當某個非同步事件完成時,io_context就會將相應的 event handler 交給任意乙個執行緒去執行。
然而這種方案在實際使用中,需要注意一些問題:
在 event handler 中允許執行阻塞的操作 (例如資料庫查詢操作)。
執行緒數可以大於 cpu 核心數,譬如說,如果需要在 event handler 中執行阻塞的操作,為了提高程式的響應速度,這時就需要提高執行緒的數目。
由於多個執行緒同時執行事件迴圈(event loop),所以會導致乙個問題:即乙個 socket 描述符可能會在多個執行緒之間共享,容易出現競態條件 (race condition)。譬如說,如果某個 socket 的可讀事件很快發生了兩次,那麼就會出現兩個執行緒同時讀同乙個 socket 的問題 (可以使用strand解決這個問題)。
也是直接上**:
#include
#include
#include
#include
#include
#define boost_asio_no_deprecated
#include
#include
class
threadpool);
}}// the destructor joins all threads
~threadpool()
// add new work item to the pool.
template
<
class
f>
void
enqueue
(f f)
private
: boost::thread_group group_;
boost::asio::io_context io_context_;
boost::asio::io_context::strand strand_;
// prevent the run() method from return.
typedef boost::asio::io_context::executor_type executortype;
boost::asio::executor_work_guard work_guard_;};
// for output.
std::mutex g_io_mutex;
int main (
int argc,
char
* ar**)
std::this_thread::
sleep_for
(std::chrono::
seconds(1
));}
);}return0;
}
執行結果
參考:
執行緒池ExecutorService 的使用
executes the given command at some time in the future.the command may execute in a new thread,in a pooled thread,or in the calling thread,at the discr...
執行緒池與程序池
從python3.2開始,標準庫為我們提供了concurrent.futures模組,它提供了threadpoolexecutor和processpoolexecutor兩個類,實現了對threading和multiprocessing的更高階的抽象,是使用非同步實現,充分利用cpu提高程式執行效率...
執行緒池與程序池
為什麼要裝到容器中 可以避免頻繁的建立和銷毀 程序 執行緒 來的資源開銷 可以限制同時存在的執行緒數量 以保證伺服器不會應為資源不足而導致崩潰 幫我們管理了執行緒的生命週期 管理了任務的分配 from concurrent.futures import threadpoolexecutor,proc...