- 1 名前:デフォルトの名無しさん mailto:sage [2010/12/25(土) 22:46:56 ]
- 主にソケットに関しての質疑応答スレッドです。
Programming UNIX Socket FAQ (日本語訳) www.kt.rim.or.jp/~ksk/sock-faq/indexj.html Winsock Programmer's FAQ (日本語訳) www.kt.rim.or.jp/~ksk/wskfaq-ja/ 関連リンクは>>2-10辺り 足りなかったら適当に付け足してね 前スレ ネットワークプログラミング相談室 Port26 hibari.2ch.net/test/read.cgi/tech/1269343909/ 関連スレ ネットワークプログラミング雑談 hibari.2ch.net/test/read.cgi/tech/1235800707/ Java ネットワークプログラミング 【教えて!】 hibari.2ch.net/test/read.cgi/tech/1086238859/
- 892 名前:デフォルトの名無しさん mailto:sage [2012/04/14(土) 23:49:10.41 ]
- >>889
そこで、1threadが複数のsocketを処理するworker方式で>>883はどうやってるんだろう というのが元の質問だったんだが。 新しくaccept()されたソケットを各workerのどれかに振り分けるとした場合、 ・1つのworkerが担当するソケットが複数読み書き可能になった場合、他のスレッドが遊んでいても 直列的にしか処理できない ・そもそも割り振られたworkerがselect()で待ち受け中の場合、新しいソケットを待ち受けることができない という問題がありそうに思えるけど。
- 893 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 00:53:55.45 ]
- >>892
パイプで渡すから問題ない
- 894 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 00:54:46.29 ]
- >>892
割り振ったworkerが偏っちゃった場合は諦める
- 895 名前:デフォルトの名無しさん [2012/04/15(日) 00:55:26.36 ]
- レイテンシのことでしょ
- 896 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 07:06:24.33 ]
- >>894
なのにそれでもworkerスレッド内でselect()したいという理由がわからないんだが。 他になにかメリットがあるんだろうか? それとやはり、そのやり方だと全スレッドがselect()でブロックされたまま新しいソケットを 処理できなくなることがあるように思うんだが。
- 897 名前:デフォルトの名無しさん [2012/04/15(日) 07:35:59.32 ]
- コルーチンで実装したことある
コルーチンの切り替え判断をC++のストリームに内臓させちゃって 結構使いやすいんだ
- 898 名前:デフォルトの名無しさん [2012/04/15(日) 07:42:15.64 ]
- でもなんだっけ、linuxでファイルをそのまま送るやつ。lighttpdの売り
カーネル内でなんかやってメモリコピーが減りましたってやつ 思い出したsendfileだ
- 899 名前:デフォルトの名無しさん [2012/04/15(日) 07:48:03.60 ]
- みみっちいよな。メモリアクセスがオーバーヘッドになることなんて
俺なんてサーバー作ったとき書きやすさのためにバッファ何層も重ねたぞ chunk用のストリーム、・・・用のストリームって
- 900 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 09:41:08.09 ]
- sendfileが軽減したのは、
単なるメモリアクセスじゃなくて、 カーネル/ユーザ空間間のコピーだよ。
- 901 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 09:49:33.87 ]
- >>896
リスナーのソケットをSelect()に入れればAccept()拾えるんでは?
- 902 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 09:56:02.40 ]
- そもそも、select()を使う場合は
recv()〜何かの処理〜send() が 短時間で終わらないと破綻する。
- 903 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 10:03:01.10 ]
- どれかひとつのスレッドでリスナーを待ち受ける場合、他のworkerに
処理を渡せない場合があることは変わらない。 それとも、全部のスレッドで同じリスナーソケットをselect()する?
- 904 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 10:05:51.25 ]
- >>902
そこでノンブロッキングI/Oですよ。
- 905 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 10:11:33.93 ]
- >>904
複数ソケットでそれを行うとselect()の再発明になる。
- 906 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 10:22:27.31 ]
- >>905
select()のかわりにノンブロッキングI/Oを使えと言っているわけじゃないよ? select()でトリガを受けて、read/writeをノンブロッキングでやるのが最近の流行。
- 907 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 10:45:26.33 ]
- >>903
今更何をw
- 908 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 11:08:40.66 ]
- >>907
今更と言うか、結局、>>883のように各workerスレッドでselect()するという場合 どのスレッドでどのソケットを監視することになるのか、これだけ質問しても よくわからなかったんだ。 今更というくらい明らかなことだったらちょっと教えてくれないか?
- 909 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 11:29:24.83 ]
- >>906
select()でトリガ拾うとrecv()/send()はブロックされないのでは?
- 910 名前: ◆QZaw55cn4c mailto:sage [2012/04/15(日) 11:41:59.98 ]
- >>906
>最近の流行 最近じゃない。初心者本 www.amazon.co.jp/dp/4874085032/ ですら昔からだ。
- 911 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 11:47:43.93 ]
- ソケット廻りって結構古いもんを引きずってるからね。
- 912 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 12:05:55.34 ]
- >>909
待ってれば読めるだろうけど多少なりともブロックされることはあるらしい。
- 913 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 12:54:56.19 ]
- >>912
WSAEWOULDBLOCK をスルーすれば良いのんか。
- 914 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 13:36:07.17 ]
- >>910
入門本に書いてあることが流行だと言ってる?
- 915 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 13:51:27.59 ]
- >>908
1スレッド100本くらいで100スレッドくらい これならそんなに無理なく1万本管理できる
- 916 名前:デフォルトの名無しさん [2012/04/15(日) 13:53:58.20 ]
- 1万コネクションサポートするのに1万スレッド作ったら問題あるのだろうか?
OSにもよるだろうけど。。。
- 917 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 14:03:06.10 ]
- 32bitOSじゃ無理。64bitならもしかしたら大丈夫かも。
- 918 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 14:09:25.25 ]
- >>916
無理がある気がするな。 Apacheなんかどういう実装になってるのだろう?
- 919 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 14:20:28.63 ]
- >>915
いや、そういう問題じゃなくて。 その100本のスレッドのうちリスナーを監視するのが1本なのか全部なのか? もしリスナーをselect()しないスレッドがあるとした場合、そいつらがselect()で ブロックしてしまう問題をどうするのか?ってことなんだが。 もちろん、100本もスレッドを用意したのに状況によって1本しか走れない ということも考えられるし。
- 920 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 14:23:15.17 ]
- >>919
そのselect()とやらが何をブロックするのだ?
- 921 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 14:39:07.53 ]
- >>917,918
そうですね。当然でした。 調べてみると、例えばWindowsのCreateThreadで作れるのは 最大で1プロセス2028スレッドとありました。
- 922 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 14:45:56.01 ]
- 当然そのスレッドを、だが。
もしかして、timeout=0でブン回すという使い方なのかな?これ。
- 923 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 14:51:37.06 ]
- >>922
そのスレッドでアイドリング処理をしないのならブロックしても問題なかろう。 recv(),send(),accept()の処理以外で何をするのだ?
- 924 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 15:05:42.39 ]
- いや問題あるだろ。
1スレッドが100ソケット受け持ったとして、そこで複数のソケットが読み書き可能に なったとしても他のスレッドは何もできないんだから。
- 925 名前: ◆QZaw55cn4c mailto:sage [2012/04/15(日) 16:52:43.69 ]
- >>914
入門書であること力点をおいているのではなく、1990年代の書籍であることに力点をおいています。 1990年代にしめされている手法が「最近はやっている」とは考えにくいでしょう、普通。 関係ありませんが、この本、ネットワークバイトオーダーに問題はあるものの、 fj でも一定の評価がついていましたね。
- 926 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 18:04:19.36 ]
- いやー、昔から使えたということと流行は関係ないでしょ。
一昔前ならわざわざ面倒なノンブロッキングI/Oを使うよりも 上の人のようにスレッド+ブロッキングI/Oの方が人気があった ような気がする。さらに前だとfork()が主流だったよねぇ。
- 927 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 18:27:54.74 ]
- 1992年でfjってのも微妙な話だなw
- 928 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 18:33:40.53 ]
- C10Kみたいなことが言われて、selectやpollの性能向上が始まったのが、
1990年代後半からだよ。本格的には2000年代入ってから。 マルチスレッド+ブロックI/Oやforkによる実装も普通に行われていた。 非同期I/Oの優位性は80年代から言われていたけど、(X11のプロトコルがそうだし) 低レベルAPIとして登場したのはその後だね。
- 929 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 20:19:03.11 ]
- >>924
そうならないように分配すればいい その上でどうしてもそうなったらあきらめればよろしい
- 930 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 20:20:01.53 ]
- >>919
リスナーは1本で。 各ワーカーにはパイプで適当にソケットを送りつければ良い。
- 931 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 20:26:49.72 ]
- select使うのにlistener必要?
分配にポリシーを実装する必要なければ、複数のworkerが直接同時にselectすればいい。
- 932 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 20:34:20.91 ]
- >>931
だれも待ち受けしなかったらサーバにならなくね?
- 933 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 20:38:39.05 ]
- >>924
>>902
- 934 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 20:40:52.10 ]
- スレッド1万あるよりはマシ
- 935 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 20:46:01.12 ]
- >>928
Winsock FAQ www.kt.rim.or.jp/~ksk/wskfaq-ja/articles/io-strategies.html には 「経験則3: select()は避ける」 とあるけど これの元ネタの英文はかなり古いものなのかな。
- 936 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 20:47:38.09 ]
- WIndowsのselectは性能悪かったしね。たぶん今もそうだけど。
- 937 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 20:49:17.95 ]
- >>935
winならそれでいいんじゃね? unixlinuxには選択肢ないからな
- 938 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 20:50:29.14 ]
- >>930
なるほど、やりかたはわかった。ただ、わざわざそうすることのメリットがよくわからないな。 activeなソケットの偏りで効率が落ちる問題は残るし、特にプログラミングが簡単になるようにも 思えないし。 >>929 「そうならないように」って、無理だろそりゃ。どのソケットがactiveになるか事前に判断できる わけがないし。
- 939 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 20:51:19.09 ]
- >>936-937
スレッド嫌いなのでselect()で実装してやったけど なんの問題もなくサクサク動いたよw Winsock FAQってWindows 9x の時代のものじゃないのかな。
- 940 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 20:51:57.12 ]
- UNIXだとfdが多くなったらselectより、poll, epoll, /dev/poll, kqueueでしょ。
意外にもfd maskのbit演算がボトルネック!
- 941 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 20:53:25.28 ]
- >>938
C10Kのようなのだとスレッドのオーバーヘッドのが大きくなるから。 クライアント数が少ないのならスレッド実装のが楽
- 942 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 20:53:27.29 ]
- 95系のselectは性能どころか仕様にも問題あった。
詳しくは古いwinsockのドキュメント読んでくれ。
- 943 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 20:56:10.86 ]
- >>931
こっちは同時select()か。全スレッド同時に起きるけど、mutexを奪った1スレッドだけが 処理するという形になるわけかな。
- 944 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 21:00:20.71 ]
- >>943
それではスレッドにする意味がないような。
- 945 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 21:06:57.74 ]
- >>943
違うよ。 同時selectしているスレッドの一つだけが起きる。 どれが起きるかはスケジューラ任せ。 自分で選びたいならlistener/schedulerを作らないと仕方ない。 read等も同様の仕様。ほとんどのUNIXが。
- 946 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 21:50:18.53 ]
- >>945
そうだっけ?それだとレベルトリガじゃないような気もするが、正直1つのソケットを複数のスレッドで 同時にselect()するなんてやったことなかったから勘違いしていたかもしれん。 であれば、どのスレッドにどのソケットを監視させるかという割り振りも必要なかったといことか。
- 947 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 22:03:10.33 ]
- forkするマルチプロセスサーバが一つのsocketで全員acceptしてますよ。
じゃないと同じポート番号にならないし。 もちろん起きるのは一つのプロセスだけ。
- 948 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 22:53:17.93 ]
- >>947
Unix 系はいいんだが, WinSock ってそのへんどうなってんの? # 明日から Windows でネットワークプログラムするはめになってしまった orz
- 949 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 23:07:41.22 ]
- >>938
1万スレッド起こせるならその方が楽だけどね 普通は無理っしょ
- 950 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 23:09:42.76 ]
- >>938
事前に判断なんて無理なので、無理しないで淡々と振り分ける。 偏ったらあきらめるか、ソケットを余力がある他のスレッドに投げる。
- 951 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 23:11:13.18 ]
- Winsockの場合は、対象となるWinsockのバージョンのドキュメントをしっかり読んでください。
特にXPでは〜、Vistaでは〜、7では〜との注意書きは必ず読みましょう。 読まない人はプログラム書くなと言いたくなるくらい細かい違いが多い。
- 952 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 23:11:39.79 ]
- >>940
今はそこはどうでもいい
- 953 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 23:18:52.51 ]
- >>945
これ本当?どこかにリファレンスがあるなら教えて欲しいな。 例えば、ソケットがread readyになって起こされたスレッドがreadしなかった 場合とかどうなるの?
- 954 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 23:25:42.66 ]
- 別に何も起こりませんが?
- 955 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 23:35:15.90 ]
- >>954
「何もない」があるのよ! epollとかでエッジトリガとかだと何もしないがゆえに 問題になることはあるかも
- 956 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 23:44:57.62 ]
- >>954
理解できないです。 select/pollはレベルトリガですよね? 起こされたスレッドがreadしないでsleepしたら同じsocketでselectしている 別のスレッドが起きない?
- 957 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 23:45:51.97 ]
- >>956
それでいいだろ Aのスレッドでなにも怒らないからBのスレッドで怒り爆発だろ
|

|