チャックルアにおけるマルチスレッド入門
chuck-luaはアクターモードのスレッドモデルをサポートしています。cthread.newでスレッドを作成し、cthread.sendmailでスレッドにメッセージを送信することができます。
chuck-luaはskynetのようなフレームワークとは異なり、マルチスレッドのタスク/メッセージスケジューリングを提供しません。各スレッドは、他のスレッドから送られたメッセージをキャッシュするためのシンプルなスレッドメールボックスを維持します。
以下は、簡単なマルチスレッドサーバーの例です。
mtserver.lua
local chuck = require("chuck")
local engine = require("distri.engine")
local socket_helper = chuck.socket_helper
local Distri = require("distri.distri")
local cthread = chuck.cthread
local worker
function on_new_client(fd)
cthread.sendmail(worker,{fd})
end
local fd = socket_helper.socket(socket_helper.AF_INET,
socket_helper.SOCK_STREAM,
socket_helper.IPPROTO_TCP)
socket_helper.addr_reuse(fd,1)
local ip = "127.0.0.1"
local port = 8010
if 0 == socket_helper.listen(fd,ip,port) then
print("server start",ip,port)
local server = chuck.acceptor(fd)
server:Add2Engine(engine,on_new_client)
Distri.Signal(chuck.signal.SIGINT,Distri.Stop)
worker = cthread.new("distri/test/worker.lua")
Distri.Run()
end
worker.lua
local chuck = require("chuck")
local socket = require("distri.socket")
local engine = require("distri.engine")
local clone = chuck.packet.clone
local cthread = chuck.cthread
local Distri = require("distri.distri")
-- Set the mail processing function
cthread.process_mail(engine, function (sender,mail)
local fd = table.unpack(mail)
local s = socket.stream.New(fd)
if s:Ok(4096,socket.stream.decoder.rawpacket(),function (_,msg,errno)
if msg then
s:Send(clone(msg))
else
s:Close(errno)
s = nil
end
end) then
s:SetRecvTimeout(5000)
else
s:Close()
end
end)
Distri.Run()
この例はシンプルで、メインスレッドがリスナーを起動し、スレッドを作成し、接続を受けたらワーカスレッドにfdを送信します。
チャックルアスレッドの詳細を簡単に紹介します。
各スレッドは別々の仮想マシン上で動作するため、ある仮想マシンから他のスレッドにメッセージで直接オブジェクトを送信することはできません。現在sendmailは、メッセージとして渡されたluaテーブルをトランスポート可能なオブジェクトとしてシリアライズし、ターゲットスレッドで受信した後、このスレッドの仮想マシンのluaテーブルに再変換しています。
cthread.sendmailでターゲットスレッドにメッセージを送信する場合、バッファ行がターゲットのメールボックスに到達するとブロックされます。メールメッセージを処理することを期待するすべてのスレッドは、メッセージコールバック関数を設定するために cthread.process_mail を呼び出す必要があります。そうしないと、メッセージ送信スレッドが永久にブロックされるかもしれません。
スレッドはjoinモードを使って作成され、作成者はcthread.joinでスレッドが終了するのを待つことができます。
今回の記事は以上です。
関連
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン