マルチスレッドプログ ..
[2ch|▼Menu]
2:デフォルトの名無しさん
06/09/10 00:19:06
関連スレ

【マルチコア】並列化について語る【使いこなせ】
スレリンク(tech板)

pthread地獄 (UNIX板)
スレリンク(unix板)


関連しやすいので一応

ネットワークプログラミング相談室 Port17
スレリンク(tech板)l50

書籍とかはもういいでしょ

3:デフォルトの名無しさん
06/09/10 00:33:25


4:デフォルトの名無しさん
06/09/10 15:04:22
4ね

5:デフォルトの名無しさん
06/09/10 16:03:40
5免蒙る

6:デフォルトの名無しさん
06/09/11 07:05:53
pthreadで排他制御やりたいときはmutexしか選択肢は無いんでしょうか?

7:デフォルトの名無しさん
06/09/11 22:08:46
condition,semaphore

8:デフォルトの名無しさん
06/09/18 01:43:12
本とかはもういいとして、このソースのthread部分は秀逸だっていうの
教えてください

9:デフォルトの名無しさん
06/09/18 09:25:39
apache2(ウソ)

10:デフォルトの名無しさん
06/09/18 10:05:22
Windowsのスレッドのタイムスライスは、上限が20msと聞きますが
これを制限する方法はありませんか?
できれば、3〜5msに押さえたいのです。

11:デフォルトの名無しさん
06/09/18 16:44:32
NT4.0を使って、boot.iniで設定。
Windows Embeddedならどっかで設定できたような。
Vistaは割り込み頻度を変えるAPIがあったかもしれず。

12:デフォルトの名無しさん
06/09/18 20:34:42
Fiber使ってで明示的にスイッチするとか

13:デフォルトの名無しさん
06/09/18 21:47:30
>>11
ありがとうございます。
こちらでも調べてみたのですが
win9x/2000でのスレッド単位での設定は出来ないようですね。
スレッドスケジューラを少しいじれば、可変に出来る気がするのですが
あんまり需要無いんですかね。

>>12
ファイバを使ってsuspendを置くか、スレッド関数にSleepを置くか、
結局のところ、これしかしかないのですね……
どちらか採用して、今のプロジェクトを進めようと思います。

14:デフォルトの名無しさん
06/09/19 10:53:29
>>10

たしか、どっかにVistaのタイムスライスに関する blogがあったな。
××をすると、スイッチが最小時間になると適らないとか。

どっかの、MVPの blogだったと思う。


15:デフォルトの名無しさん
06/09/19 21:01:54
>>14
Vista+タイムスライスでググってみた。
URLリンク(d.hatena.ne.jp)
ついでに
URLリンク(www.itmedia.co.jp)

16:デフォルトの名無しさん
06/09/21 21:28:56
InsideWindowsには
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\PriorityControl]
のWin32PrioritySeparation
をいじればいいと書いてある


17:デフォルトの名無しさん
06/09/21 22:55:26
ってスレッド単位で制御したいのか

そりゃ無理っぽいな

18:デフォルトの名無しさん
06/10/07 12:26:02


19:デフォルトの名無しさん
06/10/10 14:57:19
>>14
kernel修正すればいいじゃん。
2.6.xなら安定してるしNPTLを使えばOKだし

20:デフォルトの名無しさん
06/10/10 21:20:44
?

21:デフォルトの名無しさん
06/10/26 16:02:30
マルチプロセスのプログラムはWindowsで作れますか?

22:デフォルトの名無しさん
06/10/26 17:21:43
>>21が意図してるものとは異なるかもしれんが、マルチプロセスのアプリケーションなら作れる。
しかし>>21の質問の仕方からして、>>21には到底無理だろう。

23:デフォルトの名無しさん
06/11/04 17:13:38
質問させてください。
Win32APIのSuspendThread()に自スレッドを指定して、
自分自身を眠らせるということは可能でしょうか?

24:デフォルトの名無しさん
06/11/04 18:06:36
試せばいいじゃん

25:デフォルトの名無しさん
06/11/04 18:47:40
どうやって起こすの?
イベントオブジェクト作ってWaitForしたほうがマシだと思うが・・・

26:デフォルトの名無しさん
06/11/04 19:11:44
>>24
すいません、「可能」は「アリ」に置き換えてくださいorz
一応動くんですが、何かマズイんじゃないかなぁと思いまして。

>>25
仰るとおり実用的ではないですが、ちょっと気になったもので…

27:デフォルトの名無しさん
06/11/06 15:24:05
>>23
他スレッドからResumeThreadしようとしたとき、Resumeしても SuspendThread の直前だったため
Resume後即 Suspend してしまうケースがある。 → 解決するためには「スレッドのステート(idle,busyなど)」を設けて、
排他的に操作する必要あり。適切なイベントオブジェクトを使って待つ方が良い。

それでもまぁ他のスレッドを Suspend するのに比べればはるかに罪は少ない。

28:デフォルトの名無しさん
06/11/07 09:09:31
408 :名無しさん@お腹いっぱい。:2006/11/05(日) 18:14:14
Kentsfield(1P4C) vs Woodcrest(2P4C)
URLリンク(www.hardwarezone.com)
Opteronサーバー死んだな…
Clovertown 1.60GHz $455*2 >>> Opteron 2220 SE $786*2
Clovertown 2.33GHz $851*2 >>> Opteron 8220 SE $2149*4

29:デフォルトの名無しさん
06/11/09 22:08:24
967 名前:923[sage] 投稿日:2006/09/09(土) 17:29:41
>>959
>intrinsicはスルーか。
済みません、仰りたいことの意味が良く分りませんでした。
このプログラムの要点は、

volatile long a = 0x00001111;
void thread1(){
 while(1)a=0x00001111;
}
void thread2(){
 while(1)a=0x22220000;
}
int main(){
_beginthread(thread1);
_beginthread(thread2);
 while(1)if(a != 0x00001111 && a != 0x22220000)エラー;

return 0;
}

です。組み込み命令云々の余地があるのでしょうか?

main, thread1, thread2が開始される。
〜〜〜時間が十分経過〜〜〜
thread2が動き出す。a=0x22220000が実行される。
mainが動き出す。a!=0x00001111の評価をする。真であった。
thread1が動き出す。a=0x00001111が実行される。
mainが動き出す。a!=22220000の評価をする。真であった。
mainが動き出す。エラー処理を行う・・・???。

30:デフォルトの名無しさん
06/11/10 02:13:19
複数のスレッドを起動する場合、
システムに異常が発生しても全てのスレッドを
必ずきちんと終了させたい場合、各スレッドで try catch
入れるんでしょうか?
それとも別に良い常套手段があるんでしょうか?


31:デフォルトの名無しさん
06/11/10 06:01:09
システムに異常が発生した事を検知する関数が真を返したらすべてのスレッドが自主的に終了するようにしたらいいんちゃうん?

32:デフォルトの名無しさん
06/11/10 08:53:37
ええんちゃう? 最高ちゃう?

33:デフォルトの名無しさん
06/11/10 09:56:27
volatile最強伝説復活wwwwwwwwwwwwwww

34:デフォルトの名無しさん
06/11/10 19:04:31
このスレも自主的に終了するようにしたらいいんちゃうん?

35:デフォルトの名無しさん
06/11/10 20:51:25
ええんちゃう? 最高ちゃう?

36:デフォルトの名無しさん
06/11/10 23:12:02
>>29

while(1)if(a != 0x00001111 && a != 0x22220000)エラー;
を分解して
while ( true )
{
if ( a != 0x00001111 ) // a is 0x22220000
{
if ( a != 0x22220000 ) // a is 0x00001111
{
throw std::runtime_error("死んでしまえ");
}
}
}


37:デフォルトの名無しさん
06/11/17 16:54:00
>>36
こうすりゃいいんじゃね?

while(1){
int _a = a;
if(_a != 0x00001111 && _a != 0x22220000)エラー;
}

要は00001111か22220000以外が見つかればエラーにしたいんだから。
>>29指摘のコンテキストスイッチによる嘘エラー検出は回避できる。


38:デフォルトの名無しさん
06/11/19 14:18:42
初心者です。
スレッドの状態(実行中・サスペンド中など)を知るAPIってありますか?

State = ResumeThread( th_handle ) 又は
State = SuspendThread( th_handle )
として サスペンドカウントを見て状態を更新させています。
状態を監視する別スレッドがこのStateを見て、レジューム・サスペンドの実行をおこなっているのですが、

どーやら、状態を監視するスレッドが見ているStateと実際の状態が異なるらしく、
レジューム中のスレッドにResumeThread を実行したり、サスペンド中のスレッドにSuspendThread を実行しちゃったりしています。

なにかアドバイスもらえませんか?
おねがいします。

OS : Window XP Home
言語: C++
環境: VC++6.0

39:デフォルトの名無しさん
06/11/19 14:24:04
resume/suspendよりも、event objectやwindow messageを使って
眠らせることをオススメするよ。

40:38
06/11/19 14:35:34
>>39

アドバイス、ありがとうございます。
イベント使って、再設計してみます。

それと、色々さがしたんすけど、やっぱりスレッド状態を知るAPIとかは
ないんすかね?





41:デフォルトの名無しさん
06/11/19 14:39:09
知ったところでどうしょうもない、とだけ言っておこう。
だからないのよ。

42:38
06/11/19 14:45:36
>>41
了解です。ありがとうございます。

助かります〜

43:デフォルトの名無しさん
06/11/19 17:51:29
>>40
状態を調べたところでその次のステップで状態が変わってる可能性もあるわけで、
結局、排他やロックなどが必要になるわけです。
だったらはじめから>>39の方法の方が妥当なのです。

44:38
06/11/19 23:36:56
38です。
イベント使って再設計したとこ、なんとか思い通りに動いてくれました。
みなさん、どうもありがとう。
いい勉強になりました〜

45:デフォルトの名無しさん
06/11/20 16:10:26
linux上のC言語での質問です。

pthread_create を使ってスレッドを生成すると、そのスレッドが完了しても
1個スレッドが残るんですが、これって開放出来ないんですか?

デバッガで調べると「pthread_managear」というスレッドのようなのですが。


46:デフォルトの名無しさん
06/11/20 20:40:45
>>45
スレッドマネージャもためらいきずばかりなんだよね
自殺はよくない

47:デフォルトの名無しさん
06/11/21 01:19:01
どのlinux?
それなくなったとか聞いたんだが

48:デフォルトの名無しさん
06/11/21 09:28:07
>47
Red Hat Linux 7.3 です。

49:デフォルトの名無しさん
06/11/21 19:20:58
pthread_joinしてないとかそういう話じゃないの?

50:デフォルトの名無しさん
06/11/22 13:33:05
>49
joinはしてます。
あと 、pthread_detach も試して見ましたが変わらずでした。

51:デフォルトの名無しさん
06/11/23 14:14:40
windows c言語です。
_beginthreadexでスレッドを数千つくろうとしてるのですが、
スレッド数400ぐらいこえたところで、_beginthreadが0を返しだすので仕方なくsleepいりのbusyloop
で待って_beginthreadしつづけています。
スレッド数をタスクマネージャでながめると400になり、だんだんへって10桁程度になってから
また400に跳ね上がるのくりかえしをして、正常に終了します。が遅いです。
だんだん減っているときにはすぐに次の_beginthreadが成功してくれて、
なぜ、400のままずっといき、最後がだんだん減っておわらないのかわからないです。
あと、なぜ400で限界になるのでしょうか?
ちなみにスタックサイズをでかくするとスレッド数の限界はもっと減ります。
メモリがどんどんくわれていってスレッドももっとたくさんできて欲しいのですが・・・
スレッドの内容はメモリを動的確保しhtmlをネットから拾ってきて読むものです。

これだけでわかる人 ヒントください。

52:デフォルトの名無しさん
06/11/23 14:19:52
>>51
URLリンク(www.biccamera.com)

53:デフォルトの名無しさん
06/11/23 15:12:17
>>52
え それはないと思う。
プロセスの使用メモリ35MBぐらいなんです。
全部で1Gつんでるのに。

54:デフォルトの名無しさん
06/11/23 15:25:10
スタックメモリサイズの制限でしょ

55:デフォルトの名無しさん
06/11/23 16:03:20
> スレッドの内容はメモリを動的確保しhtmlをネットから拾ってきて読むものです。

ジョブキューイングとかワーカスレッドとか知らんかね?

56:デフォルトの名無しさん
06/11/23 17:00:57
1プロセスにスレッド400個ってのは設計上どうなんだろ…。
タスクマネージャ見ても最高でSystemの78個程度だ。


57:デフォルトの名無しさん
06/11/23 21:32:18
>>56
同意。

スレッドの生成と、管理にはそれなりのコストがかかるから、
むやみに増やしてもかえって遅くなる。

せいぜい数個から10数個くらいにとどめておくべきと思う。


58:デフォルトの名無しさん
06/11/23 22:29:39
数千スレッド使いたいってあほか。


59:デフォルトの名無しさん
06/11/23 23:13:58
PCの玄海に挑戦したかっただけだろうよきっと

60:デフォルトの名無しさん
06/11/24 01:00:08
どうもスレッドからみでは、本当に同時平行に処理したいことと、
そうでないことの区別ができてないことが多いようだ。


61:デフォルトの名無しさん
06/11/24 01:07:32
この場合は
・ネットへのリクエスト
・得られた情報の分析
が並行処理対象になると思うんだが、
前者と後者ではやりかたがぜんぜん違うよなあ

62:デフォルトの名無しさん
06/11/24 01:45:14
あまりのスケールのでかさに、別件でスレッドを使おうか迷っているのが
バカらしくなってきた

63:デフォルトの名無しさん
06/11/24 02:08:29
うちだと_beginthread()しまくるだけの奴で
スレッド2000個ちょっとまで作れるな

64:デフォルトの名無しさん
06/11/24 14:14:52
ふと>51の質問みて思ったんですが、スレッドを分ける(並列にする)
と処理速度って上がるんでしょうか。

処理の内容によるでしょうけど、単純にCPU性能に依存するような
処理で、並列に処理可能な場合とか。


まあ普通そういう目的でマルチスレッドを利用したりするわけじゃないですが。

65:デフォルトの名無しさん
06/11/24 14:15:53
ふと>51の質問みて思ったんですが、スレッドを分ける(並列にする)
と処理速度って上がるんでしょうか。

処理の内容によるでしょうけど、単純にCPU性能に依存するような
処理で、直列に処理してたけど並列に処理可能な場合とか。


まあ普通そういう目的でマルチスレッドを利用したりするわけじゃないですが。

66:デフォルトの名無しさん
06/11/24 14:16:56
連書きスマソ;

67:デフォルトの名無しさん
06/11/24 15:08:49
>>64
動作中スレッド数よりもCPUコア数が多いなら、スレッドを並列化することで高速化する。
仮に1Core1CPUで単純に並列化した場合、全く高速化しないかオーバーヘッドの分遅くなる。
まぁ、CPUコア数の数倍以上のスレッドを起こすと資源の競合が発生するから速くなる筈がない罠。

68:デフォルトの名無しさん
06/11/24 16:02:59
>>67
CPUに限らず、資源が競合する処理なら、確かにそうなるな。

逆に言えば資源を競合しないI/Oウェイトなどが多い処理なら、
CPU数より極端に多いスレッド数でも処理は早くなるといえる。

たとえば今回のようなhtmlファイルのダウンロードの場合、
相手方のサーバーのレスポンス待ちが発生するので、複数のスレッドで別々の
htmlファイルを同時に取得しにいったほうがいい。

ただ、やりすぎると今度はスレッド切り替えとか、メモリスワップとか、回線速度の限界とかで
オーバーヘッドが大きくなるので遅くなる。


69:デフォルトの名無しさん
06/11/24 16:05:55
tcpip.sysの同時接続制限とか関係ないのかな?

70:デフォルトの名無しさん
06/11/24 18:03:54
>67 68
サンクス!
実はウチの作ってるアプリで性能を指摘されてるトコがあって、
並列化ってどうなんだろうと思ったんで、参考になりました。

とりあえずCPU依存の処理は効果薄って事ですね。

71:デフォルトの名無しさん
06/11/24 19:12:42
>>70
並列化を考える前に、やることは色々あると思うよ。
CPUに、P4以上の制限つけていいならiccでコンパイルしてみるとか。
iccがあれば、並列化も簡単に試せるしね。
まぁ、詳細はスレ違いになるんで省略するけど。

72:デフォルトの名無しさん
06/11/25 01:58:51
CPU依存の処理で高速化を考えるなら、並列化ではなくアルゴリズムの最適化を考えたほうがいい。

スパコンでもない限り、今のパソコンはせいぜい4コア。
並列処理させても、4倍未満にしかならない。

だけどうまくアルゴリズムを工夫すれば、数倍から数百倍の速度が稼げる可能性がある。


73:デフォルトの名無しさん
06/11/25 02:07:56
DELLの6万円パソコン買ったほうがよくね?
10台でも60万。さてアナタの2人月より安い?高い?

74:デフォルトの名無しさん
06/11/25 02:08:38
無限に並列化可能な処理と仮定するなら、クラスタリングもありかと。
所謂グリッドコンピューティング。

75:デフォルトの名無しさん
06/11/25 02:12:36
あと2倍になればいいだけなのにチューニングだとかほざいて
無駄にコードを複雑にしようとしていたボケがいたので
サーバを3倍に増やして終わりにしました。

76:デフォルトの名無しさん
06/11/25 02:53:01
ま、そこら辺は完全にケースバイケースだよね。お仕事でやってるならコスト次第。
このスレ的には並列度を上げる方向に収束すると美しいんだけど。

77:デフォルトの名無しさん
06/11/25 03:05:17
そんな勝手に方向を決められても。

78:デフォルトの名無しさん
06/11/25 12:57:34
>>71
>iccがあれば、並列化も簡単に試せるしね。
体感で速くなったためしがない。

いったいどういう場合に効果があるのか…。

人間が見ればすぐ分かるが、コンパイラの並列可能判定って
どの程度のものなんだろう。

79:デフォルトの名無しさん
06/11/25 12:58:54
↑もちろん手動で並列化したら高速化できる状況での話ね。

80:デフォルトの名無しさん
06/11/25 13:11:18
>>78
勿論、最低限-parallelは指定しているとして、単純なループなら並列化してくれる可能性はあるよ。
尤も、OpenMPを手軽に試せるという積もりで書いたんだけど。

81:デフォルトの名無しさん
06/11/30 20:10:54
Sunコンパイラ最強伝説

82:デフォルトの名無しさん
06/12/02 20:35:28
最近、コンパイラの最適化性能比較ってあんま情報ないな。


83:デフォルトの名無しさん
06/12/03 21:51:02
すいません、マルチスレッドですか?

84:デフォルトの名無しさん
06/12/03 22:42:46
はい、マルチスレッドです。

85:デフォルトの名無しさん
06/12/03 23:28:53
あなたを、マルチスレッドです。

86:デフォルトの名無しさん
06/12/06 23:09:42
今日は徹夜でpthreadを勉強します。

87:デフォルトの名無しさん
06/12/07 01:09:39
こんやは徹夜で、マルチスレッドです。


88:デフォルトの名無しさん
06/12/07 11:08:50
それはいいマルチスレッドですね。

89:デフォルトの名無しさん
06/12/07 22:25:54
俺はみんながマルチスレッドしたあとでいいよ

90:デフォルトの名無しさん
06/12/07 22:29:26
みんないっしょでこそマルチスレッドです

91:デフォルトの名無しさん
06/12/07 23:01:07
俺ちょっと疲れたからみんな先にいってくれ

92:デフォルトの名無しさん
06/12/08 03:40:09
急激にスレの質が落ちて参りました

93:デフォルトの名無しさん
06/12/08 14:50:27
みんなでマルチコスレッドしねぇ?

94:デフォルトの名無しさん
06/12/08 21:05:24
JavaScriptの分際でマルチスレッドしてやがる事に最近気付いた。
仕組みどうなってんのよ?

95:デフォルトの名無しさん
06/12/08 21:57:49
Javascriptなら中身見れるでしょーが

96:デフォルトの名無しさん
06/12/08 22:03:46
ソースの問題じゃなくてCPUがどう処理をこなしているか知りたいんだよな

97:デフォルトの名無しさん
06/12/09 00:36:36
並行動作はせんと思うが

98:デフォルトの名無しさん
06/12/09 00:59:15
CPU?

99:デフォルトの名無しさん
06/12/09 01:01:50
onBlurとonClickで並列処理するよ。

100:デフォルトの名無しさん
06/12/09 01:02:26
だめだこりゃ

101:デフォルトの名無しさん
06/12/09 01:14:01
<script>
function Test(){
while(1){}
}
</script>

...
<span onclick="Test()">Hello World!</span>


でブラウザ死ぬけど?

102:デフォルトの名無しさん
06/12/09 01:18:19


103:デフォルトの名無しさん
06/12/09 01:28:07
どのブラウザで?
つかブラウザネタをここでやるのか・・・ヤだなあ

104:デフォルトの名無しさん
06/12/09 04:50:27
ここはやっぱり伝家の宝刀 volatileネタを持ち出して本来のスレの荒れ方に戻そうよ。

105:デフォルトの名無しさん
06/12/11 10:38:50
Intel C++ Compiler for LinuxでOpenMPを使った並列化をやっているのですが、Intel Thread ProfilerにはLinux版が存在しないので、
暗黙的/明示的なバリア, ループの分割, critical構文等のオーバーヘッドや負荷の不均衡が検出出来ず、いまいちパフォーマンスが伸び悩んでおります。
このような問題を解決できるLinux用のツールは存在するのでしょうか?
それともWindowsに移行するという選択肢しかないのでしょうか?
なんだかレベルの低い質問で慙愧に堪えないのですが、もし誘導や解答をいただければ嬉しいです。

Intel Thread Profiler
URLリンク(www.intel.com)

106:デフォルトの名無しさん
06/12/11 18:47:00
一昔前だったらまともなスレッドプログラミングしたけりゃSolaris使え、で
片付けられてたような気がするけど私も興味あるので識者の降臨を待つ。
Valgrind(Helgrinid)の他にLinuxで実用に耐えるツールはあるのかな、と。

107:デフォルトの名無しさん
06/12/11 19:06:34
とりあえず脳味噌ぶら〜んから適当に検索。
URLリンク(www.nbrains.net)
URLリンク(www.nbrains.net)

108:105
06/12/11 22:40:37
>>106-107
御解答有難う御座います。
わざわざ検索していただいたのに申し訳ないのですが、ちょっとその中には無いようですorz
凹んでいるだけでは何にもならないので、とりあえず"OpenMP"でググって片っ端から有望そうな所を覗いてみました。
結果、Omni OpenMP Compilerにtlogviewなるツールがあることがわかりました。
URLリンク(phase.hpcc.jp)
これを使えば、「iccでOpenMPを使った限界までのパフォーマンスチューニング」は難しそうですが、
「自分のコードの駄目なところ(計算粒度、ロードバランス等)を効率的に見つける」ことはできそうな感じです。
これを使って駄目だったらWinへの移行も検討してみようと思います。

109:デフォルトの名無しさん
06/12/11 22:42:55
SolarisがN:Mスレッドモデルをやめたのは効率が悪かったから?

110:デフォルトの名無しさん
06/12/11 23:45:55
アプリが1:1モデルを前提に作られる(チューンされる)ようになったから。
アプリといってもぶっちゃけoracleだが。
SolarisのためだけにN:M用チューンするのは時間の無駄だからね。

これを効率というならば効率だね。

111:デフォルトの名無しさん
06/12/20 09:58:49
I/.O主体の仕事は前提とかチューンってこととは関係なく、
1:1の方が効率がいい場合が多いでしょ。
CPUを明け渡すのがカーネル内であることが多いから。
だからエンタープライズが主戦場のSolarisでは当然のことかと。

112:デフォルトの名無しさん
06/12/20 10:23:41
OSが1:1ばかりになったというのもあるよ

113:デフォルトの名無しさん
06/12/21 01:18:13
 そういうことは関係ない。
ちゃんと選んでやっている。

114:デフォルトの名無しさん
06/12/21 01:28:43
M:Nはシグナルの動きが1:1のときと全く同じにはならない。
両モードでのデバッグや検証コストを掛けられない。

もう一つは>>112のとおり。
OS屋のオナニーで仕様が決まる時代は終わった。

115:デフォルトの名無しさん
06/12/22 22:55:26
マルチスレッドのデバッグではまっています
(私が作ったんじゃないのですが)
beginthreadが50個、EnterCriticaSectionが40個くらい、
スレッド最大200個くらいが動くとんでもないシステムです。
(もちろん満足に動いてないです)

とりあえず、下記の方針でソースをチェックしようと思いますが、
他にもありますでしょうか?

1 InitializeCriticalSection()以前の行に、_beginthreadを呼び出す関数に入ってないか
2 スタティック変数、グローバル変数にEnterCriticalSecitonなしで書き込みを
行ってないか
3 newで作ったオブジェクトのポインタを複数のスレッドで参照してないか

116:デフォルトの名無しさん
06/12/22 23:13:58
>>115
問題を正しく特定できてるのか?

117:デフォルトの名無しさん
06/12/23 00:10:24
>>116
とにかくアクセス違反で落ちたり、
const変数が書き換わったりするみたいです

もちろんマルチスレッドが原因かは特定できないのですが、
(ただ、ソースを見ると明らかにマルチスレッドを扱いきれてないです)
今、メモリ周りとかいろんな方面から数人で見ています。
もちろんデバッガ使ったりログ吐いたりはしています。



118:デフォルトの名無しさん
06/12/23 01:17:19
>>115

あと、EnterCriticalSectionへの再帰がないか。
同一スレッドだと、EnterCriticalSectionの挙動が変わるから注意。


119:デフォルトの名無しさん
06/12/23 03:03:16
どれくらいのスパゲッティ度かにもよるけども
仮想的なdbを用意して、データへのアクセスは必ずdb経由にするのも手だぞ。
(ポインタは渡さない、必ず生データのやり取りにする)
少なくとも知らない間に書き換わることはなくなる。
パフォーマンスは落ちるけどな。

120:デフォルトの名無しさん
06/12/23 09:02:59
>>118

なるほど、それは知りませんでした。ありがトン!!!!!

>>119

うーん、なるほど。それも覚えておきます。ありがトン!!!
とりあえず、ある程度安定してきたら、
再設計など検討するらしいです。

121:デフォルトの名無しさん
06/12/31 12:29:32
winapiでいうところのCrateEvent(), WatiForSingleObject(), SetEvent(), ResetEvent()
に該当する関数ってPOSIXでいうとどんなものになるんでしょうか?

mutexは双方にあって別にいいんですが、待機オブジェクトがなくて困っています。

122:デフォルトの名無しさん
06/12/31 13:24:29
>>121 condition

123:デフォルトの名無しさん
07/01/04 21:52:54
新年明けましておめでとうございます。
本年も、マルチスレッドプログラミング相談室 その5にご健勝あれ。

124:デフォルトの名無しさん
07/01/06 21:53:22
本年の相談は終了いたしました。

125:デフォルトの名無しさん
07/01/06 23:09:40
>>123
うむ御旗楯無もご照覧あれ

126:デフォルトの名無しさん
07/01/08 22:40:26
実験用にものすごく単純なマルチスレッドの http サーバを組んでみたのだけど、
コードだけ見るとロックするようなコードじゃないのに、長時間ストップしたまま
になることがある。(いちおう、しばらく待つと再開する)

listen() 状態のソケット作って、accept() したら pthread_create() してループ。
子スレッドのほうでは GET (path) HTTP/1.1 を待って、そのファイルを読んで返すだけ。

という単純なやつなのだけど、毎秒100リクエスト以上くらい httperf で送ってやると、
必要以上に処理がストップする。
(netstat -a すると一つも ESTABLISHED になっていない状態で数秒間とまっている)

カーネルは NUMA を無効にした以外は特にいじっていない Linux 2.6.15.7/x86_64
スレッドとネットワークをがんがんいじっている人には自明な問題っぽいけど、
どの辺に原因があって、どういじれば、せめて無駄なストップをしなくなるのでしょうか。

127:デフォルトの名無しさん
07/01/09 11:26:21
>>126
親スレッドでpthread_joinなり、pthread_detachしてる?
してないと、終了コード保持のため、子スレッドが終了せず、プロセスのスレッド数限界に
引っかかるかもしれん。

128:デフォルトの名無しさん
07/01/09 17:27:41
いちいちaccept毎にthreadを作成・破棄というのが良くない予感

129:デフォルトの名無しさん
07/01/09 19:18:57
>>126
子スレッドはちゃんjとソケットから全部読んでから closeするか、shutdown するかしてますか?

130:デフォルトの名無しさん
07/01/09 21:36:43
FreeBSDでコンパイル&実行するとそういう問題は起きない

131:デフォルトの名無しさん
07/01/16 22:08:14
_endthreadでスレッド終了すると、デストラクタが走りません。
無理やり{}で囲んでデストラクタを走らせてますが、
標準的な方法ってありますか?

132:デフォルトの名無しさん
07/01/16 22:17:40
_beginthreadは使わない
_endthreadexは呼ばない

133:デフォルトの名無しさん
07/01/16 22:29:22
>>132
_beginthreadexを使い、スレッド終了時に_endthreadexを呼ばないで単にreturnするだけということでしょうか??

134:126
07/01/16 23:37:42
ISP が割り当てるアドレスの周辺が 2ch にブロックされて書き込めなかった…。

スレッドとは関係なく、プロセス (もしくはある listen 状態のソケット)
あたりの同時接続数が一定値を超えると何かあるのかも、とか推測中。

>>127
pthread_detach() してますね。
>>128
待機スレッドを用意しておくとかすると改善するのかな。
>>129
あ、読み残しがある可能性はあるかも。
けど、そういう原因ならリクエスト頻度を下げても同様の問題が起こり
そうなものだが、 50リクエスト/秒くらいにすると起こらなくなる。
>>130
ソケット一般の問題じゃなくて Linux 特有の問題か…。

135:126
07/01/16 23:39:44
あ、とりあえず接続数を減らして、一接続あたりの転送量を増やすことで
目的には事足りるので、とりあえずそのようにしてやっている。

なぜストップするのか、に対する興味はあるのでまだ調べているけど。

136:デフォルトの名無しさん
07/01/17 18:05:57
tcp_fin_timeout の話かなぁ
再利用できるポートが足りなくなって、待ちになってるとか

137:126
07/01/17 22:48:11
>>136
あ、それビンゴかも。

Apache に細工して、一度ソケットを (勝手な手順で) 作り直してアクセスすると、
同様の停止現象が起こった調査結果が手元にある。

ソケットに何かの値を設定すると停止現象を回避できるのかなあ
(Apache は標準でそれをやっているけど、自分の勝手な手順ではやっていないのが原因かなあ)
と想像していた。 setsockopt() で *ソケットごとに* この tcp_fin_timeout を
設定できるらしいので、この値がそれかもしれない。

これから Apache のソースを読んでみるつもり。 thanks.

138:デフォルトの名無しさん
07/01/17 23:11:05
>>134
>あ、読み残しがある可能性はあるかも。

ソケットは、両端で正しく
・全部読む (read で 0 が戻るまで)
・shutdown する
のどちらかをしないと、close しても FIN_WAIT_2 だか何だか長めに待たされるステートに
なっちゃっうんじゃ無かったかなあ。netstat してみれば即わかるけど。

URLリンク(www.kt.rim.or.jp)
の mini FAQ の 5 を参照。

139:デフォルトの名無しさん
07/01/19 12:09:34
スレッドがシグナル状態になったあとに新たにスレッドを生成したいのですが、
そのスレッドのハンドルはクローズした方が良いのでしょうか?
シグナル状態になったらスレッドのスタックは解除されるようですが。
上書きしてCreateThreadをしたらメモリリークしたりしますか?
Win32APIです。

140:デフォルトの名無しさん
07/01/19 12:36:33
クローズした方が良い

141:デフォルトの名無しさん
07/01/19 23:23:03
ハンドルってただのポインタだから、
上書きしてもポインタ先が変わるだけ
リソースは残ったままだとおもう

142:デフォルトの名無しさん
07/01/19 23:30:08
スレッドが終了してシグナル状態になったんであれば、
スタックとかコンテキストは解放されると思うけど
ハンドルは残ったままじゃないか?戻り値を受け取るためにハンドルが必要だし。
といっても、ハンドルごとき残ったままでもたいしたことは無い。
(少々のリソース漏れはたいしたことないなんて言ってる奴のコードは信用ならんけど)

143:デフォルトの名無しさん
07/01/20 01:01:12
試してみた。
#include <stdio.h>
#include <windows.h>
static DWORD WINAPI func(LPVOID p) {
printf("thread %d\n", (int)p);
return 0;
}
int main() {
int i;
for(i = 0; ; i++) {
if (::CreateThread(0, 0, func, (LPVOID)i, 0, 0) == 0) break;
}
::getchar();
printf("i = %d error code %u\n", i, ::GetLastError());
::getchar();
}

VS2005のデバッガ上だと2000超えたあたりでERROR_NOT_ENOUGH_MEMORYで止まる。
デバッガ外でやってみたら10万超えても終わらず、
なぜかipoint32.exeにアプリケーションエラーが出たりして怖くなったのでやめた。

144:デフォルトの名無しさん
07/01/21 13:15:48
メモリリークか 何もかも(ry

145:デフォルトの名無しさん
07/01/21 15:01:28
func のスレッド優先度、上げといた方がいいのでは?


146:143
07/01/22 08:17:30
あーそっか。あくまでハンドルのみのテストだったらちゃんとWaitForSingleObjectで待たなきゃいかんわな。
しかしWaitForSingleObjectしたのにわざわざCloseHandleしないでおく理由って考えにくいが。

147: ◆0uxK91AxII
07/01/22 19:48:12
CreateThreadで走らせたthreadでは、CRTのfunctionを呼ぶべきではない。

148:デフォルトの名無しさん
07/01/22 20:37:55
メモリーリーク?

149:デフォルトの名無しさん
07/01/23 00:11:40
再入?

150:デフォルトの名無しさん
07/01/23 01:46:25
URLリンク(d.hatena.ne.jp)
こんな話もあった。

151:デフォルトの名無しさん
07/01/24 19:22:25
とりあえずCRTは動的リンクしておけと

152:デフォルトの名無しさん
07/02/02 23:38:46
2つプロセスで共有メモリのデータを共有する
サンプルってどこにあるのですか?pthread Linuxのやつを探しています。

153:デフォルトの名無しさん
07/02/03 09:49:27
スレッド関係ないから。APUE買え。

154:デフォルトの名無しさん
07/02/03 10:21:08
VS2005って標準でOpenMP使えたんだな

155:デフォルトの名無しさん
07/02/18 16:38:41
ここで俺がひとまずここまでのレスをまとめる。

マルチスレッドは ム ズ カ ス ィ

156:デフォルトの名無しさん
07/02/18 20:05:23
>>152
だまってmmapすればいいんでないの?

157:デフォルトの名無しさん
07/02/18 21:12:05
>>155
お前にこの言葉を授けよう
「糞スレ立てるな」

158:デフォルトの名無しさん
07/02/20 23:27:34
ファイアーモックス!

159:デフォルトの名無しさん
07/02/24 10:27:57
質問なんですがマルチスレッドでは同じ変数のアドレスの場所を
if文等で見に行くだけならぶつかることはないですか?

160:デフォルトの名無しさん
07/02/24 10:34:52
読むだけなら問題ないと思。
最適化には気をつける必要があるが。

161:デフォルトの名無しさん
07/02/24 10:40:11
FAQだな。
読むだけなら排他不要。
ただしvolatileを忘れずに。

つーかvolatile最強。

162:デフォルトの名無しさん
07/02/24 12:17:45
>>159-161
別スレッドからの書き込みも考慮するならロックなどによる同期が必要。

volatile はネタだよね?

163:デフォルトの名無しさん
07/02/24 12:46:43
他スレッドが変更するメモリを読むなら必要でしょ。

164:デフォルトの名無しさん
07/02/24 13:02:15
おっ久々にvolatileが来たか。わくわく。

165:デフォルトの名無しさん
07/02/24 13:16:54
>>162
writerが一人、readerが複数ならロックする必要ないよ。

166:デフォルトの名無しさん
07/02/24 13:28:17
>>165
あたまだいじょうぶか

167:デフォルトの名無しさん
07/02/24 13:28:40
意地悪しないで教えてやれよって。
JavaやC#でのvolatileはその解釈であってる。
C/C++のvolatileは割り込みしか想定していないので、マルチスレッドでの動作は不定。
ただしシングルCPUでのマルチスレッドは割り込み(タイマー割り込み)で実現されているのでたまたま動作する。

>>165
変数がアトミックじゃない場合、例えば32bitCPUで64Bitの変数にアクセスする場合などは、
書いてる最中に読み込みされると半分しか書き換わってない状態を読み込む可能性がある。

168:デフォルトの名無しさん
07/02/24 13:34:19
シングルCPUのマルチスレッドだと動いてしまうことが多いからね。それで合ってると思い込んでしまうのだよ。
CPUキャッシュの問題は難解だね。
さらにウィークメモリモデルともなるとさすがについて行けんorz

169:デフォルトの名無しさん
07/02/24 13:43:29
書き込み側が明示的に、アトミック書き込み命令を出せばいいんでね?

170:デフォルトの名無しさん
07/02/24 16:37:41
読み込みもアトミックじゃねーと意味ね-よ

171:デフォルトの名無しさん
07/02/24 16:41:40
要は、アトミックに読み込めることが期待できるint程度のデータ以外はなんらかの排他が必要ということでよろしいか。
#いや、intでも排他するべきなのかもし煉瓦。

172:デフォルトの名無しさん
07/02/24 18:52:05
>>171
> #いや、intでも排他するべきなのかもし煉瓦。
というのが>>168だね

マルチCPU環境の排他はバス設計の影響もうけるから
環境を明記しないと言及不能やね


173:デフォルトの名無しさん
07/02/24 20:21:33
>170
書き込みがアトミックに出来るのに、読み込みがアトミックに出来ない、なんて
変態CPUが現存するのか?そういうCPUではロックをどう実装するんだろ?

174:デフォルトの名無しさん
07/02/24 23:09:38
キャッシュラインをまたぐと面白いよねー


175:デフォルトの名無しさん
07/02/25 01:29:43
>書き込みがアトミックに出来るのに、読み込みがアトミックに出来ない、なんて
>変態CPUが現存するのか?

>書き込み側が明示的に、アトミック書き込み命令を出せばいいんでね?

>読み込みもアトミックじゃねーと意味ね-よ

だれも読み込みがアトミックにできないなんて言っとらんわ。


176:デフォルトの名無しさん
07/02/25 04:26:18
どっちかというと
>ねーと  → ー
>ね-よ  → -
この不整合の方が気になるな
どちらかがアトミックじゃないのかもしれない

177:デフォルトの名無しさん
07/02/25 05:04:12
こういう意味不明な誤変換はUNIX発のFEPwに多いな

178:デフォルトの名無しさん
07/02/25 15:04:49
volatile方式を知られては困る奴が必死だなw

179:デフォルトの名無しさん
07/02/25 15:39:00
URLリンク(d.hatena.ne.jp)
volatile無意味説

180:デフォルトの名無しさん
07/02/25 17:24:44
そのリンク先にしても、なぜvolatileでは駄目なのかが書いてなくて
「お母さんが駄目って言ってたから」レベルの話しか書いてないな。
そして、そのURLを貼る>>179も同様。

181:デフォルトの名無しさん
07/02/25 17:50:33
なぜ volatile で済むと言えるのか、書くかリンク貼るかしてみやがれ。

182:デフォルトの名無しさん
07/02/25 18:59:13
volatile - Multithreaded Programmer's Best Friend
URLリンク(www.ddj.com)

183:デフォルトの名無しさん
07/02/25 19:32:05
>>182
もしかして >>181 へのレスのつもりなのか?

184:デフォルトの名無しさん
07/02/25 19:41:48
そんなわけないだろ。逆だ。
"Paradoxically, it's worse to use volatile directly with built-ins, in spite of the fact that initially this was the usage intent of volatile!"

185:デフォルトの名無しさん
07/02/25 20:20:26
>>182
これって
>スレッドセーフなメソッドにはvolatileをつける。
という提案だよな?まだ実装はないと思ったのだが。

186:デフォルトの名無しさん
07/02/25 22:48:59
volatileを実装してるJVMってほとんど無いんじゃなかったっけ

187:デフォルトの名無しさん
07/02/25 23:35:03
>>185
実装ってどういうこと?標準 C++ コンパイラがあれば使える手法に見えるんだけど。

188:デフォルトの名無しさん
07/02/26 01:31:15
C とか C++ の volatile って I/O レジスタとか, 割り込み同期変数とかを, オ
プティマイザがレジスタキャッシュしないように指示するために導入された物で,
バリア同期命令とか生成する処理系は皆無のような気がするが...

俺の認識が古くって, バリア同期とか生成してくれる処理系が既にあるんだった
ら先にあやまっとく


189:デフォルトの名無しさん
07/02/26 05:30:32
何故「volatileで済む用途」のケースにメモリバリアがどうのという話になるのかわからんね。

簡単な例で言えば
(タイマ割り込み等で更新される)カウンタを読む場合とか
複数スレッドで値を読み取るとしても、ロックする必要なんか無い。
たとえ1ns更新が遅れたって、問題が出ることは無い(問題が出るようなら、設計がおかしい)。

え、更新時の再入を考慮しろって?
そういうのを「設計」と言うんだろうに。

190:デフォルトの名無しさん
07/02/26 06:29:25
>>182
int func() const { } はよく使うが、int func() volatile { } を実際に使ってる例ははじめてみる。
ただその記事のLockingPtrは func() volatile の仕組みだけ拝借して実際の排他はmutexでやってるようだ。
よく理解できない部分もあるがvolatileしておいてconst_castで限定的に穴あけてるのだろうか。
このスレで問題になるのはそこではなくて、
記事の最初と2番目のコードで while (!flag_) のflagがvolatileだけでいいのか、
同期機構を使わなくてはいけないかのポイントだと思う。


191:デフォルトの名無しさん
07/02/26 07:52:54
>>188
volatileで済むってのは、コヒーレントキャッシュを持っている環境で
アトミックに読み書きできるサイズ限定だから、メモリバリアは関係ないよ。
2つ以上の変数に依存関係があったら、volatileだけでは無理。

一般論の話をすれば、キャッシュの一貫性を保障しない環境もあるから
int程度でもvolatileでは駄目という話になるが。

192:デフォルトの名無しさん
07/02/26 09:15:17
ちゃんと読めてないが、>>182って、コンパイラの実装とか関係なくて
constみたいな印としてvolatileを使ってみようっていう提案だよね?

193:デフォルトの名無しさん
07/02/26 19:26:29
volatileの仕様は処理系定義だとあれほど言ってるのに…

処理系を指定しないでvolatileについて語れることはない

194:デフォルトの名無しさん
07/02/26 21:25:32
処理系どころか言語すら指定されてない気がするのは
漏れだけではないはずだ

195:デフォルトの名無しさん
07/02/27 00:02:42
とりあえず、volatileをCの最適化阻害だけと仮定して、

>>191
一貫性を保証しなかったとしても、それはあくまで保証の話。
いつまで経っても同期されないような腐ったCPUってあるの?
あったとしたら処理系としてBrokenだよなぁ・・・。

>>193
ここに書いてる人のほとんどは処理系依存だなんて承知の上でしょ?


とりあえず、intだとしても同期やメモリーバリアは必要か?
って問いはもう少しレベル分けした方がいいと思う。

1. 読み込みに依存した書き込み(read-modify-write)
⇒ 同期もしくはメモリーバリアを含んだCASが必要。

2. 読み込みに依存しないが、確実に更新を見る必要がある
⇒ OoOを回避するために、少なくともメモリーバリアは必要。

3. 読み込みに依存しないし、更新は近いうちに反映されればよい
⇒ volatileでレジスタへの張り付きを阻害するだけで問題なし?

>>189の「更新が遅れても構わない」は3になると思うんだが。

196:デフォルトの名無しさん
07/02/27 01:19:13
つまり、例えば時間掛かる処理をするスレッドがあってその進捗をプログレスバーに出すような用途なら、
進捗を書き込むのを処理スレッドに限定してGUIスレッドでそこをvolatileで参照するのもありってことでOK?

197:デフォルトの名無しさん
07/02/27 01:57:30
マルチスレッドの話は環境によって差異がありすぎるから
環境を限定しない討論に何の意味もないって感じだな。

198:デフォルトの名無しさん
07/02/27 03:01:55
volatile最強伝説が吹き荒れるwww

199:デフォルトの名無しさん
07/02/27 08:43:30
> 195
> とりあえず、volatileをCの最適化阻害だけと仮定して、

曖昧な仮定だな。
まずはお前の想定している処理系と、そのマニュアルにある
volatile参照の仕様を書くんだ。

200:デフォルトの名無しさん
07/02/27 09:11:34
もう>>182みたいにvolatileキーワード使って組込型でも何でもロック必須にしちゃいなyo!
template <typename T>
struct NativeWrapper
{
operator T&() { return obj; }
private:
T obj;
};

volatile NativeWrapper<int> syncint;
mutex mtx;
LockingPtr<NativeWrapper<int> > pInt(syncint, mtx);
*pInt = 10;

201:195
07/02/27 12:18:08
>>196
そんなとこ。他ではTwo-Phase Terminationの終了フラグとか。
こちらの場合はメモリーバリアを含んだ同期をループの内部で
実行する事が殆どだから、次のループで確実に気付くだろうけど。

>>197,199
おまえら処理系依存って書きたいだけだろ?
実際のとこはどうなのか、って話がしたいんだよ。

少なくともOoOやコヒーレンシが問題になるんだから、
最低限SMP/Multi Core/HT等のアーキテクチャとなる。

例えばIA-32,Power PC,Sparc等のSMPの類をサポートした
アーキテクチャのうち、>>195よりも厳しい制約が必要と
なるものは存在するの?

202:デフォルトの名無しさん
07/02/27 13:04:58
>>201
個々の CPU について考えるなんて面倒だから、
保証されてるかどうかで話したほうが楽なのに。

今は無くても将来にわたって無いとも言えないしね。

203:デフォルトの名無しさん
07/02/27 14:04:14
>>193
データ構造上の都合か何かでキャッシュラインをまたぐような位置から
int を読み込む場合には 3 もだめじゃないかな。

204:デフォルトの名無しさん
07/02/27 14:12:43
>>201
Intel Itanium では、非共有キャッシュが大きい上にキャッシュフラッシュの順序が
書き込みの順序と異なる。ので、

・volatile int a を監視
・aが変更されたら「何か」を行う

という処理の場合、大抵は「何か」の準備が出来たから a を1にしてるんだと思うけど、
メモリバリアが無いとその準備の処理結果を読み出せない可能性がある。

例) volatile size_t buflen; volatile char buf[max_buf]; で、
スレッド1: buflen = read(hoge); ...
スレッド2: if (buflen>0) { bufを利用; }
で、(スレッド2側のCPUから見て)buflen には read の結果のバイト数が書かれているが、
buf の内容はデタラメ、という状況がごく当たり前にあり得る。

205:195
07/02/27 14:54:42
>>203
キャッシュラインをまたぐ場合って、普通のコードじゃ起きないし、
char buf[sizeof(int)+1]; *(int *)(buf+1) = 0;した場合とかでしょ?
今では例外飛ばさずにアクセスできるアーキテクチャの方が少数派なのでは?

>>204
他の変数を確定的に見る必要がある場合はOoOの関係で無理。
>>195はひとつのintを扱う場合なつもりで書いてます。

>>196を例にすると、タイマでプログレスバーを更新する時はvolatileのみ、
最後に終了したかを確定的に判断したい時だけpthread_join()するケースとか。

206:デフォルトの名無しさん
07/02/27 15:21:57
>>205
PCで使われているCPUの98%は、それをごく普通に実行します。
任意位置からの32bitの整数読み出しはMPEG系のビデオコーデックの
処理では多利用されるし。

207:195
07/02/27 16:11:02
CPUの数が多いのは当たり前だからアーキテクチャって書いたのに。
そんな下らないツッコミは要らないって。。

Codecの処理だろうが、境界整列に反したメモリアクセスなんて
行儀の悪いコードなんじゃないの?少なくともポータブルじゃない。
処理系依存のレベルで言ったらvolatileの比じゃないと思うんだけど。


次ページ
最新レス表示
スレッドの検索
類似スレ一覧
話題のニュース
おまかせリスト
▼オプションを表示
暇つぶし2ch

4209日前に更新/97 KB
担当:undef