背景
プロセス
について説明されているサイト(preforkサーバーを作ってみよう)を読んでいました。
その中でpreforkサーバ
が触れられており、以下のコードが示されていました。
ruby
1# -*- coding: utf-8 -*- 2require "socket" 3 4number_of_workers = 3 5listening_socket = TCPServer.open(12345) 6 7number_of_workers.times do 8 pid = fork 9 10 if pid 11 # 親`プロセス`は次々に fork で子`プロセス`を作る 12 next 13 else 14 # 子`プロセス` 15 16 # クライアント受け入れ無限地獄 17 loop do 18 puts "`accept`ing..." 19 # 子`プロセス`は全部ここでブロックする。 20 socket = listening_socket.`accept` 21 puts "`accept`ed a client!" 22 23 # クライアントの入力受け取り無限地獄 24 loop do 25 line = socket.gets 26 line.gsub!(/[\r\n]/,"") 27 28 if line == "exit" 29 socket.close 30 puts "closed a connection!" 31 break 32 end 33 34 puts line 35 end 36 end 37 end 38end 39 40# 子`プロセス`は無限ループしてるからここには届かない 41# 親`プロセス`では子`プロセス`の終了を待ち続ける 42Process.waitall
このサーバーは以下の流れで動いているかと思います。
流れ
リスニングソケット
を作られる- forkして子
プロセス
を三つつくる - 3つ全ての子
プロセス
のリスニングソケット
がaccept
(接続待ち状態)に以降する - 子
プロセス
達はリスニングソケット
のオープンファイル記述
が共有されている事から、外部Aから接続が来た場合、3つのうち1つのプロセス
だけ接続される
(一番処理が先に進んだどれかのリスニングソケット
に接続されると、オープンファイル記述
に外部Aと接続してるよ!と書かれるから、その他の子プロセス
のリスニングソケット
は「なんだもう外部Aとは接続されてるのか」となり、特段なにもしない)
5. 外部Bから接続された時は、余っている子プロセス
のリスニングソケット
が対応して同じような事をする
これを読んでいて疑問がいくつかわきました。
疑問
その1
流れ3にて一番処理が速かったプロセス
のリスニングソケット
がaccept
(接続待ち状態)に以降した時に、オープンファイル記述
には「今俺accept
(接続待ち状態)しているよ!」という旨の文言が書かれてしまい、他のプロセス
達はaccept
(接続待ち状態)していないにも関わらず自分の事をaccept
(接続待ち状態)していると勘違いしないのか?
(accept
(接続待ち状態)処理をしようとすると既にaccept
(接続待ち状態)していますエラーが出たりしないのか?)
その2
最初に外部Aと接続した子プロセス
のリスニングソケット
は、接続済みソケットを生成したあと再び待ち状態になるかと思うけど、この子プロセス
のリスニングソケット
が再び接続を受け取ってしまう事はないのか?
もしリスニングソケット
が一度接続済みソケットを生成したら休止状態に入るとするならば、ファイルオープン記述を共有している他の子プロセス
のリスニングソケット
もみんな休止状態に入ってしまい結局一つしか接続できない事になってしまう為、rubyのソケットも一般的なTCPソケットのaccept
挙動と同じく、接続済みソケットを生成したあと再びaccept
(接続町状態)になると考えています。
所感
オープンファイル記述
で共有される内容がよくわからない・・・
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/10/13 03:04
2019/10/13 03:52
2019/10/13 04:02