CPUのプロセスとスレッドについて勉強していてふと疑問に思ったことがあります。
どの言語にもおそらく待機させる処理があるかと思いますが
CPUコアを1つだけ積んだサーバー上で、ウェブアプリケーションをワーカー数3で起動していた場合、3人が同時にアクセスしてきて、sleep処理を実行していると4人目は誰かの待機処理及びfunc_Bが終わるまでfunc_Aも実行されない状態になってしまうのでしょうか?
func_A() sleep(3) func_B()
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答1件
0
ベストアンサー
sleep処理を実行していると4人目は誰かの待機処理及びfunc_Bが終わるまでfunc_Aも実行されない状態になってしまうのでしょうか?
ならないです。現代のOSはそんなに単純ではないので安心してください。
まず、sleep
を実行したときから、そのアプリケーションはOSに制御を委ねます。文字通りそのアプリケーションは眠った状態になります。OSは別のプロセスに制御を移します。sleep
で指定した時間が満了すると、OSはまたそのアプリケーションに制御を移し、そのアプリケーションの実行が再開されます。上記の説明はsleep
と言うメソッドの実行を契機として別のプロセスが動く例ですが、、実際はさらに、各プロセスに割り当てた細かい時間単位で制御が移り渡っていきます(時分割/タイムスライス)。スレッドが関係すればさらに細かくなります。
CPUがシングルコアではなく、マルチコア、メニイコアの場合は、良くWEBの記事ではコア1つに対して1スレッドなどと説明がありますが、そうとも限りません。割り当てられなければ1つのコアで複数のスレッドが時分割されて動きますし、反対に複数のコアでもスレッドが1つしか使われないようなケースもあります。
コメントを受けて追記しました:2019-10-27 09:02
※回答欄へのコメントより引用:
(ここでのワーカーはunicornなどでのワーカーです)
前提がそうであると、上記の私の回答は該当しませんね。この場合は質問者さんの疑問どおり、
「ワーカー数3で起動していた場合、3人が同時にアクセスしてきて、sleep処理を実行していると4人目は誰かの待機処理及びfunc_Bが終わるまでfunc_Aも実行されない状態」になります。
手間取りましたが、Ubuntu16上でRuby Sinatra + Unicorn + nginxを使って確認してみました。
unicornを起動した状態が、以下のようであるとします。ワーカープロセスは3881, 3883, 3886の3つです。
bash
1$ unicorn -c unicorn.conf -D 2 3$ ps -ax 4... 5 3879 pts/19 Sl+ 0:00 unicorn master -c unicorn.conf 6 3881 pts/19 Sl+ 0:00 unicorn worker[0] -c unicorn.conf 7 3883 pts/19 Sl+ 0:00 unicorn worker[1] -c unicorn.conf 8 3886 pts/19 Sl+ 0:00 unicorn worker[2] -c unicorn.conf
この状況で Sinatraで造ったWEBアプリを動作させます。http://<server>/test1
へのGETで、10秒sleep
するだけするものです。処理の前後でタイムスタンプを保存し、レスポンス中にプロセスIDと共にデータとして載せます。
$ cat config.ru require 'rubygems' require 'sinatra/base' class HelloApp < Sinatra::Base get '/test1' do now1 = Time.now sleep(10) now2 = Time.now ts = now1.strftime("%H:%M:%S") te = now2.strftime("%H:%M:%S") s = "PID=#{Process.pid}, s=#{ts}, e=#{te}" return s end end run HelloApp
この状態で、クライアント側からwget
コマンドで3つのリクエストを送ります。3つが受け付けられた後、更に1つのリクエストを送出します。すると、以下のような結果が得られました。
# 1つ目のリクエストでのレスポンス内容 PID=3881, s=08:13:33, e=08:13:43 # 2つ目のリクエストでのレスポンス内容 PID=3886, s=08:13:34, e=08:13:44 # 3つ目のリクエストでのレスポンス内容 PID=3883, s=08:13:36, e=08:13:46 # 4つ目のリクエスト PID=3881, s=08:13:43, e=08:13:53
4つ目のリクエストによるレスポンスが、接続はWEBサーバーであるnginxに受け付けられるものの、実際にUnicornのワーカープロセスの処理に制御に移るのは、1つ目のリクエストの処理が終わったPID=3881のプロセスによるものであることが分かります。
大量の同時リクエストがあったとしてもプロセス数の制限を設けることで堅牢性やメモリ占有率を担保しようとする(<たぶん)Unicornのような形態をとるWEBアプリでは、ワーカープロセスの終了まで長時間占有するような処理はご法度、と言うことですね。数に制限のあるスレッドプールなどにも言えそうです。なお、CPUコアの数が依然として関係ないのは前の回答と同様のはずです。~~なぜならば、Unicorn自体がプロセス数の制限を担っているからです。~~ご質問に提示されたコードと私のコードは、CPUコア数の多少に影響されるものではありません。
技術的な疑問から出た今回のご質問だったと思いますが、1プロセスで長時間占有するようなWEBアプリの処理は考えたことも無かったので、私も勉強になりました。
参考に、確認に使ったunicorn.confの内容とnginxの設定内容を記しておきます。
unicorn.confの内容:
worker_processes 3 listen '/tmp/unicorn.sock' stderr_path File.expand_path('unicorn.log', File.dirname(__FILE__)) stdout_path File.expand_path('unicorn.log', File.dirname(__FILE__)) preload_app true
nginxのconfの内容:(/etc/nginx/sites-available/default)
upstream unicornapps { server unix:tmp/unicorn.sock; } server { listen 80 default_server; listen [::]:80 default_server; root /var/www/html; index index.html index.htm index.nginx-debian.html; server_name _; location / { proxy_pass http://unicornapps; } }
投稿2019/10/26 11:19
編集2019/10/27 00:29総合スコア9256
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/10/26 12:00
2019/10/26 21:38
2019/10/27 00:12
2019/11/04 10:19