1. 程式人生 > >談談Boost網路程式設計(3)—— 一些坑

談談Boost網路程式設計(3)—— 一些坑

       很多時候,我們以為採用了一種新技術(尤其是成熟的技術),過程應該是一馬平川的。然而實際上,採用新技術的過程卻是掉入了各種坑裡。究其原因,或者是使用方式有問題,或者是效率的白白浪費。這一章,我想講講,我在使用Boost Asio程序網路程式設計時,所遇到的各種坑。

       其一、CPU佔用100%問題。

       在沒有采用非同步程式設計之前,程式佔用100%基本是不敢想象的事情,因為一旦程式佔用100%的CPU,那必然是程式碼中出現了死迴圈的BUG。但是採用了Boost Asio後,我發現新系統很容易就跑滿了CPU。Why?

       1)服務端接收任務過快。快一直是我們系統所追求的,為此我們特別進行了優化,支援一次接收一組任務(100-300之間)。然而我們處理任務時,client一次最多隻能夠處理10條任務,這就是典型的生產者-消費者問題。生產者能力大於消費者,而且消費者在消化時(HTTP傳送任務時),對方反饋是同步反饋的,這就造成了CPU的持續增加。再則,任務完畢被髮送到report_runner時,反饋任務是一條一條反饋,這又是生產能力大於了消費能力。

       針對此問題,我們做了一些限制和優化:stream_server增加限速功能,report_client可以合併反饋。

      2)bind意味著拷貝,儘量在bind時傳遞指標而不是例項。

      其二、shared_ptr和多型。

      如果我有一個基類的shared_ptr,我可以用它來指向具體的子類嗎?答案是需要將子類的shared_ptr賦值於這個指標,否則無法實現多型。

      其三、子程序問題。

       由於我們的客戶端只運行於linux,所以這裡只描述在基於boost asio的多執行緒程式中如何再做到多程序。注意:這裡有一個前提,子程序中只調用shell或可執行,並不用到父程序中的asio例項。

       為什麼要單獨講子程序問題呢?因為Boost的asio並不是fork安全的,而且其Doc中特別指出了在子程序中需要呼叫notify_event來通知asio以使fork安全。這至少造成了我的疑惑:如果我不需要在子程序中使用Asio,我還需要notify嗎?答案是不需要。正如我們系統所遇到的,只需要呼叫linux的exec*即可。

       進一步,由於我們並不需要拷貝父程序,所以用vfork取代了fork。