Boost Asio 中的執行緒和基本原理
說到Boost.Asio的執行緒時,我們經常在討論:
- io_service:io_service是執行緒安全的。幾個執行緒可以同時呼叫io_service::run()。大多數情況下你可能在一個單執行緒函式中呼叫io_service::run(),這個函式必須等待所有非同步操作完成之後才能繼續執行。然而,事實上你可以在多個執行緒中呼叫io_service::run()。這會阻塞所有呼叫io_service::run()的執行緒。只要當中任何一個執行緒呼叫了io_service::run(),所有的回撥都會同時被呼叫;這也就意味著,當你在一個執行緒中呼叫io_service::run()時,所有的回撥都被呼叫了。
- socket:socket類不是執行緒安全的。所以,你要避免在某個執行緒裡讀一個socket時,同時在另外一個執行緒裡面對其進行寫入操作。(通常來說這種操作都是不推薦的,更別說Boost.Asio)。
- utility:就utility來說,因為它不是執行緒安全的,所以通常也不提倡在多個執行緒裡面同時使用。裡面的方法經常只是在很短的時間裡面使用一下,然後就釋放了。
注意:如果沒有其他需要監控的操作,service.run()就會結束,就像下面的程式碼片段:
在上面的例子中,只要sock建立了一個連線,connect_handler就會被呼叫,然後接著service.run()就會完成執行。io_service service; tcp::socket sock(service); sock.async_connect( ep, connect_handler); service.run();
如果你想要service.run()接著執行,你需要分配更多的工作給它。
這裡有兩個方式來完成這個目標。一種方式是在connect_handler中啟動另外一個非同步操作來分配更多的工作。 另一種方式會模擬一些工作給它,用下面的程式碼片段:
typedef boost::shared_ptr work_ptr;
work_ptr dummy_work(new io_service::work(service));
上面的程式碼可以保證service.run()一直執行直到你呼叫useservice.stop()或者 dummy_work.reset(0);// 銷燬dummy_work.