マルチスレッドプログラミング相談室 その3

このエントリーをはてなブックマークに追加
929デフォルトの名無しさん:2005/09/07(水) 18:41:22
MINIX使ってないので、「オペレーティングシステム―設計と理論およびMINIXによる実装」読んでも意味ないし
930デフォルトの名無しさん:2005/09/07(水) 19:13:46
はあ。
Windowsは業界スタンダードだから意味あるはずだけどねえ
931デフォルトの名無しさん:2005/09/07(水) 20:05:26
何業界だ?
932デフォルトの名無しさん:2005/09/07(水) 20:08:36
Window業界でのはなしでしょう
933デフォルトの名無しさん:2005/09/07(水) 22:20:40
windowsのイベントや、UNIXのsignalは、プログラマからみれば
APIとしてはコードのその場所でじっとwaitしてる形になると思うけど
イベントやsignal自体の内部実装(カーネル側?)
では結局はポーリングで実現されてたりするわけ?
934デフォルトの名無しさん:2005/09/07(水) 22:24:37
エロゲー的にはポーリングが正義、というFAが出ておりますが何か?
935デフォルトの名無しさん:2005/09/07(水) 22:28:17
割り込みにきまってんだろハゲ
936デフォルトの名無しさん:2005/09/07(水) 22:34:22
>>933
signal trampoline
937デフォルトの名無しさん:2005/09/13(火) 18:52:56
>>933
イベントやシグナルみたいな大掛かりなものはスレッド自体が
待ち状態になってスケジュールしなおされる。

スピンロックで待つのはWin32でSMPのEnterCriticalSection(記憶違
いかも)とか、Windows の WDM のコードとか、linux のカーネル内の
コードとかでスケジューラを動かすまでもないホンのちょっとの排他
処理を行うとき。
938デフォルトの名無しさん:2005/09/13(火) 22:59:20
なるほろ
939デフォルトの名無しさん:2005/09/16(金) 02:59:23
今2wayの鯖あるのですが、2つのCPUを効率よく使って計算させようと思うと
スレッド間でメモリ共有するだけでいいでしょうか?何か気をつけることないですか?
940デフォルトの名無しさん:2005/09/16(金) 03:10:07
意味若乱
941デフォルトの名無しさん:2005/09/16(金) 03:35:40
逆になるべく共有リソースを無くして独立させる方が良いと思う。
共有してると、アクセス排他制御とか同期制御とかが絶対必要。
942デフォルトの名無しさん:2005/09/16(金) 03:52:23
ていうかスレッドはメモリを共有してるもんでしょう
943デフォルトの名無しさん:2005/09/16(金) 07:09:44
>>942
メモリ空間は共有してても、同じメモリアドレスを共有してなきゃ問題ないじゃん。
944デフォルトの名無しさん:2005/09/16(金) 08:49:07
>>943
財布は共有してても生活空間は共有しない
という独立思考の高い夫婦モデルだな
945デフォルトの名無しさん:2005/09/16(金) 09:48:15
まあ普通プロセス/タスク内のスレッド間ではメモリを共有してるけどな。
946デフォルトの名無しさん:2005/09/21(水) 19:20:26
>>937
なんか変じゃない?
スレッドがスケジューリングされなきゃ、何時まで経っても他スレッドが実行されず、
状態が変化しないのと違う?
947デフォルトの名無しさん:2005/09/21(水) 20:05:03
>>946
完全に協調型ならそうなりますな。
普通は外的要因で叩き起こされると思いまふが。

948デフォルトの名無しさん:2005/09/21(水) 20:15:08
>>946の行っている意味が分からないので解説して。
>>937のどの部分に対していっているの?
949デフォルトの名無しさん:2005/09/21(水) 20:16:49
元の質問も、その答えも、高度すぎて意味がわからん
950デフォルトの名無しさん:2005/09/21(水) 23:40:48
>>948
いつまでもspinlockの所有権をacquire しようとし続けると
デッドロックしてしまうということ。
なわけでデッドロックしないように考慮する必要がある。

具体的には、
Win32 API のCritical Section の場合にはInitializeCriticalSectionAndSpinCountで
「スケジューリングしないでぐるぐる回る回数(の上限)」を設定して使う必要があるし、
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/initializecriticalsectionandspincount.asp

Windows のカーネル内でKeAcquireSpinLock なんかを使う場合にはdispatch level とか
も考慮して、acquire したら自コンテキストの実行が中断されないうちにすぐreleaseすることが
要求されている。
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/kmarch/hh/kmarch/Synchro_f74a900d-aad5-4473-8f46-00531c9ade89.xml.asp
951デフォルトの名無しさん:2005/09/21(水) 23:50:19
要するに、

>>937
> スケジューラを動かすまでもない

を「自分からyeild()しないで」等に書き直した方がいいって事ね。

952デフォルトの名無しさん:2005/09/22(木) 03:02:54
そもそもSMPでスケジューラ等を実装するには、
スピンロック等の低レベルな排他機構が必要なわけで…
953デフォルトの名無しさん:2005/09/22(木) 11:44:45
マルチスレッドと、ウィンドウプロシージャについて質問なんですが、
現在、通信系のプログラムを書いています。

あるデータを受信したら処理をして、その結果を送信元に返信する。

という関数があるのですが、
1).スレッドを作り、そのスレッドで処理をさせる。
2).ウィンドウプロシージャを作り、メッセージにデータのポインタを渡す。
 ウィンドウプロシージャで処理を行わせる。

この2通りを考えてみたんですが、楽なのは2)です。
どっちの方法が有効でしょうか?
954デフォルトの名無しさん:2005/09/22(木) 11:48:00
スレッドを使ってブロッキングでやるのが1番楽だと思う
955デフォルトの名無しさん:2005/09/22(木) 14:02:05
>>953
結局1)が楽です。
956デフォルトの名無しさん:2005/09/22(木) 16:32:07
こんにちは。
gcc(RHEL), MinGW(Win), Visual Studio .NET(Win)の各環境でC++を使って私用ミニツールなど
を作ったりして仕事してる、一介の営業マンです。最近はサービスでお客さん用のツールなんか
も作ったりし始めました。SE受注減らしてどうするんだって感じですが。

C/C++でのpthreadに関する質問です。
pthread_createでガーっと並列にスレッドを作って仕事をさせ、pthread_joinを回して終了を待つわけな
のですが、
pthread_joinはブロックするので、先頭のスレッドが長引いちゃうと後に続くスレッドが先に終わってても
ボケーっと待ってしまいますよね。
これを、スレッドが終了した順に処理する方法ってありますでしょうか?
よろしくお願いします。
957デフォルトの名無しさん:2005/09/22(木) 16:46:40
例えばこんな風にすればいいんじゃない?

* 生きてるスレッド数を数えるカウンタを用意しておく。(スレッド数で初期化)
* 各スレッドは終わるときにカウンタを減らして、ゼロになったら pthread_cond_signal() みたいなことをする。
* メインは pthread_cond_wait() かなんかで待ち。
* 起こされた時にはスレッドは全部終わってるはず。
* もちろんカウンタをいじるときは排他制御。
958デフォルトの名無しさん:2005/09/22(木) 16:48:56
あと、スレッドが終わる度になんかするなら、

* 各スレッドは終わるときにカウンタを減らして、 pthread_cond_signal() みたいなことをする。
* メインは pthread_cond_wait() かなんかで待ち。
 起きたときにカウンタがゼロになってたら全部終わってるはず。
959デフォルトの名無しさん:2005/09/22(木) 16:53:21
どうせ全部まとめて終了を待つなら、順番にjoinするだけで何の問題もないと思うけど。

メインスレッドはワーカースレッドを終了を順次待ちつつ何かしてる必要があるなら、
キューを用意してスレッドが終了前に自分のpthread_tを追加するとか、
メインスレッドがイベントループなら終了を通知するイベントを投げるとか。
960デフォルトの名無しさん:2005/09/22(木) 19:33:15
> 全部まとめて終了を待つ
逆です
早く終わったスレッドの順に次のジョブキューに入れるやり方ですね
961デフォルトの名無しさん:2005/09/22(木) 19:36:14
それならスレッドプールでしょ
962デフォルトの名無しさん:2005/09/22(木) 19:42:45
元の質問文と真実の内容がかけ離れてんな
963デフォルトの名無しさん:2005/09/22(木) 20:10:03
>>960
>早く終わったスレッドの順に次のジョブキューに入れるやり方ですね

その場合はスレッド終わっちゃいけないから、joinなんか使えないと思われ
964デフォルトの名無しさん:2005/09/22(木) 20:30:46
リスト構造にしたらいいんじゃね?
965デフォルトの名無しさん:2005/09/23(金) 01:37:09
>>963
pthread_cleanup_push()で登録するとか。
966956:2005/09/29(木) 20:31:03
つまりこんなかんじ?

1. 子スレッドはその仕事の最後にグローバル関数で
「俺は終わりましたフラグ」を立ててから死ぬ

2. メインのスレッドは全部の子スレッドの「俺は終わり
ましたフラグ」を監視しながらぐるぐる回ってる

3. あるスレッドの「俺は終わりましたフラグ」が立ったら、
そのスレッドの計算結果を取得して次の仕事に放り込む


んー、スレッドの数が不定なので、俺は終わりましたフラグの
作り方と監視の仕方の実装に工夫が要りそうですね。
967デフォルトの名無しさん:2005/09/29(木) 21:40:28
>>956
なぜスレッドを使って並列でしようとしてるのかが見えないんだけど・
本当にマルチスレッドにする必要あるのかな
968デフォルトの名無しさん:2005/09/29(木) 21:43:23
つか>>965は無視なんか?
969デフォルトの名無しさん:2005/09/29(木) 21:56:27
リスト構造でやってみたらと・・・

//スレッドに持っていく構造体
typedef struct tag tag;
struct tag{
tag *next;//初期化してNULLにしておく
・・・
};

//メインが持つグローバルデータ
tag *root;
tag *last;
int flg;

計算が終わった子は
flgが特定の値であれば待機。
flgが特定の値でなければ特定の値にして
  rootがNULLでなければlast->nextに自分の構造体のアドレスを登録。
  rootがNULLであればrootとlastに自分の構造体のアドレスを登録。

メインスレッドは
flgが特定の値であれば待機。
flgが特定の値でなければ特定の値にして、
構造体のデータを取り出す。
root=root->next;とする。
flgの値を戻す。

ま、こんな感じでどうざんしょ。
970デフォルトの名無しさん:2005/09/29(木) 22:00:26
>>966
漏れならこうするよ。

メインスレッド
1. ジョブをキュー(FIFO)に登録。
2. ワーカスレッドを妥当な数だけ生成
3. pthread_cond_wait() か何かで待ち、ジョブのキューが空になっていたら完了。

ワーカスレッド
1. ジョブをキューから取り出して実行
2. 完了したら、その結果を利用した「次の仕事」を(もしあれば)ジョブキューに入れる。
  無ければスレッド終了。
3. 1に戻る
971デフォルトの名無しさん:2005/10/01(土) 13:03:58
pthread_cond_waitとかpthread_cleanup_pushとか、クレバーなコーディングはご法度
972デフォルトの名無しさん:2005/10/03(月) 13:56:54
クリティカルセクションとミューテクスはどちらがお勧めなのでしょうか?
ダンディーな方、教えてくださいませ。
973デフォルトの名無しさん:2005/10/03(月) 14:47:01
>>972
オススメと言うか、その2つは使い分けるもの。
Win32の場合の話だけど、

プロセス内でのスレッドの同期程度ならクリティカルセクションを用いる。
複数のプロセスで排他を行いたいなら、ミューテックスの類を使う。

SMPで無ければ効率は同じ。SMPの場合にはInitializeCriticalSectionAndSpinCount の説明を参照。
974デフォルトの名無しさん:2005/10/03(月) 18:16:26
>>973さん
なるほど、納得しました!
どうもありがとうございました。
975デフォルトの名無しさん:2005/10/03(月) 19:09:16
>>974
まだあった・・
複数の同期オブジェクトを待ったり、待っている最中にWindowメッセージや
COMのLRPC(外部スレッド/プロセスからのCOM呼び出し)を処理する必要
があるなら Mutex。
976デフォルトの名無しさん:2005/10/03(月) 19:28:00
>>975
色々違いがあるんですね。
ご丁寧に有難うございましたm(_ _)m
977デフォルトの名無しさん:2005/10/11(火) 23:14:03
age
978デフォルトの名無しさん
お舞らたとえばですがファイルの内容をメモリ上に展開しそこにほかのスレッドがアクセスする必要があるとしたらどんな風に書きますか?
・データは木構造
・IOからメモリに展開するスレッドは複数
・そこにUI スレッドや、計算スレッドが頻繁にアクセスする。リーダーとライターが複数ずついる。
・ためしにクラスレベルロックみたいのでやったらUIスレッドでCPUが100%言ってないのにたまに固まる(1秒以下)ことがある。

こういう場合ってどんな風にするもんなんでしょう。粒度さげると書くのが('A`)マンドクさくなるしデッドロックの危険も出てくる。
一般解や俺ならこうしてるってのがあればよろ。