Bost asio庫與執行緒池的使用

2021-10-05 20:55:17 字數 2669 閱讀 8769

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...