歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> 采用多線程方式的Ruby DRB server的實現

采用多線程方式的Ruby DRB server的實現

日期:2017/3/1 10:38:22   编辑:Linux編程

DRB是ruby的遠程進程調用(remote process calling)機制,類似於java的RMI。近期在一個項目中采用了DRB實現server與client之間的通信,其中對於server有以下要求:

a) 並發處理多個client的請求,對於每個client用一個線程來處理;

b) client發出請求後可以立即返回,不需要阻塞在那裡等待server處理。

我對server的設計如下:

給client調用的接口函數放在server主線程中。主線程還維護了一個消息隊列,每收到一個client的服務請求,就把這個請求添加到消息隊列中。

對服務請求的具體處理由processor對象來實現。對於每個請求創建一個processor對象,並創建一個新的子線程,在子線程中執行這個processor對象的服務請求處理函數。

整個server的代碼比較短,不過因為我不熟悉ruby線程和drb,寫的過程中踩到幾個陷阱。現在把實現時需要注意的幾點總結如下:

1) 為了實現上述b),server主線程中給client調用的接口函數不完成具體的服務請求處理,只是創建新的processor對象,並且把client的請求放到消息隊列裡面。

2) 在主線程裡,當DRB服務啟動之後,執行server.run。這個server.run是一個死循環(消息循環)。每次從消息隊列裡面取出排在頭上的消息,創建子線程,把對應的processor對象放到子線程裡面,對消息進行處理。處理完了這個子線程就exit。

3) ruby啟動子線程有thread.join和thread.run兩種方式。其中thread.join會讓主線程阻塞,等待子線程退出之後才返回。我一開始用的thread.join,結果主線程掛起了,只有等第一個子線程處理完退出之後才會讀第二條消息,創建第二個子線程,所以實際上沒有實現對多個服務請求的並發處理。改成thread.run,主線程不會阻塞,就可以並發了。但是thread.run是當主線程退出時,所有子線程都會被強制結束。所以把主線程的server.run做成死循環,保證每個子線程都可以正常執行完再退出。

還有兩個需要優化的地方,作為下一步的工作:

1) 現在這樣頻繁的創新子線程比較耗資源,做成線程池的方式會好一些。

2) 現在只有一個消息隊列,是按FIFO處理的。還可以做得更靈活一些,比如支持多個優先級,按照一定的策略對於消息隊列進行調度,等等。

Copyright © Linux教程網 All Rights Reserved