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

このエントリーをはてなブックマークに追加
1デフォルトの名無しさん
マルチスレッドプログラミングについて語るスレ。
OS・言語・環境は問わないが、それゆえ明記すべし。

その1 http://pc3.2ch.net/test/read.cgi/tech/997345868/
その2 http://pc5.2ch.net/test/read.cgi/tech/1037636153/
2デフォルトの名無しさん:04/10/20 19:29:21
3デフォルトの名無しさん:04/10/20 20:19:45
Pthread関係

The Single UNIX Specification, Version 2 Threads Extensions
http://www.unix.org/version2/whatsnew/login_threads.html

Multithreading in the Solaris Operating Environment
http://wwws.sun.com/software/whitepapers/solaris9/multithread.pdf

Building an open-source Solaris-compatible threads library
http://www.opensource.hp.com/the_source/linux_papers/scl_solaris.htm

Pthread Support in Microsoft Windows Services for UNIX Version 3.5
http://www.microsoft.com/technet/itsolutions/interop/sfu/pthreads0.mspx

Programming with POSIX Threads
http://www.awprofessional.com/title/0201633922
4デフォルトの名無しさん:04/10/20 20:21:31
ダグ・リー「Javaスレッド・プログラミング
並列オブジェクト指向プログラミングの設計原理」
http://www.amazon.co.jp/exec/obidos/ASIN/4881359185/
5デフォルトの名無しさん:04/10/21 13:08:21
>>1
誌ね
6デフォルトの名無しさん:04/10/21 13:16:00
>>1
糞スレ乙
7デフォルトの名無しさん:04/10/25 04:49:17
ほすしてみよう
ネタ щ(゚▽゚щ) カモーン
8デフォルトの名無しさん:04/10/25 10:10:28
FairThread最強伝説
9デフォルトの名無しさん:04/10/25 18:51:19
Win32のスレッドでGDIオブジェクトをスレッド間で共有して
ロックせずに交互に描画なんかしたりしたらまずいよね?
なんかWeb上にそういうサンプル使って説明してる馬鹿がいたからびっくりした
10デフォルトの名無しさん:04/10/25 21:14:29
>>9
...
11デフォルトの名無しさん:04/10/25 21:42:21
>>9
どこのページ?
12デフォルトの名無しさん:04/10/25 22:32:19
はっ、漏れのHPだw
13デフォルトの名無しさん:04/10/26 10:35:16
デッドロック以外にスローダウンというのがあって、こいつを回避するのは
なかなか難しいね。頭痛いわ。
14デフォルトの名無しさん:04/10/26 15:21:56
>>13
スローダウンってなんですか?
15デフォルトの名無しさん:04/10/26 21:50:29
確かに微妙な表現だよねw
16デフォルトの名無しさん:04/10/27 23:17:12
>>12
早く直せよ
17デフォルトの名無しさん:04/10/28 20:31:50
18デフォルトの名無しさん:04/10/28 21:47:23
そのサイトは初心者スレで馬鹿にされたサイトだな
19デフォルトの名無しさん:04/10/30 04:23:22
>>14
スローダウンぐらいぐぐれよ(((;-д- )
ttp://msugai.fc2web.com/java/thread/deadLock.html
システムプログラミングの本には大抵症状を起こすプログラム例がのっている。
20デフォルトの名無しさん:04/10/31 00:37:13
要するにスレッドの実行より切り替えに時間がかかって本末転倒状態になってるのがスローダウン?
21デフォルトの名無しさん:04/10/31 01:07:15
>>19
べつにyahooでいいじゃん
22デフォルトの名無しさん:04/10/31 07:37:24
>>20
全然違う。内部でミニデッドロックが多発して、本来走っているべき
スレッドの数が大幅に少なくなっているのがスローダウン。止まらず
に動いているので一見正常に見えるが、処理速度が遅くなるので、
あちこちに不都合が出る。最終的に完全なデッドロックに移行してしまう
事もある。

設計ミスが原因。
23デフォルトの名無しさん:04/10/31 11:17:12
ミニデッドロックって何だよ(w

ジャインアントロックすると簡単に起きるよね。
24デフォルトの名無しさん:04/10/31 11:37:02
スーパーデッドロックとかウルトラデッドロックはもっとデッドロックだぞ。
25デフォルトの名無しさん:04/10/31 12:18:59
デッドロックにミニもビッグもないだろ。バカ?
26デフォルトの名無しさん:04/10/31 15:32:31
27デフォルトの名無しさん:04/10/31 16:01:46
マルチスレッドとか言っても
管理に手間かかってメモリ余計に食うだけだろ

普通に処理したほうが百倍早い
28デフォルトの名無しさん:04/10/31 16:03:00
>>27
レベルの低い方はお引き取りください
29デフォルトの名無しさん:04/10/31 16:03:48
>>27
たいていそうだよね (百倍速いってことはないけど)。
できるだけ避けるほうがいいと思うよ、マルチスレッド。
30デフォルトの名無しさん:04/10/31 16:08:37
>>12
なおしたのか?
31デフォルトの名無しさん:04/10/31 16:12:22
>>29
HT
32名無しさん@お腹いっぱい。:04/10/31 16:49:20
スーパーとかウルトラとか百倍とか、漫画みたいだな。
33デフォルトの名無しさん:04/10/31 17:22:28
>>22
>>19のリンク先との説明と全然ちがうのですが、どっちが正しいの?
34デフォルトの名無しさん:04/10/31 18:02:23
>>30
まだです
35デフォルトの名無しさん:04/10/31 18:31:21
>>33
>>19のリンク先の説明は舌足らず。ちゃんとした本を買って勉強した方がいい。
36デフォルトの名無しさん:04/10/31 18:44:02
>>22
>内部でミニデッドロックが多発して

それは普通にデッドロックって言わない?
37デフォルトの名無しさん:04/10/31 18:44:53
>>34
さっさと直せよ
38デフォルトの名無しさん:04/10/31 19:08:52
FTPのパスワード忘れたので、無理です。
39デフォルトの名無しさん:04/10/31 20:18:58
ネタですか?
40デフォルトの名無しさん:04/10/31 23:06:38
ネタです。
41デフォルトの名無しさん:04/10/31 23:29:46
もう寝たです。
42デフォルトの名無しさん:04/11/01 03:34:01
スローダウンの他にスタベーションってのがあるから、>>22の場合は
それに相当すると思う。またレース状態ってのもある。

ttp://www.microsoft.com/japan/msdn/vs/general/vbtchusingthreads.asp
43デフォルトの名無しさん:04/11/01 04:58:11
すたべは、機会は与えられているのに、
リソースを割り当てられないエンエィティがあること。

レース状態というのは、
単にリソースを奪い合う関係にある状態のこと。
44デフォルトの名無しさん:04/11/01 07:53:18
スローダウンの他にマスタベーションってのがあるから、
45デフォルトの名無しさん:04/11/01 08:55:55
>>44
誰かが言うと思ってた。本当にバカなんだから。
46デフォルトの名無しさん:04/11/02 13:37:01
遅漏ダウンの他に
47デフォルトの名無しさん:04/11/03 16:56:43
pthreadで、スレッドが現在動いているかどうか調べるにはどうすればいいんですか?
48デフォルトの名無しさん:04/11/03 17:11:41
Cで書いてるのだが、なかなかうまくいかない。
以下のようなプログラムを作ってる。
懸賞サイトをよく利用するので住所などの入力を自動にするプログラム。
配布されてるのはあるが、なんか使いにくく機能がいまいち。
サイトごとに指定できないので、入力がおかしくなる懸賞サイトがある。
49デフォルトの名無しさん:04/11/03 17:32:00
>>48
スレ違い。
50デフォルトの名無しさん:04/11/03 23:59:16
>>47
「現在動いている」とは?
51デフォルトの名無しさん:04/11/04 06:15:00
gccでMPIを使えるようにするにはどのようにしたらよいのでしょうか?
52デフォルトの名無しさん:04/11/04 10:56:52
MPIはスレ違い。
使えるようにするだけなら、MPIの実装をinstallしろ。それだけだ。
53デフォルトの名無しさん:04/11/04 22:26:16
rand()がスレッドセーフではないのは何故ですか?
54デフォルトの名無しさん:04/11/04 22:29:45
めんどいから
55デフォルトの名無しさん:04/11/05 01:51:03
boost::randomはスレッドセーフじゃなかったっけ?
56デフォルトの名無しさん:04/11/10 20:37:20
Win2003 Server以上でMemoryBarrierというキャッシュのフラッシュのマクロがあるのだが、
それ未満のOS(マルチCPUやHyperThreadingなども含めて)ではスレッドの切り替え時には、
同期制御をして書き換えた部分も切り替え後に値が途中までしか変わっていない
ということが有り得るのでしょうか?

通常、小さい変数などはvolatileをつけるべきだってのは知っているのですが、
const_castでvolatileを変える仕様はMS VC7.1には入っていないし、
同期をかけるクラスはすべてvolatile版も作れということですかねぇ。
57デフォルトの名無しさん:04/11/10 21:21:42
>>56
前スレ読め。
58デフォルトの名無しさん:04/11/10 22:04:14
DAT落ちなんですが。
その1にもありますかね?その1読み中。
59デフォルトの名無しさん:04/11/10 22:14:38
にくちゃんねるで拾えば読めるよ
6056:04/11/10 23:22:11
にくちゃんねるでその2だけひっかからず。mimizなんたらも見えず。
その1をよんだところ、マルチスレッドな環境で同期処理用の関数で
制御を行うときにはキャッシュはクリアしていなければ、まともに動作しねぇ。
マルチプロセスじゃ弱いメモリモデルというのになってるらしい。
本でもあさってみますわ
61デフォルトの名無しさん:04/11/10 23:47:02
> MemoryBarrierというキャッシュのフラッシュ
微妙に誤認がある。やはりその2嫁
62デフォルトの名無しさん:04/11/10 23:57:59
>>58
googleのキャッシュとか、archive.orgとか。
6356:04/11/11 06:51:00
google cacheでその2(900ちょい前迄)よんだが、流れがつかみにくい・・・
VC++な俺は_ReadWriteBarrierでreorderされないようにバリアしろ。
Intrinsicな_Interlocked*をつかって、reorderも抑制しろ。
ソース書き直す前に、手持ちの本も読んでみます。
64デフォルトの名無しさん:04/11/13 17:54:55
上手いスレッドレイプのやり方教えてくらさい。
65デフォルトの名無しさん:04/11/13 18:39:17
>>64
君には無理です。氏になさい。
66デフォルトの名無しさん:04/11/13 19:42:36
>>64-65
ここでスレイプの練習するの止めてくれる?
自作自演で煽り煽られの状態に持ち込むのがテクニックの一つだよね?
67デフォルトの名無しさん:04/11/17 14:43:47
Solarisのマルチスレッドプログラムをlinuxに移植しることになったんだけど、
なんか参考になるサイト教えてくださいおながいします。
6867:04/11/17 15:19:35
linuxのThreadライブラリには何種類かあると思うのですがpthreadが無難なんでしょうか?
69デフォルトの名無しさん:04/11/17 15:49:25
>>68
pthreadが無難だと思う
70デフォルトの名無しさん:04/11/17 22:35:10
なんでオライリーのpthread本はイモムシの表紙なんですか?
気持ち悪いです。
71デフォルトの名無しさん:04/11/17 23:01:38
重複スレ立てて並列実行しなくていいの?
72デフォルトの名無しさん:04/11/17 23:19:02
スレの立て方の覚えたての時期は
得意げになってクソスレ立てまくるんだよな
これ、マジでシャレにならんよ
73デフォルトの名無しさん:04/11/18 01:49:27
>>67
kernelのversionは新しくしてね。
古いlinuxthreadは糞だから。pthread互換じゃないから。
74デフォルトの名無しさん:04/11/22 15:04:29
75デフォルトの名無しさん:04/11/23 20:50:21
マルチスレッド プログラムの動作をうまく視覚化するような図法ってあるのでしょうか?
何かありましたらお教えください。お願い致します。
76デフォルトの名無しさん:04/11/23 21:59:08
そういうデバッガはある。
77デフォルトの名無しさん:04/11/24 00:03:04
Java言語で学ぶデザインパターン入門 マルチスレッド編にちょっと図があるけど、
Javaの範囲(モニタ)に特化してるかも。とするとpthreadだと使いにくそうな気がする。
組み込み系の本に載ってるかも…でもスレッドじゃなくて全体が並列に動くからなあ。
78デフォルトの名無しさん:04/11/24 00:12:22
>>75
UML
昔はペトリネット
79デフォルトの名無しさん:04/11/25 11:19:50
現在複数スレッドから共有するメモリにアクセスしたいのですが
メモリにアクセスする時にクリティカルセクションで同期をとっています。
クリティカルセクションEnter状態の時に、子関数を呼んだ場合
子関数が動作中も安全なのでしょうか。
Thread()
{
  EnterCriticalSection();
  Func();
  LeaveCriticalSection();
}

Func()
{
  共有するメモリの編集処理
}
80デフォルトの名無しさん:04/11/25 11:33:43
>>79
安全なのです
8179:04/11/25 12:02:06
>>80
回答ありがとうございました。
82デフォルトの名無しさん:04/11/25 18:57:55
マルチスレッドってそもそもまに?
83デフォルトの名無しさん:04/11/25 19:12:55
一つの掲示板にスレッドがいくつも立てられること
84デフォルトの名無しさん:04/11/28 22:45:24
>>79
他スレッドはEnterCriticalSection()から返ってこない。
動作を見れば簡単にわかるだろうに・・・。
85デフォルトの名無しさん:04/11/29 05:20:34
pthreadで優先度を変えてスレッドを実行するにはどうしたらよいのでしょうか?
86デフォルトの名無しさん:04/11/29 11:58:07
>>85
pthread_setschedparam()
87デフォルトの名無しさん:04/11/30 01:53:04
ネーミングセンスを疑う>pthread_〜
88デフォルトの名無しさん:04/12/09 22:28:24
Linuxで、pthreadを用いたマルチスレッドプログラムを作っています。
pthread_cond_wait関数を用いて待機させ、
pthread_cond_signalやpthread_cond_broadcast関数を用いて
待機スレッドを起こしています。

ここで質問ですが、
ある時点において、待機中のスレッドがあるかどうか、
できればいくつあるのか、を拾う術はあるのでしょうか。
ある待機中のスレッドをpthread_cond_signal関数で起こした際に、
他に待機中のスレッドがあるかどうかで処理を変えたいと思っています。

以上、よろしくお願いします。
89デフォルトの名無しさん:04/12/09 23:08:15
OpenGLでパーティクルとばしたいのだがどうすればよいのでしょう?
90デフォルトの名無しさん:04/12/10 07:34:19
>>88
pthread_*にはないので、その辺のロジックは自分で書く。
91デフォルトの名無しさん:04/12/10 22:44:35
C言語(Solaris)でマルチスレッド初心者向けの本が欲しいのですが、お勧めを教えて下さい。
92デフォルトの名無しさん:04/12/11 00:46:32
英語ならテンプレにあるよ。
93デフォルトの名無しさん:04/12/11 01:01:26
ありがとうございます。でも、出来れば日本語がいいんですけど・・・
94デフォルトの名無しさん:04/12/11 04:53:27
http://www.amazon.co.jp/exec/obidos/ASIN/4756117848/qid=1102708104/sr=1-2/ref=sr_1_10_2/249-8517280-2920313
http://www.amazon.co.jp/exec/obidos/ASIN/4756116825/qid=1102708104/sr=1-3/ref=sr_1_10_3/249-8517280-2920313
下のは持ってるが、ソラリスマンセーでいかにソラリスが素晴らしいか
嫌というほど延々と語っている本だ。訳文は悲惨だし、カナーリ古い内容なので
お勧めはしないけど。どこに住んでるんだ?
都内なら、神保町の三省堂本店に二冊ともあったよ。
95デフォルトの名無しさん:04/12/11 08:40:51
両方ともいい本だ。こういうしっかりした内容のスレッド本は珍しい。
前の本は古いSolairs独自のスレッドAPI。しかし解説が良い。
初心者向けのスレッド概念、マルチスレッド技法から説き明かしてある。

Solarisは8辺りからスレッド内部が結構変っているから、
細かい制御をしたい人は、>>3のSunのPDFを。
96デフォルトの名無しさん:04/12/11 16:26:49
fiberってWinMeじゃ動かんの?
9769式フリーPG ◆hND3Lufios :04/12/11 16:49:01
CreateFiberは98/Meも使えるようだけど。
98デフォルトの名無しさん:04/12/11 17:06:31
>>97
ありがd

あちこち調べまわった結果、95以外は一応大丈夫みたいですのう。

でもfiber関連はドキュメント見ると
>  Windows NT: 3.51 SP3 以降を使います。
>  Windows: サポートされていません。
と書いてあるのが激しく不安
99デフォルトの名無しさん:04/12/11 20:29:28
>>98
Microsoft Platform SDK February 2003から
Client: Included in Windows XP, Windows 2000 Professional, Windows NT Workstation 3.51 SP3 and later, Windows Me, and Windows 98.
10091:04/12/11 21:40:45
>>94
ありがとうございます。今日、神保町で買ってきました。
三省堂には、なかったので書泉グランデで。
101デフォルトの名無しさん:04/12/12 01:49:01
>>88
診断(デバッグ)目的なら、必要な状況は理解できるが

それ以外だとちょっと用途が浮かばない。
だいたい、調べた次の瞬間、待機中のスレッドが待機中かどうかわからんし。

sem_getvalue( )なんかも同じだけどね。
セマフォ値を得たところで、その値を使うころに
値がどうなっているのかわからん。
102デフォルトの名無しさん:04/12/12 02:56:02
>>51
MPICHを入れようね。
SSHかRSHを使えるようにしてね。
複数のコンピュータ上にNFSで同じディレクトリを用意しておいてね。
mpicc hoge.c
mpirun a.out
で実行できるよ。
103デフォルトの名無しさん:04/12/12 10:24:19
>>90
わかりました。
がんがります。

>>101
まさにその通りで、デバッグ用に使おうと思ってました。
printkでどう表示するか、を分けようと・・・。
仰っている懸念は、設計上回避しているつもりではいます。
一旦あるスレッドがpthread_cond_signalで起こされると、
起こされたスレッドでの処理が終わるまではpthread_cond_signalは
呼ばれないようにはしています。
逆に待機スレッドが増えるという可能性はありますが、待機スレッドが
0か0以外かさえわかればいいので無問題です。
というわけでセマフォを使うことにします。
ありがとうございました。
104デフォルトの名無しさん:04/12/12 11:09:01
>>103
表示だけならどうと言うことは無いけど...。

> 一旦あるスレッドがpthread_cond_signalで起こされると、
> 起こされたスレッドでの処理が終わるまではpthread_cond_signalは
> 呼ばれないようにはしています。

スレッドの処理の終了と pthread_cond_signal を呼び出す処理の競合のあたりちと心配。
105デフォルトの名無しさん:04/12/12 19:56:20
pthreadで、あるスレッドが動いているかどうかを調べるにはどうしたらいいのでしょうか。
pthread_createで得られるptherad_tを使って判定する関数がありそうなのですが、
調べたところ見つかりませんでした。
106デフォルトの名無しさん:04/12/12 20:03:01
しかし、そんな難しい使い方しなくてもCSP的な簡単な使い方だけですます
のではだめなの?何も複雑にすることないじゃん。
107105:04/12/12 20:56:07
自己解決です。
1.動いているかどうか判定する変数を用意する。
2.pthread_create()の直前にtrueにする。
3.pthread_create()で設定したデストラクタでfalseにする。
108デフォルトの名無しさん:04/12/13 00:11:08
>>107
テストした瞬間、どうなっているかわからんがな。
109デフォルトの名無しさん:04/12/13 22:03:59
>>107 勝手に自己解決するな!

質問の意味がさっぱりわからん。
pthread_tがあるってことは、それすなわちthreadじゃないのか?
「スレッドが動いている」って何?
110デフォルトの名無しさん:04/12/13 23:55:05
読む気力がないので誰か要約して(w
http://lists.debian.org/debian-devel/2003/04/msg02112.html
111デフォルトの名無しさん:04/12/14 00:47:14
犬板で聞けば?

ざっと読んだところ。

主張
・正式な意味でのi386サポートをやめたい

理由
・gcc3.2以降はi386をサポートしていない(i386では動作しない)
・i486以降に限定すれば、速度の面でかなり有利。カーネルも、ユーザアプリも。
・i386とi486以降を個別にサポートするのは時間の無駄だ。

提案(3案)
・i386とi486以降に分けて、それぞれサポートする
・i386アーキを捨てる。i486という名前のアーキを新たに作成する
・i386の名前のまま、実際はi486以降必須にする

てなところか。酔ってるので間違い勘弁。
112105:04/12/15 13:38:53
>>109
まずメインスレッドがありますよね?これをスレッドAとします。
そしてpthread_createで新しいスレッドを作って動かします。これをスレッドBとします。
Bで何か作業をやらせておいて、AではBが終わった瞬間、Bの計算結果を使った処理をします。
ところがBが終わったという判定をする方法がわからないのです。
それからpthread_joinはAの作業が止まってしまうので使えません。
以下のプログラムで、isfinished()という関数がありますが、
このようにスレッド識別子pthread_tを使ってスレッドの終了を判定したいのです。
113デフォルトの名無しさん:04/12/15 13:39:43
int global_value;

/*スレッドB*/
void thfunc(void *dat)
{
  /*ここでスレッドBの計算を行う
  最終的にglobal_valueに計算結果の値が入る*/
}

/*メイン(スレッドA)*/
int main()
{
  pthread_t th;
  pthread_create(&th, NULL, thfunc, NULL);

  while(1){

    /*あるループを伴う作業*/

    /*Bで計算が終わったか?*/
    if( isfinished(th) ){
      /*global_valueを使う*/
    }
  }
  return 0;
}
114デフォルトの名無しさん:04/12/15 13:49:34
isfinished()は架空の関数です。これに類する関数があると思うのですが、
pthreadのリファレンスには載っていませんでした。
もしjavaが分かるようでしたら、スレッドクラスのisAlive()と同じものと思ってください。
あるいはjavaの場合はjoin()する際タイムアウト時間が設定できるので、
もしCでもそのような方法があるようでしたら、教えてください。
115デフォルトの名無しさん:04/12/16 02:44:40
某サイトでWinSockでサーバーを作る方法について勉強していたら、
「GUI アプリケーションの場合は、プロセスの主スレッドで呼び出さないようにしてください」
と書いてあったのですが、
これはスレッドを作ってそこでやればいいということですか?
116デフォルトの名無しさん:04/12/16 02:59:50
GUIが固まってWindowが再描画されなかったりしても良いなら
単一スレッド上でブロッキングソケットを使っても構わないよ。
117デフォルトの名無しさん:04/12/16 09:00:42
そう。非同期などもあるが。
118115:04/12/16 11:42:48
>>116,>>117
ありがとうございます。
別のスレッド作ってやらないとCUIが固まるんですね。
119117:04/12/16 13:28:42
>>118
Windowsの仕組みを見てみることをお勧めする。
誰がウィンドうを描画してるのか、メッセージキューなどがキーワード
120115:04/12/16 14:35:21
>>119
サーバーとして待機するときにacceptを使った瞬間、
アクセスがあるまで次に進まないので、
ウィンドウプロシージャに送られてくるメッセージなんかも
たまる一方で処理できないということですね?
121117:04/12/16 14:58:13
それでよろし
122105:04/12/16 16:03:11
せっかく説明したのに誰も答えてくれない
(´・ω・`)ショボーン
123デフォルトの名無しさん:04/12/16 16:10:33
>>122
その処理なら condition variable を使えばいいんじゃないの?
なんでわざわざ thread の生存で判断したいのかわからん。
124デフォルトの名無しさん:04/12/16 16:12:04
んー、重要なのは、
「別のスレッドが終了したこと」ではなく、
「別のスレッドで行っている処理が終了したこと」なんでしょ?

だったら、自分で書いたようなフラグを使っての判定で良いと思うんだけど。
125デフォルトの名無しさん:04/12/16 21:22:00
pthread_cond_timedwaitって秒単位、しかも絶対時刻かよ
ダセエな
126デフォルトの名無しさん:04/12/16 22:58:42
は? 第三引数はstruct timespec*なわけだが。
127デフォルトの名無しさん:04/12/16 23:18:23
>>125
An absolute time measure was chosen
for specifying the timeout parameter for two reasons.
First, a relative time measure can be easily implemented
on top of a function that specifies absolute time,
but there is a race condition associated with specifying an absolute timeout
on top of a function that specifies relative timeouts.
128デフォルトの名無しさん:04/12/16 23:19:39
If the thread is preempted between the first statement and the last statement,
the thread blocks for too long.
Blocking, however, is irrelevant if an absolute timeout is used.
An absolute timeout also need not be recomputed if it is used multiple times in a loop,
such as that enclosing a condition wait.
129デフォルトの名無しさん:04/12/17 01:55:39
英語なので翻訳します。(要約しながら)

「マニュアル読め」
130デフォルトの名無しさん:04/12/17 02:19:57
驚愕に値するマヌケ野郎だな
131デフォルトの名無しさん:04/12/17 03:22:41
俺の感覚からすれば、今のケースに「マヌケ」ってのは
どうもしっくりこない。

マヌケ野郎ならなおさら。

なんでだろ
132デフォルトの名無しさん:04/12/17 10:37:17
ノータリンならばよろしいか。
133デフォルトの名無しさん:04/12/17 11:06:25
うすら間抜けがMT-Safe。
134デフォルトの名無しさん:04/12/22 19:31:23
マルチスレッドって難しいな。
whileの無限ループが入ったスレッドを二つ立ち上げるだけで一気にCPU使用率が100%いく。
一つ目ならまだなんとか20%台なんだが。
スレッドってこんなものなのか?
135デフォルトの名無しさん:04/12/22 19:35:24
そんなもんです。
136134:04/12/22 19:45:16
>>135
どうも。
137デフォルトの名無しさん:04/12/22 21:44:12
そりゃビジーループを動かしゃそうなる。
一つで20%しか食わないって方がOSのスケジューラに問題ありそうな。
138デフォルトの名無しさん:04/12/22 21:51:08
キャッシュ溢れなんじゃね?
139134:04/12/23 18:49:07
>>137->>138
どうも。
それから、
同じスレッドを複数呼び出したりしたら、そのスレッド内のローカル変数はどうなりますか?
例えば、 a という数値型変数をローカル変数として宣言してあって、
そのスレッド内で一定時間おきに a の値を一つずつ増やしていく・・・
ということをした場合、このスレッドを2つ3つと走らせた場合に
a の値は・・・?

2倍、3倍になりますか?
それとも各々のスレッド内で独立した変数として通常通り一つずつ増えていきますか?
140デフォルトの名無しさん:04/12/23 19:34:26
Cの場合、static変数は全関数呼び出しインスタンスで共通(共有)、
auto変数は全関数呼び出しインスタンスで別個。
141134:04/12/23 20:06:20
>>140
えっと・・・
ということは、staticをつけずに宣言した場合は別々ということですね。
ありがとうございます。
142デフォルトの名無しさん:04/12/23 21:45:29
>>134

ビジーループには0.1秒、または0.05秒Sleepを置くのが常套手段

143デフォルトの名無しさん:04/12/24 19:21:41
recvfromしてるスレッドを停めるとき
もっともスマートあるいはエレガントで
標準的な方法は?
144デフォルトの名無しさん:04/12/24 19:23:55
lockを使った排他による停止。
145デフォルトの名無しさん:04/12/24 20:09:06
socketをclose
146デフォルトの名無しさん:04/12/24 20:27:04
psしてkill
147デフォルトの名無しさん:04/12/24 20:27:38
syncしてsyncしてsyncしてhalt
148デフォルトの名無しさん:04/12/24 20:30:32
アアナルほど。
失敗終了させればいいのか。


終了フラグ立ててダミーパケットを送ってみたりしてたんだが、
何か随分無駄っぽい気がしてたんだよな。
「パケットとりこぼしたらやだな」ってのもあったし。

最初、終了フラグに揮発性を設定し忘れてたし。
149デフォルトの名無しさん:04/12/24 20:31:44
pthread_kill()でEINTRを起こす。
150デフォルトの名無しさん:04/12/24 23:18:13
>同じスレッドを複数呼び出したりしたら、そのスレッド内のローカル変数はどうなりますか?
>例えば、 a という数値型変数をローカル変数として宣言してあって、
>そのスレッド内で一定時間おきに a の値を一つずつ増やしていく・・・
>ということをした場合、このスレッドを2つ3つと走らせた場合に
>a の値は・・・?

すいません、139じゃないんですけど、ちょうど悩んでたんで便乗でおしえてください。
上記の139さんの質問、Cの場合は答えて頂いてますが、Delphiだとどうなるでしょうか?

さらに上の例で言うと、aがローカルではなく、スレッドのpublicなメンバーだったらどうなるでしょうか?
151デフォルトの名無しさん:04/12/24 23:54:08
「スレッドのpublicなメンバー」って何やねん。
152デフォルトの名無しさん:04/12/25 00:05:20
>>151
TThreadから派生させて作ったクラスのpublicメンバ変数ってことです。
こんな感じ。
type
TMyThread = class(TThread)
private
{ Private 宣言 }
public
a: integer;
protected
procedure Execute; override;
end;
153デフォルトの名無しさん:04/12/25 00:12:37
Delphi付属のサンプルコードに、スレッドを複数立ち上げてソートするコードなかったか?
154150:04/12/25 00:15:56
すんません、6Personalなんですが、サンプルコードついてないっぽいです...
155デフォルトの名無しさん:04/12/25 00:36:01
scheme(scm)でスレッドを実装したいときはどうすればいいのですか?
make-engineがそれにあたるのでしょうか…
156デフォルトの名無しさん:04/12/25 00:41:03
>>152
グローバル変数と一緒。
157デフォルトの名無しさん:04/12/25 00:46:25
>>156
回答ありがとう。
しかし...グローバルと一緒ですか...
Priveteならたぶんスレッド内で独立した変数になるんだろうけど、メインのフォーム
から操作する必要あるんですよねえ。
publicな手続きつくってその中でaを操作すればいいのかな。
158デフォルトの名無しさん:04/12/25 00:50:57
>>157
御免、言っている意味がよくわからない。
スレッドローカルな変数で、グローバル変数とローカルな変数の中間。
生存期間: そのスレッドが終了すると(TThreadが消えると)なくなります。
アクセス: パブリックなので、アドレス分かればどこからでもアクセス可能。
159デフォルトの名無しさん:04/12/25 00:52:06
で、スレッド毎に確保。
そのスレッドから見ればグローバル変数と一緒。
160157:04/12/25 14:54:06
なるほど、スレッドローカルな変数ですね。説明ありがとう。
僕も最初そうかと思ったんですけど、実際に動かして見るとどうも動きがちがうのよねえ。

152であげた例でいうと、メインフォームのほうでこいつのインスタンスを二つ作って

Thread1:=TMyThread.Create(False);
Thread2:=TMyThread.Create(False);

でaを操作する。

Thread1.a:=1;

TMyThreadのExecuteでaを監視してるんですが、これやると、なぜかThread2も
反応してしまうんですよ...

どこが間違ってるんでしょうか。ご指導お願い致します
161デフォルトの名無しさん:04/12/27 23:56:30
TMyThread のインスタンスはメインスレッドでつくられるんだから、単なるフィールド変数だろ
162デフォルトの名無しさん:04/12/28 10:56:51
これデルファイ?C++ならメモリアドレス見れば一発なのに
163デフォルトの名無しさん:04/12/28 22:27:56
>>160
スレッドローカルだからでは?
もう自分でも何をしたいのか、よくわかっていないでしょ?
164157:04/12/28 23:38:05
皆さんコメント感謝
163さん言うとおり、相当煮詰まってあれこれ試しているうちに
何がなんだか混乱していたのも事実です。

aをpriveteに移して、aをメインスレッド側からいじらないように改造
したら誤動作なくなりました。
正直言うとまだ明確にはわかっていません。

あまりプログラミングの知識ないのですが、最初ごく単純なツール
の予定だったので私でもできるかなと引き受けたのですが、あれよ
あれよと機能追加要求が来て大変です。
でもまあ、あれこれ迷いながら楽しんで仕事できてます。

とりあえず変数の種類とスコープを復習しなおすことにします。
ありがとう。
165デフォルトの名無しさん:05/01/14 07:34:30
超高速で操作するとなんかスタックが壊れる・・・
「無効なアンワインド対象がアンワインド操作で検出されました。。」
ってなんやねんわけわかめ!わけわか!
166デフォルトの名無しさん:05/01/14 08:31:34
スタック壊れてるのはたいてい自分でメモリを壊してるせい
167デフォルトの名無しさん:05/01/16 11:34:13
>>165
「アンワインド」の意味は分かっているの?

スタック上のアンワインド用のメタデータが壊れているんでしょう。
それが餡ワイン度している時に見つかったと。
168デフォルトの名無しさん:05/01/16 14:27:02
うへぇ、不味そう<餡ワイン
169デフォルトの名無しさん:05/01/19 13:16:21
クリティカルセクションオブジェクトのLockCountが-1でOwningThreadもNULLで
どこもロックしてないのにLockSemaphoreだけロックされててわけわかめ。なんじゃこれ
もう疲れた
170デフォルトの名無しさん:05/01/23 22:50:00
スレッドの生成や消滅って、implicitなmemory barrierになると考えて良いのでしょうか?
#POSIX, Win32両方使ってます。
171デフォルトの名無しさん:05/01/24 13:58:45
状況がつかめん。
コードで示せ。
172170:05/01/24 14:58:01
メインスレッドが大域変数gFooに1を、排他制御なしで書く

メインスレッドがスレッドTを生成する

TがgFooの値を排他制御なしで読む

の順で処理が発生したとき、Tが観測するgFooの値が1であることが保証されているかが知りたいです。
メインスレッドは1を書いた後、当面gFooにアクセスしないと仮定してOKです。

よろしくおながいします。

173デフォルトの名無しさん:05/01/24 16:33:36
>>172
環境によっては保証されない。
何故ならば、大域変数へのアクセス完了を待ってスレッド生成する保証がないから。
174170:05/01/24 18:28:24
>>173
> 環境によっては保証されない。
> 何故ならば、大域変数へのアクセス完了を待ってスレッド生成する保証がないから。

gFoo = 1;
// ここ
pthread_create();

というコードで、「ここ」と書いたところはsequence pointで、かつ「ここ」ではまだシングルスレッド
状態なわけですが、それでも「大域変数へのアクセス完了を待つ」が保証されないのでしょうか?

>> スレッドの生成や消滅って、implicitなmemory barrierになると考えて良いのでしょうか?
という質問に戻ってしまうわけですが・・。
175デフォルトの名無しさん:05/01/24 18:52:29
そのコードなら確実に1は保証されるぞ。
1の代入が完了しなければスレッドが作られないんだから。
1の代入とスレッド作成は同一スレッドで行われるわけだからね。
176デフォルトの名無しさん:05/01/24 18:56:38
>>175
前スレの最後の方とか http://www.nwcpp.org/Downloads/2004/DCLP_notes.pdf を見た上でもそう思う?

177デフォルトの名無しさん:05/01/24 19:09:38
アセンブラのレベルで、同一スレッドでmov命令(1代入)発行した後に関数コール(pthread_create)
する場合でも、movが完了する前にpthread_createされることって有り得るの?
そういう話ではないよね?コンパイラのオプティマイザによって変わってくるということかね?
178デフォルトの名無しさん:05/01/24 19:11:43
Pentium4とかの最近のCPUだと有り得る
179デフォルトの名無しさん:05/01/24 19:13:19
コンパイラのオプティマイズ(命令のreorder)の話もあるけど、それに加えて、
・コンパイラがreorderしなくても、CPU(H/W)が命令をreorderするかもしれない
・あるCPUでmovが完了したからといって、その値が別のCPUから観測可能かはわからない
ということでは?
180デフォルトの名無しさん:05/01/24 19:20:28
どうも。勉強不足でした。恥ずかしい。
前スレッドを見たいが見られない。困った。
181デフォルトの名無しさん:05/01/24 19:23:32
>>180
memory barrierでググればそれ関係の論議は大抵見つけられると思う。
182170:05/01/24 19:33:12
pthread_createやCreateThreadの先頭にmemory barrier(full fence)が挿入され
ているのか、挿入するよう規格が要請しているかが知りたいです。

#またはfenceなどなくても大丈夫というならその理由を
183デフォルトの名無しさん:05/01/24 20:19:01
volatile
184デフォルトの名無しさん:05/01/24 20:22:17
またvolatile厨か・・・
185デフォルトの名無しさん:05/01/24 21:19:14
total store order
186デフォルトの名無しさん:05/01/24 21:22:38
またtotal store order厨か・・・
187デフォルトの名無しさん:05/01/24 21:24:35
>>185
詳しく
>>186
ポカーン
188デフォルトの名無しさん:05/01/24 21:24:42
どうでもいいじゃん
189デフォルトの名無しさん:05/01/24 21:25:48
スレッドセーフなライブラリつかっとけばOK
190170:05/01/24 21:39:43
>>185
> total store order
すみません、memory modeに疎く、TSOだけだとちょっと意図が汲めません。結局>>172の例は
safe/unsafeどちらだとお考えでしょうか?



191170:05/01/24 21:40:28
mode -> model
192デフォルトの名無しさん:05/01/24 21:54:32
>>170
volatile とか VC/VC++ の _ReadWriteBarrier とかその辺の問題はともかく、
MSのサンプルでも、Win32のThreadProcで、渡されたデータ、実体はポインタ、
が挿すメモリアクセスするような場合にMemoryBarrier()呼び出しをしている例は
一度も見たことなく、逆の例は沢山あるので、
Win32のCreateThreadはメモリバリアになってるような気がします。

具体的なドキュメント等の記述は見つからないけど。
193デフォルトの名無しさん:05/01/24 21:55:20

編集していたらなんか「、」が多くて変な文になってしまった。
194デフォルトの名無しさん:05/01/24 22:04:25
この名前空間、クラス、およびメンバは、.NET Framework Version 1.1 だけでサポートされています。
195デフォルトの名無しさん:05/01/25 00:30:21
>>170
POSIXではpthread_create()もpthread_join()もMemory Synchronizationが
要請されてますな。
ttp://www.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap04.html#tag_04_10
196170:05/01/25 12:12:35
>>192, 195
ありがとうございます!!
スッキリ解決です。

197デフォルトの名無しさん:05/01/25 22:20:49
このスレでvolatileって言葉が出てきたらほぼ100%厨房な間違いってことでFA。


198デフォルトの名無しさん:05/01/25 23:09:05
つまり
>>56, >>183, >>184, >>192, >>197
はほぼ100%厨房な間違いってことでFA。
199デフォルトの名無しさん:05/01/25 23:09:07
volatileはthreadじゃなくてinterruptのときのモノだしな。
200デフォルトの名無しさん:05/01/25 23:34:26
またvolatile厨か・・・
201デフォルトの名無しさん:05/01/26 00:34:16
>199
ISO C/C++的にはシグナルハンドラからアトミックに更新したい変数に用いる型、だね。
volatile sig_atomic_t。この使い方以外でvolatileって語は出てこないし。

あーあと、POSIXにはまったく登場しないね。
202デフォルトの名無しさん:05/01/26 00:36:59
>>198
56はリア厨だったりする罠。

>通常、小さい変数などはvolatileをつけるべきだってのは知っているのですが、
必要ありません。

>const_castでvolatileを変える仕様はMS VC7.1には入っていないし、
>同期をかけるクラスはすべてvolatile版も作れということですかねぇ。
CRITICAL_SECTION使え
203デフォルトの名無しさん:05/01/26 14:01:57
またvolatile厨か・・・
204デフォルトの名無しさん:05/01/26 15:27:42
またvolatile厨か・・・
205デフォルトの名無しさん:05/01/26 17:22:23
またvolatile厨か・・・
206デフォルトの名無しさん:05/01/26 19:04:35
またvolatile厨ですね・・・
207デフォルトの名無しさん:05/01/26 19:13:18
(またvolatile厨)厨ですよ・・・
208デフォルトの名無しさん:05/01/26 19:14:25
((またvolatile厨)厨)厨ですよ・・・
209デフォルトの名無しさん:05/01/26 19:58:21
こんな(((volatile厨)厨)厨)厨見たことない・・・
210デフォルトの名無しさん:05/01/26 20:36:31
こんなところで三段落ちを見るとは…さすがvolatile厨だな
211デフォルトの名無しさん:05/01/27 00:31:20
来たれ、void厨!
212デフォルトの名無しさん:05/01/28 00:28:17
ということにしたいのですね。
213デフォルトの名無しさん:05/01/28 02:46:28
取り込み中済まないんだけど、mutex で待たないで条件変数で待たなきゃいけない場合って
どんな時ですか? 長い時間掛かる処理を待ってる時は、条件変数使った方が良いみたいですが。

ググったら見つかったとこ。

ttp://www.imou.to/~AoiMoe/column/pthread/pthread_cancel.html

これは、絶対に mutex で待っちゃダメって事じゃないですよね。
214デフォルトの名無しさん:05/01/28 03:08:46
>>213
condition variableで待つ場合ロックしているmutexを一時的に
解放してくれて、かつ、signalやbroadcastで条件が調った時に
一時的に解放していたmutexを自動的にロックしてくれる。
なので、時間とかの問題ではなく、デッドロックを避けつつ、
必要な排他処理を過不足無く行なうために必要であれば、
condition variableを使うか、自前で同等の処理を行なうことに
なる。
mutexをロックしたまま別のmutex待ちをして良いのなら、
condition variableを使う必要は無い。
215デフォルトの名無しさん:05/01/28 03:38:10
>>214
どうもありがとうございます。

自分が考えていたのは、mutex が一時的に解放されてもそれほど嬉しく無さそうな
処理だったので、まずは mutex のみで実装してみようと思います。
216デフォルトの名無しさん:05/01/30 17:49:59

volavolavolavolavolavolavolavolavolavolaァァァァーー!
217デフォルトの名無しさん:05/01/30 18:28:51
intサイズ以下なら、volatileつければ、
マルチスレッドのときにも排他は不要ですよね?
218デフォルトの名無しさん:05/01/30 18:31:21
そうですね
219デフォルトの名無しさん:05/01/30 18:35:10
>>217
へ?
220デフォルトの名無しさん:05/01/30 18:57:20
CCSを使ってモデル化して検証する
>>217
不要だと思うなら、そうすればいい。

後で泣きを見ても知らんけどな。
222デフォルトの名無しさん:05/01/30 21:18:59
>>221
100%煽りでしょ。
せっかくの「またvolatile厨か・・・」への前振りを無駄にするな。
223デフォルトの名無しさん:05/01/31 11:01:30
またvolatile厨か・・・
224デフォルトの名無しさん:05/01/31 19:34:43
またvolatile厨厨か・・・
225デフォルトの名無しさん:05/01/31 23:11:21
coutを複数スレッドから利用する場合改行までの間で出力が混ざってしまうのは、
下記のページみたいな感じでmutexやクリティカルセクションを使ってロックするしかないの?
なんか重そうだけど。
http://www.athomejp.com/goldfish/mfc/cobject/thread.asp
226デフォルトの名無しさん:05/01/31 23:41:26
心配しないでもI/Oの方が遅い。
stringstreamの場合は工夫した方がいいと思うが。
227デフォルトの名無しさん:05/02/02 23:23:58
クリティカルセクションならカーネルレベルまで話が及ばない(ほとんどのばあい)
から重くないと思われ。
228デフォルトの名無しさん:05/02/03 01:12:21
どっちもI/Oの重さを考えたら無いようなもん。
応答性やパフォーマンスを気にするならcoutなんかやめて
非ブロッキングI/Oを使えばいい。
229デフォルトの名無しさん:05/02/03 10:36:44
キタ━━━━(゚∀゚)━━━━!! @cppll ML

>επιστημηです。
>
>で、関連事項なんすけど、スレッド間で共有する変数の類は
>Mutexなんかでガードしてないならvolatileつけとくのが無難
>なんでしょかしらやっぱ?

えぴすさんでもひっかかっちゃうのね。
230デフォルトの名無しさん:05/02/03 12:09:18
>>229
「でも」とはなんだ「でも」とは!
奴だからこそ、だろう。
231デフォルトの名無しさん:05/02/03 12:17:26
レスはもっと香ばしいけどね。レジスタがどーたらとか。
232デフォルトの名無しさん:05/02/03 12:50:58
>>229の文章ならそんな問題ないでしょう?

排他のためにやるわけじゃなくて、
最適化の抑止の事だけを話しているのかも知れないから。
十分って言っているわけじゃなくて、無難だしね。まあ、

>で、関連事項なんすけど、

何に関連していたかにも依るわけですが…
233デフォルトの名無しさん:05/02/03 13:01:08
constと同じとこにvolatileやconst volatileも書けるっていうお話でしたとさ。
234デフォルトの名無しさん:05/02/03 21:34:24
>>232
> 排他のためにやるわけじゃなくて、
> 最適化の抑止の事だけを話しているのかも知れないから。
排他が関係しないスレッド間の共有って、全スレッドがreadしかしないとかそういうこと?
確かにそれなら定数読むのとかわらんから、volatileもメモリバリアもいらないけど、そういう文脈なのかなぁ。
235デフォルトの名無しさん:05/02/04 01:21:32
しかし、最近そこかしこでmutexのかわりに/mutexに加えてvolatileって騒いでる人を見かけるんだけど
国内でだれかvolatileを布教してる人でもいるんですか?
236デフォルトの名無しさん:05/02/04 05:57:04
またvolatile厨厨か・・・
237デフォルトの名無しさん:05/02/04 06:10:36
coutを複数スレッドから利用する場合改行までの間で出力が混ざってしまうのは、
下記のページみたいな感じでmutexやクリティカルセクションを使ってロックするしかないの?
なんか重そうだけど。
http://www.athomejp.com/goldfish/mfc/cobject/thread.asp
238デフォルトの名無しさん:05/02/04 08:26:34
>>237
思い込みはどうでもいいからベンチマークとれよ
239デフォルトの名無しさん:05/02/04 09:00:25
スレッドプログラミング初心者です。
volatileはマルチスレッド対応ですか?教えてください。
240デフォルトの名無しさん:05/02/04 09:10:22
>>237
coutをvolatileにしろ
241デフォルトの名無しさん:05/02/04 09:23:38
アプリケーションがシングルスレッドである間しか書き込みしない事が分かっている場合
(スレッドが2つ以上になった時点では読込しか行わない場合)
排他処理したり、volatile修飾する必要は無いの?
242デフォルトの名無しさん:05/02/04 09:42:47
>>241
またvola (ry

えーとね、排他は必要ない。169-170の質問と実は同じ内容だから、
回答は >>192 >>195 を参照のこと。

あと、volatileはいい加減やめい。スレッドとvolatileは無関係。
243デフォルトの名無しさん:05/02/04 20:15:08
ボラボラボラボラボラボラボラボラボラタイール!
244デフォルトの名無しさん:05/02/04 22:16:44
volatileってコンパイラの想定外の理由で変数の内容が変わるので最適化の対象にしないでくれって宣言だよね?
245デフォルトの名無しさん:05/02/04 22:22:00
>>244
ウザい
246デフォルトの名無しさん:05/02/04 22:26:20
bool型の値に書込と読込を色々なスレッドから同時にするような場合排他をしない場合は、
trueに変えたはずなのにまだfalseと読み出されたりするくらいで、
いきなりスレッドが死んだりする事は無いよね?
247デフォルトの名無しさん:05/02/04 22:39:07
>>245
お前がな。
そもそもこのスレでのvolatile発言はすべて煽り。ほいほい釣られるのはやめてくれ。
248デフォルトの名無しさん:05/02/04 23:12:27
>>247
お前がな。
そもそもこのスレでのvolatile発言はすべて煽り。ほいほい釣られるのはやめてくれ。
249デフォルトの名無しさん:05/02/05 01:22:51
volatileにしてから、女の子にもてもてです。
250デフォルトの名無しさん:05/02/05 02:14:05
>>246
volatileと宣言すれば完璧です。
251デフォルトの名無しさん:05/02/05 02:43:57
volatileって飛びますよね
252デフォルトの名無しさん:05/02/05 15:08:47
volatileほいほい状態のなか申し訳がないのだが、c/c++のvolatileと
java/c#のvolatileは意味合いが違うという理解でいいのでしょうか?
普通のブラウザからなので過去スレッドに既出ならすまそ。
253デフォルトの名無しさん:05/02/05 16:13:11
同じ
254デフォルトの名無しさん:05/02/05 16:53:32
>>252
c/c++の言語仕様にはマルチスレッドとvolatileとの関係なんて定義されていない。
きちんと定義されているものと未定義のものとを比較して、
意味合いが違うとかどうとか言うのは意味がない。
255デフォルトの名無しさん:05/02/05 17:00:36
bool f;//global

while (f)
{
;
}

は最適化で

if (f)
{
for(;;) {}
}

になったりはしないの?
256デフォルトの名無しさん:05/02/05 17:10:58
>>255の言いたいことがわかる人いる?
257デフォルトの名無しさん:05/02/05 17:15:29
>>256


コンパイル時の最適化についての話でしょう。
前者の記法は後者の記法のように変換されて解釈されるのではないか、
という質問だと思います。
258デフォルトの名無しさん:05/02/05 17:59:55
>>254
>c/c++の言語仕様にはマルチスレッドとvolatileとの関係なんて定義されていない。
ありがとう。なんかすごく腑に落ちました。
現実には独自仕様などでそれなりの関係で動いちゃう処理系が多々あるってことで
しょうね。混乱するほうが自然なような気もしてきました。
259デフォルトの名無しさん:05/02/05 18:12:37
>>257
今でも最適化でこんな間違いが生じる恐れあるのか?
260デフォルトの名無しさん:05/02/05 18:34:22
int f = 1;
while (f) {
/* ループ中でfは参照されない */
}

こういうコードなら、それに近い最適化される
可能性もあるんじゃない?
261デフォルトの名無しさん:05/02/05 20:40:40
ていうかね、例えば
void f(const char *str) {
 int i;
 for (i = 0; i < strlen(str); ++i) {
  ...
 }
}
なんてコードは、
慣れてる人が見れば「毎回長さを判定している糞コード」なわけだけど
VCとかだと、このstrlenをループの外に出しちゃうわけよ。

こういう最適化をするコンパイラが
ループ内で変更していない変数の値を、ループ時に毎回評価するなんてありえないわけで。
262デフォルトの名無しさん:05/02/05 20:51:20
> VCとかだと、このstrlenをループの外に出しちゃうわけよ。

はつみみです
263デフォルトの名無しさん:05/02/05 21:44:43
ループじゃないけど,最適化に関係することでこんなのがあります.
http://www.microsoft.com/japan/msdn/library/default.asp?url=/japan/msdn/library/ja/jpdncode/htm/secure10102002.asp?frame=true&hidetoc=true
264デフォルトの名無しさん:05/02/05 23:29:58
>>262
VCについては知らんが、gccだとpureアトリビュートってのを
関数に宣言してやると、そういう動作をするな。

以下、Infoより引用。
---
`pure'
Many functions have no effects except the return value and their
return value depends only on the parameters and/or global
variables. Such a function can be subject to common subexpression
elimination and loop optimization just as an arithmetic operator
would be. These functions should be declared with the attribute
`pure'.
265デフォルトの名無しさん:05/02/05 23:43:07
>>264
pureって意味わかりにくね?
C++の純粋仮想関数を想像しちまう。

Oracle PL/SQLのdeterministicの方がいいな。
266デフォルトの名無しさん:05/02/06 00:05:45
267デフォルトの名無しさん:05/02/06 04:49:58
結局どうなんですか?
268デフォルトの名無しさん:05/02/06 09:14:47
volatileとつければ完璧です。
269デフォルトの名無しさん:05/02/06 10:48:37
volatile相談室に改名したら?
270デフォルトの名無しさん:05/02/07 09:07:40
volavolavolavolavolavolavolavolavolavolaァァァァーー!
271デフォルトの名無しさん:05/02/08 01:04:08
ごまかして終わりですか?しょせん2chですもんね。
272デフォルトの名無しさん:05/02/08 03:51:12
volatile宣言はコンパイラの吐くコードの最適化を抑制します。

そのことと、マルチスレッドプログラミングがどう絡むのかというと、
最適化を抑制することが、
マルチスレッドプログラミングにおいて発生する問題を解決したり、
未然に防いだりするのに有効な場合があるのです。

もちろん、volatileの使用は、起こりうる問題の全てを解決したり、
予防したりするものではありません。そとのきは、
mutexを使うなりして別の手段を用いる必要があるでしょう。
273272:05/02/08 03:58:21
そとのときは...云々は、
そのときは の誤りです。スレを汚してごめんなさい。

274デフォルトの名無しさん:05/02/08 04:09:37
そとのときはそのときはのあやまりですはそとのきはそのときはのあやまりですのあやまりです
275デフォルトの名無しさん:05/02/08 04:17:12
早口言葉?ちょっと笑えた。
276272:05/02/08 04:46:42
あ...

誤)そとのとき
正)そのとき

ではなくて、

誤)そとのき
正)そのとき

だと指摘してるのかな?
2重にスレを汚してごめんなさい。
277デフォルトの名無しさん:05/02/08 09:24:29
ま た v o l a 厨 か

「場合がある」程度で使われちゃ迷惑なんだよ
つか仕組を理解していない証拠だ
278デフォルトの名無しさん:05/02/08 09:46:40
だーかーらー、volatileとmulti-threadは関係無いっての。
279デフォルトの名無しさん:05/02/08 10:35:50
>>272
i = i++; 並みの珍説だな
280デフォルトの名無しさん:05/02/08 11:03:11
http://www.microsoft.com/japan/msdn/library/default.asp?url=/japan/msdn/library/ja/vclang/html/_langref_volatile.asp?frame=true&hidetoc=true

に,

One use of the volatile qualifier is to provide access to memory locations used by
asynchronous processes such as interrupt handlers.

って書いてあるんだけど...
さらには,

http://www.microsoft.com/japan/msdn/library/default.asp?url=/japan/msdn/library/ja/vclang/html/_pluslang_const_and_volatile_pointers.asp?frame=true&hidetoc=true

では,

When a name is declared as volatile, the compiler reloads the value from memory
each time it is accessed by the program.
This dramatically reduces the possible optimizations.
However, when the state of an object can change unexpectedly,
t is the only way to ensure predictable program performance.


とあります.
少なくともVC++の場合は(気をつければ)volatile使うのもありなのでは?
もちろん,C++の規格上は,マルチスレッドとvolatileの関係なんか何も定められていないと思うけど.

親の敵がごとくvolatileを嫌っている理由を知りたいです.
281デフォルトの名無しさん:05/02/08 11:31:05
マルチスレッドでの同期とはアクセスタイミングの問題ではないから、
volatileは何の解決にもならないんだよ。
volatileで解決したように見えるものを別のところに持っていって正しく
動く保証は全くない。

自説に固執する前にちっとは勉強したらどうよ。
282デフォルトの名無しさん:05/02/08 11:43:37
言語の規格で定められていない以上,VC++で動いたからって,
他の環境でも正常に動作するとは限らないというのは全く同意です.
正直にいうと,マルチスレッドプログラミングはWindows上でしか
経験がありません.それで,

>> 自説に固執する前にちっとは勉強したらどうよ。

自説に固執しているつもりもありませんが,
勉強する意欲はありますので,よろしければ,

>> volatileは何の解決にもならないんだよ。

ということを学習できる書籍,URLなどをご紹介ください.
英語でもかまいません.
283デフォルトの名無しさん:05/02/08 12:04:03
Memory Mapped I/O 以外に volatile を使う必然性が解らん…
Atomic じゃない処理でアクセスしてるなら、気休めにもならんぞ。
284デフォルトの名無しさん:05/02/08 12:26:35
>>283
> Memory Mapped I/O 以外に volatile を使う必然性が解らん…
> Atomic じゃない処理でアクセスしてるなら、気休めにもならんぞ。
cppllの受け売り?mmapでもvolatileはまずい。
285デフォルトの名無しさん:05/02/08 12:27:18
あ...私もところかまわずvolatile使いまくってるわけじゃないです.

例えば,
bool 型の変数(初期値false)があって,ある一つのスレッドが,
その値をtrueに変更し,他のスレッドは,その変数の値が
trueになるのを待ち構えている...的な状況に使っています.

同期オブジェクト使えばいいじゃん.と思われるかもしれませんが,
例えば,上のbool型の変数がグローバル変数であった場合,
単純に同期オブジェクトに置き換えることも出来ません.
初期化の問題もあるし,それをクリアしてもリソースをいつ
OSに返せばいいかという問題もあります.

より具体的には,
http://www-6.ibm.com/jp/developerworks/java/040416/j_j-jtp02244.html
の後半にある,
「リスト1. volatileフィールドを「見張り」変数として使う」
的な利用の仕方をしています.

上記サイトは言語がjavaですし,古いjavaのメモリ・モデルでは,
最適化のリオーダの定義が甘く,うまく動かないと結論づけらているので,
あんまり適切なソースではありませんが,私が提示できるのはこれくらいです.
286デフォルトの名無しさん:05/02/08 12:27:56
>>280
such as interrupt handlers.

でしょ?MSもスレッドとの相互作用は言及していないやん。
287デフォルトの名無しさん:05/02/08 12:28:37
まだ言語の規格うんぬん言ってるよこの人……。
288デフォルトの名無しさん:05/02/08 12:29:36
>>285
>bool 型の変数(初期値false)があって,ある一つのスレッドが,
>その値をtrueに変更し,他のスレッドは,その変数の値が
>trueになるのを待ち構えている...的な状況に使っています.
残念ながらダメな使用例の典型です。
http://www.aristeia.com/Papers/DDJ_Jul_Aug_2004_revised.pdf
289デフォルトの名無しさん:05/02/08 12:36:01
ソースコード中にvolatileなんてDOS時代で割り込み使うときに書いただけだな。

>>285
変数の操作前後に同期オブジェクト使用。
290デフォルトの名無しさん:05/02/08 12:42:43
>>285
> 例えば,
> bool 型の変数(初期値false)があって,ある一つのスレッドが,
> その値をtrueに変更し,他のスレッドは,その変数の値が
> trueになるのを待ち構えている...的な状況に使っています.

バカの典型例。

> 同期オブジェクト使えばいいじゃん.と思われるかもしれませんが,

いいじゃん、じゃなくてそれが正しい解。

> 例えば,上のbool型の変数がグローバル変数であった場合,
> 単純に同期オブジェクトに置き換えることも出来ません.
> 初期化の問題もあるし,それをクリアしてもリソースをいつ
> OSに返せばいいかという問題もあります.

単なる言い訳。
291デフォルトの名無しさん:05/02/08 12:51:18
>>284
cppll ってのが何か知らんが、Mapped Memory の話なぞしていない。
メモリ空間に配置された I/O ポートの話。

>>285
うむ。最悪な用途だな。
>同期オブジェクト使えばいいじゃん.と思われるかもしれませんが,
使えばいいじゃん。
292285:05/02/08 12:54:04
>>288
ソースの提示ありがとうございます.
早速読んでみます.

> 残念ながらダメな使用例の典型です。

でも,ちょっとショックです.
285の使用例を許すOS自体が存在しないということなら,さらにショック.
293デフォルトの名無しさん:05/02/08 13:02:24
>>292
> でも,ちょっとショックです.
> 285の使用例を許すOS自体が存在しないということなら,さらにショック.
OSっつーかハードウェアとコンパイラね。

(1)シングルコアのシングルCPUの上でしか動かさないプログラムか、
マルチプロセッサだけど強いmemory consistencyを持つハードウェア上でしか動かさないプログラムで、

かつ、

(2)コンパイラの最適化の特徴を完璧に把握している

場合のみboolをロックなしで使用してよし。実質的に常人には判断不可能とおもうが。
特に(2)はコンパイラの作者でもなければわからない悪寒。
294285:05/02/08 13:21:24
>>293
解説ありがとうございます.
pdf,まだ読んでませんが,困難さが伝わってきました.

285のような場合は,Windowsの場合ですと,
boolをlongにして,InterlockedExchangeみたいな
API を使っても無駄なあがきでしょうか?
295デフォルトの名無しさん:05/02/08 13:30:57
固執しまくってるやん。
296デフォルトの名無しさん:05/02/08 13:40:08
>>285 の“trueになるのを待ち構えている”が
ビジーループだったりすると、volatile 以前の問題だったり。
297デフォルトの名無しさん:05/02/08 13:47:42
>>294
http://msdn.microsoft.com/library/en-us/dllproc/base/interlockedexchange.asp
などをみると、This function generates a full memory barrier (or fence) and performs ... とかなんとか
説明がある。この意味が分からないなら手を出さない方がいい。
298デフォルトの名無しさん:05/02/08 13:51:53
>>294
InterlockedXXXはもちろんOKでそ。
基本的にはマルチプロセッサを考えない場合にはスレッド間でのメモリ内容の
同期化は考えなくても良いので、volatile とか _ReadWriteBarriar (VCね)とかで
テキトーに済ませてしまっても問題ない。

でも今時「マルチプロセッサではデッドロック起こします」なんてプログラムは
書かないことが多いんでは?なので他のスレッドが書いたデータを読むとき
には、適当にメモリバリアになる処理を入れておくべき(ドライバ書いているとき
には、リングバッファ - メモリモデルの問題さえなければ、writerとreaderは
並行して動作しうる - とかではまることがある)。

あとJava VMの場合は新し目のJSR-000133 に準拠したものだと、
同じvolatile変数へアクセスするコンテキスト間ではアクセス時点で同期化が
成されるみたいだけど、これはまだ一般的じゃないと思う。
299デフォルトの名無しさん:05/02/08 13:56:34
>>298
コンパイラの最適化によるトラブル@シングルプロセッサは無視ですか?
300デフォルトの名無しさん:05/02/08 15:44:47
変数の領域が最適化によってレジスタに作られた場合、別のスレッドがこれを参照することの影響ってあるんですか?
301デフォルトの名無しさん:05/02/08 15:54:06
>>300
お前が意味不明。
302デフォルトの名無しさん:05/02/08 16:26:36
>>300
そのためのvolatileでしょうが。

#って書くとまたvolatile厨云々書く香具師が沸くのかな?
303デフォルトの名無しさん:05/02/08 16:28:15
>>299
既出の、
 Javaの場合普通JSR-133を仮定しないで同期化でメモリバリアするから問題起きない。
 サーバ側などVM限定で良くて高速処理が必要なら、JSR-133を仮定して高速な実装を使うこともアリ。

 C/C++ならvolatile とかVCの_ReadWriteBarrier(>>298ではスペルミスしてました)みたいなものでテキトーに。
 (インラインでアセンブラ書ける処理系なら、大抵はメモリへの配置と値のストアを強制できると思う)
 参考:http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclang/html/vclrf_ReadWriteBarrier.asp

ってようなことの他に何か最適化によるトラブルがあったら教えてください。
304デフォルトの名無しさん:05/02/08 16:53:58
>>302
外から参照できるような変数がレジスタに割り付けられるような
間抜けなコンパイラが存在するんですか?そりゃすげぇや。
305デフォルトの名無しさん:05/02/08 16:56:01
>>304
ごく普通にある。例:GCC
306デフォルトの名無しさん:05/02/08 17:01:12
>>304
C/C++ではvolatileでメモリへの割付は強制できるけど、Javaとは違って当該のメモリ位置に
何時データを書き出すかまでは指定できない(読み出しは字面上の位置でメモリから読むこと、
と規定されてるけど)。

んだからさんざ既出の様に「VCの_ReadWriteBarrierみたいなもの」を併用する必要があるわけ。
gccでもvolatile変数に代入した後インラインアセンブラでちょいと参照しておけばOKなんじゃない?
(でもgccってgasにした後で最適化入るんだったような記憶が・・・それだとダメか?)
307294:05/02/08 18:15:35
邪魔が入ってpdf読めないでいるうちに重要な投稿がいくつも...

実は,Javaにおけるクラスレベルのロック機能みたいなのを実現したいと思っているのです(とりあえずはWindowsで,言語はC++).
クラスレベルのロックをするための同期オブジェクトは,初期化と後始末の問題があるため単純に静的な変数に出来ません.

また,クラスレベルのロックをするための同期オブジェクトの生成過程もロックしないといけませんし,
それをするのにmutexなどの同期オブジェクトを作っていたのでは,またそのオブジェクトの生成過程をロックしなければいけなくなってきりがないのです.

そこで,volatileと,Interlock系のAPIを使用してクラスレベルのロックをするための同期オブジェクトの生成過程をロックすればよいんでは?
と思いプログラミングしてみたところ,見た目は動いてるっぽいです.
ただ,動作確認をしているマシンが1CPUですので,まだまだ,勉強が必要です.

とりあえずは,今回提示されたpdfを読んでみようと思います.
勉強になりました.ありがとうございました.
308デフォルトの名無しさん:05/02/08 18:17:32
>>303
いや、だからね、

> 同期化は考えなくても良いので、volatile とか _ReadWriteBarriar (VCね)とかで
> テキトーに済ませてしまっても問題ない。

「volatileとか」は余計だろ?
メモリバリアを正しく使ったなら無問題だよ。
309デフォルトの名無しさん:05/02/08 18:20:05
>>306
> gccでもvolatile変数に代入した後インラインアセンブラでちょいと参照しておけばOKなんじゃない?
参照っていうか、fence命令を挿入だな。Linuxカーネルなんかに_ReadWriteBarriar相当の
マクロなんかがあるから参考にすればいい。
310デフォルトの名無しさん:05/02/08 18:23:28
>>302
> そのためのvolatileでしょうが。
全然違う。

volatileによって、
変数の領域が最適化によってレジスタに作られた場合、*自スレッドが* これを参照することの影響を排除すること
はできるが。
311デフォルトの名無しさん:05/02/08 18:26:53
>>283
> Atomic じゃない処理でアクセスしてるなら、気休めにもならんぞ。
アトミックかどうかは関係ないでしょう
312294:05/02/08 18:33:50
あ...あと,いまさらですが,

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclang/html/_langref_volatile.asp

に,

The volatile keyword is a type qualifier used to declare that an object can be modified in the program by something such as the operating system, the hardware, or a concurrently executing thread.

ってありました.
313デフォルトの名無しさん:05/02/08 18:38:00
>>308
308で言ってることは正しい指摘だと思うんだけど、それはともかくとして

>>298
>コンパイラの最適化によるトラブル@シングルプロセッサは無視ですか?
これの例を聞いてみたわけだけど。エイリアス関係ならvolatile指定でOKだし・・・
314デフォルトの名無しさん:05/02/08 18:42:26
>>312
IA32の強めの一貫性を仮定しているんだろうね
315313:05/02/08 18:44:04
>>313
↑読み返すと粘着っぽいので反省して取り下げます・・・
316デフォルトの名無しさん:05/02/08 18:46:13
>>313
俺に聞かれても困るんだけど・・

volatileはvolatileで修飾した変数Vをレジスタに置かないことは保証するが、V
にアクセスする順序(Vにアクセスしたことが他CPUからみえるようになるタイミ
ング)までは制限しない

ということじゃないの?それ以上はEffectiveC++の作者様にでも聞いてくれろ
317デフォルトの名無しさん:05/02/08 19:33:10
> volatileで修飾した変数Vをレジスタに置かないことは保証する

これまた微妙な表現・・・
318デフォルトの名無しさん:05/02/08 19:46:18
>>317
参照する場合には、ってことだよね・・・
あと他人の質問に一旦返事しといて、再度聞かれると
「俺に聞かれても困るんだけど・・ 」は反則じゃねーの。
319デフォルトの名無しさん:05/02/08 20:05:39
「volatileとmulti threadはまったく無関係」というレスが沢山つくのを見ながら
「このスレッドの人はJSR-133も知らないのか」と思っていたが、みんな
知ってて遊んでたのね。人が悪い。
320デフォルトの名無しさん:05/02/08 20:24:59
>>319
全員Cの話をしているものだとばっかり。
321デフォルトの名無しさん:05/02/08 20:26:43
>>317
書き直してみて
>>313
誰に質問してるかによるんじゃないの?
322デフォルトの名無しさん:05/02/08 20:58:06
>>307
WindowsにゃPTHREAD_MUTEX_INITIALIZERみたいなのがないからなぁ。
苦労するのはよくわかる。まぁ、、現実にはみなテキトーにやってるわけだがw
323デフォルトの名無しさん:05/02/08 21:13:21
>>307
漏れはヘルパクラスを作って静的変数(classのstaticメンバにすることが多い)の
コンストラクタとデストラクタでやってます。

複数のスレッドから、DLL等ダイナミックにローディングされるような状況(COM等)ではそれだと
上手くないので、DLL_PROCESS_ATTACH のタイミングでCRITICAL_SECTIONを初期化し、
開放はしないという方針(DLL_PROCESS_DETACHでDeleteCriticalSectionはGPF出ることがある)。
Mutex使えば簡単なんだけど、重いからなぁ・・・
324デフォルトの名無しさん:05/02/08 21:20:20
> 静的変数(classのstaticメンバにすることが多い)
初期化順の問題がおきそうですね。

あと、Windowsってmain関数が走る前にマルチスレッド状態ってことはあるんですか?

325デフォルトの名無しさん:05/02/08 21:29:56
>>324
初期化順の問題が出てくるようなコードの場合には、DllMainで処理するより他ないでしょうね。

>あと、Windowsってmain関数が走る前にマルチスレッド状態ってことはあるんですか?
そういうプログラムを作るか、他プロセスからフック等で介入するかすれば。
326デフォルトの名無しさん:05/02/08 22:11:01
J・S・R! J・S・R!
327デフォルトの名無しさん:05/02/08 22:37:22
ま、マルチスレッドといえばJavaの話題と考えるのが自然なわけだが。
328デフォルトの名無しさん:05/02/08 22:54:02
>>327
ば、ばかな。
329デフォルトの名無しさん:05/02/09 00:05:46
複数枚CPUのささったサーバ等で、Javaでマルチスレッド化
されたアプリを動かしたとき、そのアプリ内でたてるスレッドって
それぞれ別CPUが処理してくれるのでしょうか?

いや、単純にスレッドをCPU分作れば複数枚のCPUパワーを
フルに使えるのか、それともシングルスレッドのアプリを複数
プロセス立ち上げた方がいいのかってところなんですが。
もちろん完全並列処理が可能だという前提で。

330デフォルトの名無しさん:05/02/09 00:12:36
VM次第。
331デフォルトの名無しさん:05/02/09 00:20:29
OSとJVMの実装による。
SunのJREとSolaris/Linux/Windowsなら基本的にはその通り。
並列度がどれくらい効くかはOS自身の成熟度にもよるけど。

あとはプロセスを別個に作るとかなりメモリが無駄に重複して
消費されるだろうとかGC的には逆に並列でスレッドが沢山走って
でかいプロセスだと負担がどうだろうとかその他のリソースの
制約はどうだろうとかあるけど。
332PHP:05/02/09 01:46:55
HTMLのセレクトボックスの項目をデータベースから持ってきた値にしたいんですけどうまくいきません。
どうしたらいいんでしょうか?
真剣にだれか教えてください
333デフォルトの名無しさん:05/02/09 01:51:03
>>332
WebProg板でやれよ
334329:05/02/09 02:02:18
ありがとう。
なんスレッドくらいがよいのか試してみます。
335デフォルトの名無しさん:05/02/09 10:11:01
336307:05/02/09 10:34:15
いい感じの内容の論文(なのかな?テクニカルレポート?)でした.
内容をちょっとだけ紹介します.

Singletonクラスのインターフェースが次のように定義されていたとします.

class Singleton {
public:
  static Singleton* instance();
  ...
private:
  static Singleton* pInstance;
};

本当はいろいろな場合わけがなされているのですが,ここでは,
Double-Checked Locking Pattern(DCLP)としてのinstanceメソッドの(まずい)実装例を取り上げてみます.

Singleton* Singleton::instance() {
  if (pInstance == 0) { // 1st test
    Lock lock;
    if (pInstance == 0) { // 2nd test
      pInstance = new Singleton;
    }
  }
  return pInstance;
}

これが何故まずいのかというと,
pInstance = new Singleton;
この一文がアトミックに行えないことにその原因があります.
【次へつづく】
337307:05/02/09 10:35:37
本文では上記コードを下記の等価なコードに置き換えて説明しています(Step1〜3の順番がややこしくなっていから注意して).

Singleton* Singleton::instance() {
  if (pInstance == 0) {
    Lock lock;
    if (pInstance == 0) {
      pInstance = // Step 3
        operator new(sizeof(Singleton)); // Step 1
      new (pInstance) Singleton; // Step 2
    }
  }
  return pInstance;
}

で,どんな問題が起きるかというと,

1.Step2のコンストラクタが例外を投げた場合,pInstanceにはoperator newでアロケートした領域のアドレスが代入されたままになります.
  さらに,コンストラクタが例外を投げたときは,operator deleteが呼ばれてしまうので,pInstanceにはフリーストアに戻ってしまった記憶領域のアドレスが保持されていることになります.


2.Thread Aがinstanceの中に入ってif文を通過しロックを取得し,Step3とStep1 を実行したとします.そしてThread Aがサスペンドしたとします.
  pInstanceにはnullではないポインターが保持されていますが,コンストラクタはコールされていません.

  この状態でThread Bがinstanceの中に入ってきた場合,pInstanceはnon-nullですから,そのまま,pInstanceの値をリターンしてしまいます.
  何度もいうようですがコンストラクタはコールされていません.


正直,ここまで考えるか!と感心してしまいます.しかもこんなのが連続します.
Singletonクラスを設計するときにはとても役立ちそうです.

ありがとうございました.
338307(いまさらだけど):05/02/09 10:52:18
http://www.cuj.com/documents/s=7998/cujcexp1902alexandr/
で 285 的なvolatileの使用例があります.上記urlでは,最初に問題のあるコーディング例として,
class Gadget
{
public:
  void Wait()
  {
    while (!flag_)
    {
      Sleep(1000); // sleeps for 1000 milliseconds
    }
  }
  void Wakeup()
  {
    flag_ = true;
  }
  ...
private:
  bool flag_;
};

というコードが記述されています.そして,
So all you have to do to make Gadget's Wait/Wakeup combo work is to qualify flag_ appropriately:
class Gadget
{
public:
  ... as above ...
private:
  volatile bool flag_;
};

と,問題点が修正されます.でも,CPUが複数個の場合は,環境依存ということになりそうですね.
339デフォルトの名無しさん:05/02/09 11:14:00
>>338
フラグをヒントにするくらいなら問題ないんじゃね?
終われそうなら終わってくれって程度で。
340デフォルトの名無しさん:05/02/09 11:59:08
ああ...確かに.個々のCPUのキャッシュが...どうのこうの考えたのですが,
仮にメモリの内容の同期が遅れてループが多少何回か多めに回転しても,この場合は無問題ですね.
341デフォルトの名無しさん:05/02/09 14:32:29
>>339
いいかもね。

俺のチームからはクビにするけど。
342デフォルトの名無しさん:05/02/09 14:37:16
>>341
お前のチームで一緒にやりたくねーよwwww
343デフォルトの名無しさん:05/02/09 14:40:03
結局>>246はどうですか?
>>250さんが言っているように
volatileにしとけば完璧ですか?
344デフォルトの名無しさん:05/02/09 14:45:03
>>343
そうだ。その通りだ。わかったらクソして寝てろ。
345デフォルトの名無しさん:05/02/09 15:04:29
ときどき聞くけどvolatileなに?
温めるの
346デフォルトの名無しさん:05/02/09 15:09:08
>>345
そうだ。その通りだ。わかったらクソして寝てろ。
347デフォルトの名無しさん:05/02/09 19:09:54
volatileとマルチスレッドは全く関係ないんだってば
348デフォルトの名無しさん:05/02/09 19:22:33
>>347
そうだ。その通りだ。わ(ry
349デフォルトの名無しさん:05/02/09 21:15:19
>342
wの多さは知能の低さ
>343
スレッドが死んだりすることはない。volatileで他スレッドの変更を
いつの日か読めるかどうかは環境依存。何度もいうが規格で規定され
ていない(C++)か未定義とされている(POSIX)ことに結論を求めては
いけない。ロック汁。

まぁ釣りなんだろうけどクマー
350デフォルトの名無しさん:05/02/09 21:35:52
>>349
Javaは?
351339:05/02/09 21:57:17
>>349
規格厨ですか?

Sleep()で寝てもいるのにvolatileなフラグの変更を
いつまで経っても読み取れない処理系挙げてみろよ。

なんでヒントって書いたかわかってないだろ?
352デフォルトの名無しさん:05/02/09 21:58:14
Alpha
353デフォルトの名無しさん:05/02/09 22:08:34
>>351
> なんでヒントって書いたかわかってないだろ?
なんで条件変数とかEventオブジェクト使わないの?

354デフォルトの名無しさん:05/02/09 22:09:25
>>350
JSR厨の光臨を待て!
355デフォルトの名無しさん:05/02/09 22:10:22
>>351
己の無知を棚に上げて人を規格厨呼ばわりするのはやめておけ。
356351:05/02/09 22:14:07
>>355
ふぅん。なら問題の出る処理系挙げてみ?
ここって規格の話をするスレだっけ?
357デフォルトの名無しさん:05/02/09 22:23:53
Alpha
358351:05/02/09 22:28:14
>>353
想定したのはProducer/ConsumerのConsumer側スレッドプールの
スレッド数を縮小させる場合などで、ターゲットのスレッドに対して
適当なタイミングで終了させるフラグを実装するような場合。

キューから引っ張ってきたタスクを実行中に止められるはずもなく、
その次のループで確実に終了する必要もない。

この条件でもフラグ見るのに絶対に同期する必要がある?
359デフォルトの名無しさん:05/02/09 22:28:49
>>356
池沼が根拠の無い嘘を書き散らす場所でないことだけは確か
360デフォルトの名無しさん:05/02/09 22:37:30
351は出荷済みのコードのことを思い出してガクブルしていて
誰かに問題ない!と言ってもらいたいんだろうな。
OSとCPUとコンパイラくらい書けばいいのに。
361デフォルトの名無しさん:05/02/09 22:54:05
volatileとマルチスレッドは無関係
362351:05/02/09 22:59:12
んにゃ。別に。

同期しときゃ済む話だし、省いたところでパフォーマンスが特に
上がるわけでもないからどうでもいい。

だけど、更新のある変数を扱う時は*絶*対*に*同期しなきゃ
いけないような論調になってるのが気に食わなかっただけ。

普通はフラグだけで完結するようなものはなくて、厳密な整合性を
必要とする操作のところで同期取ってるはずだから、結局はそこが
Memory Synchronizationになってるから問題ないでしょ?ってことさ。

だから問題がある処理系があるなら、それを挙げろ、と。
363デフォルトの名無しさん:05/02/09 23:09:31
横から失礼。

お前がコード貼って、みんなの環境でコンパイルして逆汗して、それをメモリモデルを考慮しながら検証するしかないだろうな。
俺は嫌だけど。
364デフォルトの名無しさん:05/02/10 00:37:25
>>349
> volatileで他スレッドの変更を
> いつの日か読めるかどうかは環境依存。

1 thread内なら、sequence pointは越えないんだけどね。

http://www.redhat.com/docs/manuals/enterprise/RHEL-3-Manual/gcc/volatiles.html
365デフォルトの名無しさん:05/02/10 00:37:57
>>351
C/C++なら、プログラミング言語の処理系レベルの問題ではなく、
アーキテクチャレベルの問題なんだが、それがわかってないようだな。
366デフォルトの名無しさん:05/02/10 00:42:17
だからさ、問題のおこる実例を出せって言ってるんだよ。
バカはこれだから困る。
367デフォルトの名無しさん:05/02/10 00:53:34
>>366
変数が扱えなくてリンゴとミカンでしか考えられない小学生みたいですね。
368デフォルトの名無しさん:05/02/10 00:56:24
>>366
おまいさんの質問に対して、もう二度も例が挙がってる。
それに気付いてない時点で、無知を曝け出しているのだよ。
369デフォルトの名無しさん:05/02/10 01:54:59
では、volatileラヴな皆さんへの問題。

// 初期値はともに0とする。
volatile int a = 0;
volatile int b = 0;

int threadA() {
int x;
a = 1;
x = b;
return x;
}

int threadB() {
int x;
b = 1;
x = a;
return x;
}
370369:05/02/10 01:55:31
上のようなC/C++のコードがあったとして、
SMP構成のPentium4マシン(HT機能はoff)上で
threadA(), threadB()をそれぞれ別スレッドから同時に呼び出したとする。

このとき「threadA()とthreadB()がともに0を返す」ようなことが起こり得るか?
起こり得る(起こり得ない)なら、その理由は?


次に、同じプログラムをUP構成だがHT機能を有効にしたPentium4マシンで
動かした場合はどうなるか?


# とりあえず、C/C++コンパイラはgcc 3.xとする。
# (VCでも同じ答えになるはずだが。)
371デフォルトの名無しさん:05/02/10 02:03:47
ようやく楽しげになってきたのでage
372デフォルトの名無しさん:05/02/10 02:08:20
うーん、過去ログなどは見てないで書くけど。

>>369はvolatileかどうかに関わらず、どちらが先に実行されるかって問題だけな気がする。
volatileがマルチスレッドに使えるとしている人たちの論拠は、緩やかな同期を取る話であって、
>369みたいなクリティカルな実行順序まで期待しての話じゃないと思うのだけど。
#わーい、自分でも何が言いたいのか判らんぞ
373デフォルトの名無しさん:05/02/10 02:20:37
> SMP構成のPentium4

ハァ?バカか?
んなもん存在しねーよ。
これだからバカは困る。
374デフォルトの名無しさん:05/02/10 02:32:31
Pentium4/Xeon
375デフォルトの名無しさん:05/02/10 02:35:01
351よ・・・もういい、頼むからもう安らかに眠ってくれ
消えろ。

376デフォルトの名無しさん:05/02/10 06:34:07
なんかボラタイルが自動的に同期をとるようにコンパイラに指定する
ものだと思ってるってことになっちゃってない?
377デフォルトの名無しさん:05/02/10 07:59:02
>>376
そういうレベルの話はとっくに片付いてる。
雑音も多いけど珍しくまともな議論になっていると思うよ。
378デフォルトの名無しさん:05/02/10 09:17:32
ぼらたれば
379デフォルトの名無しさん:05/02/10 09:22:31
>>369
volatileで修飾されいるとき、
変数の宣言とreturn文の間の2文の実行順序って気まぐれに変化するんだっけ?
何気に回答になっていなくてすまん。
380デフォルトの名無しさん:05/02/10 10:58:56
しまった。x はvolatileでなかったのね。
381デフォルトの名無しさん:05/02/10 11:22:15
誰もコンパイルしないな
ここはコンパイラももってないリア工房のスレだったのか。
382デフォルトの名無しさん:05/02/10 11:25:02
環境依存だからコンパイルして動かした所で意味無いしね
383デフォルトの名無しさん:05/02/10 11:28:54
(^Д^)ギャハ!↑みなさん、この人のレスどう思いますか♪なんてありきたりなんでしょうね♪
誰もが皆、一瞬つけてみたくなる発想のレスです♪
しかし、賢明な人はその自らの短絡的思考を野放しにする事を嫌がり、
こういうレスは控えます♪しかし、この人はしてしまったのです(^^;
「誰もが思い付くような事」を堂々と♪
この人にとってこのレスは何なのでしょうか♪
このレスをしている間にも時間は刻々と 過ぎ去っているのです♪
正にこの人のした事は「無意味」「無駄」でしかありません♪ああ・・・何ていう事でしょう(^^;ワラ
図星で泣いちゃうかも(^^;ワラ
384351:05/02/10 11:31:51
>>368
今のところ、Singletonで確実に一度しか実行されないことを保証するのに
volatileでは解決にならない、ってことは結論出てるけど、決定的な一貫性を
必要としない、falseがtrueに変化するだけのフラグに使用することに関しては
まだ話題に上がってないと思うんだけど。
385デフォルトの名無しさん:05/02/10 11:36:25
>>382
threadの書き方もしらねーじゃねーの( ´,_ゝ`)
VBかDelphiでスレッドかいてるのがバレバレ
386デフォルトの名無しさん:05/02/10 12:11:59
a= 1 と x = b の間には依存関係はないから、OoOをサポートした大抵のCPUで
実行される順序は保証されないんじゃないかなー。
Pen4のOoOの仕様についての質問なら多少スレ違いじゃないか?
387デフォルトの名無しさん:05/02/10 12:15:23
>>384
漏れ手元に環境ないからわからないんだけど、IA64でスレッド/CPUの対応を
固定にして実行させると、単に参照している側は永遠にキャッシュから幸せに
falseを読み出し続けるような気がする。

もちろんSleep(100)の間に、他スレッド・プロセスの実行によってキャッシュが
無効になる可能性は十分あるけど。
388デフォルトの名無しさん:05/02/10 12:16:36
ひとりごとなら駅の裏でアリを相手に言えばいい
389デフォルトの名無しさん:05/02/10 12:31:28
>>386
こういう負け惜しみ言うやつって
仕事じゃ使えないんだよな
390デフォルトの名無しさん:05/02/10 13:36:17
話の腰を折って申し訳が無い。面白そうなのでいろいろ試してみたいのですが、
キャッシュの影響でスレッド間で同期が取れない状況というのは
Pentium4のHTでも起きるのでしょうか?物理的には1CPUだから無理なのでしょうか?
391351:05/02/10 19:49:51
>>387
Coherent Cacheだから無問題。
一貫性が崩れるのは他のCPUに伝わるまでのわずかな時間だけ。

さすがにそうじゃないアーキテクチャの場合(あるのか知らないけど)は
重要な前提が崩れるわけで、他でも悲惨なことになるんだろうね。

>もちろんSleep(100)の間に、他スレッド・プロセスの実行によってキャッシュが
>無効になる可能性は十分あるけど。

これは十分というより確実にあるでしょ。CPUがスレッド数より多く、さらに
その場合はOS側でコンテキストスイッチを行わないような実装になって
いればありえるかもしれないけど、そんなの現実的じゃないし。

で、SingletonのDCLの場合は、ひらたく言えば、ある変数の読み取りと
書き込み(+比較)を、必ずしも同期なしでAtomicに行うことができるか?
という命題と捉えていいと思う。

今のフラグの話題に戻ると、DCL問題ほど制約は厳しくなくて、読み取る
タイミングは必ずしも正確である必要はなく、書き込み側では読み取りは
一切無く、1ビット(Cだと1ビットでも立ってればtrue扱い)の書き込みのみ。
Reorderされようが、最終的に1ビット立ってりゃいいだけってこと。

volatileがなければ、ループ前に最適化でレジスタにキャッシュされて、
そのまま永遠に回し続けられる可能性も否定できなくなる。

これでも*絶*対*に*同期しなきゃいけないんだろうか?
392デフォルトの名無しさん:05/02/10 21:56:55
同期しなくてもいい場合を一生懸命探しているスレはここですか?
393デフォルトの名無しさん:05/02/10 23:37:13
synchronization eliminationは非常にメジャーな研究テーマです。
394デフォルトの名無しさん:05/02/10 23:52:48
もともと、同期しなくてもいい場合なんて探すまでもないでしょう。
>>392 はそこいらじゅう同期オブジェクトだらけのプログラムでも作ってるのでしょうか?
395デフォルトの名無しさん:05/02/11 09:05:15
メインスレッドでやるとウィンドウが白くなって、(応答なし)って
出るような場面だけマルチスレッドにすればいいんだよな?
396デフォルトの名無しさん:05/02/11 09:59:35
基本的にはスレッドにできる死したほうがいいのはすべてスレッドにしてます明日が何か?
397デフォルトの名無しさん:05/02/11 11:14:01
>>396
同期できてないんじゃないか?なんか出力がおかしいぞ。
398デフォルトの名無しさん:05/02/11 11:21:48
ハァ?volatile宣言しているから*問題ない*はずですが?
399デフォルトの名無しさん:05/02/11 11:26:59
>>397
おもしろい。というのはさておき、

>>391
Windowsしかも1CPUの環境でしか、マルチスレッドプログラミングしたことないヘタレだけど、
>>338 的なことはフツーにやってんだけど、やっちゃいけないことってされてたの?
危ない橋を渡ってたんだろうか?
オレは単純だから>>338 みたいなコードが無限ループみたいになるんだったら、volatileの存在意義なんてないって思ってたんだけど...
間違い?(とされてたのか?)
だれかホントのことを教えてくれ。むちゃくちゃ気になる。
400デフォルトの名無しさん:05/02/11 11:34:51
>>399
もっぺんスレを最初から読め
401デフォルトの名無しさん:05/02/11 11:54:39
すまん。最新100ぐらいしか読んでなかった

ところで,338>>で既出の
http://www.cuj.com/documents/s=7998/cujcexp1902alexandr/
ってC/C++ Users Journalなのな。しかも書いてる人がAndrei Alexandrescu !
ヘタレなおれには心強い

とにかく最初から読んでみるよ
402369:05/02/11 12:22:17
>>386
「OoOだから保証されない」じゃちょっと不十分かな。
「どういうメモリ操作が」OoOで実行されるかってことまで突っ込んで欲しかった。

>369のコードで「threadA()とthreadB()がともに0を返すことが起こり得ない」ためには
どういうmemory orderingが要求されるか、ってのは重要。
あるアーキテクチャでは、Double-Checked Lockingは正しく動作するが
Dekker's Algorithmは動かない、それは何故か。なんて話にも繋がる。

少なくともこの程度は意識できていないと、規格厨には対抗できんぞ。
403デフォルトの名無しさん:05/02/11 12:34:30
すまんせん、OoOってなんでしょうか。
ググってみたが関係しそうなのが見つからなかったっす。
404ジャムおじさん:05/02/11 12:38:41
OpenOffice.org
405デフォルトの名無しさん:05/02/11 12:41:21
「OoOだから保証されない」正解者全員プレゼント

クイズに当たると最高100万円等が正解者全員に当たる!
1問コース 小物、アクセサリー 2問 鞄、雑貨、
3問 指輪、アウトドア  5問 商品券、家電、食品
6問、ゲームボーイアドバンス、折りたたみ自転車等
10問 PS2、2万円、サイバーショット、GQ、ブランド物等
15問 10万円、VAIO U、ビデオカメラ
20問 30万円、VAIO QR、VAIO W 25問 100万円
406ジャムおじさん:05/02/11 12:42:54
>>405
賞品にママの手づくりジャムが入ってないよ〜
407デフォルトの名無しさん:05/02/11 12:46:44
>>403
雑音はおいといて、Out of Orderの略。
408デフォルトの名無しさん:05/02/11 13:16:19
とにかく、volatileって書いておけば、マルチスレッドでも大丈夫、ということ。
409デフォルトの名無しさん:05/02/11 13:25:52
釣られないぞ。
410デフォルトの名無しさん:05/02/11 13:41:08
スレ全体の流れとしては、

当初は、>>338のようなコードはダメの典型(必ず同期を取る必要がある)とされてきたけど、
今は、>>339, >>340のいうような緩やかな同期というか成り行き任せの同期が
許される状況では >>338 のようなコードも選択肢のうちに入れてよいのでは?

ってことになってるってことでOK?

そして、C/C++ Users Journalの記事に反論できる猛者の出現を待っていると...
411デフォルトの名無しさん:05/02/11 13:41:58
>>402
write → readがout of order実行されるとダメってことですかね。
例えばIA32だとこういう操作がout of order実行される、とかってどこかに書いてあるの?
412デフォルトの名無しさん:05/02/11 13:45:25
>>410
> 今は、>>339, >>340のいうような緩やかな同期というか成り行き任せの同期が
> 許される状況では >>338 のようなコードも選択肢のうちに入れてよいのでは?

同期というより、なおかつ変更があった直後に気付くという保証が不要で、
そのうち気がつけばいいやという程度なら、ですね。
413デフォルトの名無しさん:05/02/11 13:46:13
×変更があった直後に気付く
○変更があった後の最初のチェックで気付く
414410:05/02/11 13:49:34
>>412, >>413
あっそうか...
この場合は「同期」という言葉は不適切だね。
修正ありがとう。
415410:05/02/11 14:23:00
あ... っていうより、もともと同期を必要としていない状況なのにもかかわらず、
「何で同期しないんだ!」ってことになってたからおかしくなってたんだ...
416410:05/02/11 14:26:51
補足。
もちろん、同期を必要としない状況下で同期しても害はないね。
417デフォルトの名無しさん:05/02/11 14:41:03
ここはお前の日記帳じゃあねえんだ
チラシの裏にでも書いてろ
418デフォルトの名無しさん:05/02/11 15:15:09
>>417
いまここに必要とされている人は、C/C++ Users Journalの記事に対して反論できるほどの識者であり、
もはや,あなたのようにノイズを撒き散らすだけがとりえの人間の居場所はありません。
より正確には、あなたの存在自体がノイズです。
ノイズはノイズらしく消えてください。
419デフォルトの名無しさん:05/02/11 15:35:12
っていうか、volatile最強じゃね?
420デフォルトの名無しさん:05/02/11 15:46:40
と無限ループで夜は更けていく
421デフォルトの名無しさん:05/02/11 16:07:52
>>420
もう更けるのかよ!
北極圏にお住まいなのかよ!
422デフォルトの名無しさん:05/02/11 16:24:04
volatileで>>338のようなコードの無限ループ化は防げますが、
2ちゃんねるの議論の無限ループ化は防げません。

ってことでOK?
423デフォルトの名無しさん:05/02/11 17:20:45
volatile厨厨完全に沈黙wwwwwwww
424デフォルトの名無しさん:05/02/11 17:28:38
VHDLならいつもぱられリズム
425デフォルトの名無しさん:05/02/11 23:59:13
volatileカワイイヨvolatile
426デフォルトの名無しさん:05/02/12 00:50:39
volatileを恐れなく使う兵達のスレ
でも立てるか
427デフォルトの名無しさん:05/02/12 03:55:28
このスレの住人のSMPなマシンの保有率を調べてみたい
428デフォルトの名無しさん:05/02/12 07:09:05
なんか良く判らないけどDUAL CPU用のトリップ検索ソフト作って。
429デフォルトの名無しさん:05/02/12 11:26:06
仕事じゃ4 way, 8 way, さらには16 wayなんてマシンも扱っていますが、何か?
430デフォルトの名無しさん:05/02/12 11:28:59
プ
431デフォルトの名無しさん:05/02/12 14:31:29
情報処理試験(エンベデッド)の問題について教えてください。

セマフォの記述として、適切なものはどれか。
ア P操作待ちのタスクはキューで管理される。
イ V操作待ちのタスクはキューで管理される。
ウ デッドロックの心配がない排他制御の手段である。
エ 排他制御の目的以外には使用できない。
          (平成10年度 ES 午後 問32)

正解がアかイかでちょっとだけ揉めています。どちらが正しいと思いますか?
432デフォルトの名無しさん:05/02/12 15:43:04
>>431
調べりゃ分かるが、確保するのがPで返却がV
queue使うのはP操作待ちの方だな
433デフォルトの名無しさん:05/02/12 17:30:11
オランダ語が由来だっけ?
それにしてもあまり出来のいい問題じゃないと思うなあ。
434デフォルトの名無しさん:05/02/12 18:33:52
>>432 セマフォの返却を待つタスクが並ぶキューというのはないのですか?
435デフォルトの名無しさん:05/02/12 18:48:35
それがP操作の九だって・・・・・(´・ω・`)
436デフォルトの名無しさん:05/02/12 19:13:25
そのキューではV操作を待っているんですよね?
437デフォルトの名無しさん:05/02/12 20:28:19

  ||ヽn/|, --- 、
  |i/^r     ヘ、
 く, '/彡 (ノノ))))i|  待ちタスク管理したいな
  |N ミ| | ┃ ┃ | |
  | lヽ| | ''' ヮ''ノi |     ______
  | | ⊂}|i † i|{つロ  / ロ ロ ロ  /
  Vy と.l_/_|_j_〉  / ロ ロ ロ  /
             ̄ ̄ ̄ ̄ ̄ ̄
438デフォルトの名無しさん:05/02/12 21:53:49
ダレダ、オマエハダr(ry
439369:05/02/13 02:28:27
>>411
> 例えばIA32だとこういう操作がout of order実行される、とかってどこかに書いてあるの?
そりゃ、"IA-32 Intel Architecture Software Developer's Manual"で決まりでしょ。
ttp://www.intel.com/design/pentium4/manuals/index_new.htm
とりあえず、Volume 3の"7.2. MEMORY ORDERING"以降は必読。
440411:05/02/13 03:06:40
ほんとだ。
見たはずなのに気づいてなかった。
とりあえず読んでみます。
441デフォルトの名無しさん:05/02/13 09:00:34
>>432
お前は知識は申し分ないが、日本語の能力に問題がある。
442デフォルトの名無しさん:05/02/13 14:58:10
>>336にあるようなDCLP実装ですけど、次のような方法はどうでしょう?

Singleton* Singleton::instance() {
if (pInstance == 0) {
Lock lock1;
if (pInstance == 0) {
Singletom* volatile temp;
{
Lock lock2;
temp = new Singleton;
}
pInstance = temp;
}
}
return pInstance;
}

上のコードは、Lockの確保/解放をまたいでコードが移動しないことを前提としています。
Lockの用途を考えるとLockの外側にコードが移動することはないと思いますが、
Lockの内側にコードが移動することがあるのかどうかが不明です。
443351=339:05/02/13 23:20:36
>>442
散々既出。(・∀・)カエレ!!
これだからvolatile厨は・・・。
444デフォルトの名無しさん:05/02/13 23:48:02
>>442
> 上のコードは、Lockの確保/解放をまたいでコードが移動しないことを前提としています。
> Lockの用途を考えるとLockの外側にコードが移動することはないと思いますが、

それって言えるの? 少なくともセマンティクス上はロックだなんてコンパイラは
関知しないから普通にありえるんじゃないの?

> Lockの内側にコードが移動することがあるのかどうかが不明です。

lockだと認識してもありえるんじゃないの?
Javaのsynchronizedもこれはありえたと思う。
445442:05/02/14 01:23:47
>>444
> それって言えるの? 少なくともセマンティクス上はロックだなんてコンパイラは
> 関知しないから普通にありえるんじゃないの?

確かにそうなんですが、これが保証されてないとロックは使い物になりません。
コンパイラを限定するか、普通のコンパイラであれば問題ないように
実装されているのだと想像しますが、ライブラリのスペックとして
どのように決まっているのかを知りたかったのです。

> Javaのsynchronizedもこれはありえたと思う。

おっしゃるとおり、Javaではありです。
C/C++(あるいはC上でのライブラリ)ではどうなのか、ということです。
446デフォルトの名無しさん:05/02/14 06:21:32
>>442
そのコードはともかくとして、
http://www.nwcpp.org/Downloads/2004/DCLP_notes.pdf
により、アドバンストなDCLPの実装があるよ。
でも、マルチCPUの場合は適切にメモリバリアを挿入してない、
DCLPはダメ(あらゆるマルチCPUな環境でダメというわけではないと思うが)
ってことになってるよ。
447442:05/02/14 23:36:55
>>446
読みました。
>>442のコードは2つほど問題があるようです。

1つ目。
new SingletonがpInstance = tempよりも前に実行される必要があるが、
これは必ずしも保証されません。
ロックが完全同期をとるメモリバリアの場合や、
メモリモデルがTSOのようにwrite→writeの順序が逆転しなければ
問題なさそうです。
しかし、acquire/release型のメモリバリア(release consistencyというのかな?)の場合
release後の読み書きは同期されないため、write順が逆転すると意図通りになりません。

2つ目。
Singleton::instance()で取得したオブジェクトを読み書きするときの例として以下のコードを考えます。
SIngleton* p = Singleton::instance();
p->x;
もしメモリモデルが(Pentium4のように)read→read順序が保証されないものだったとすると、
p->xがpの代入より前に行われる可能性があります。
(ただp->xはpに依存しますので、実際には順序が入れ替わることはないような気もします)

特定の環境では動きそうですが、確かにポータブルな書き方はなさそうですね。
どうもありがとうございました。
448デフォルトの名無しさん:05/02/14 23:54:06
> p->xがpの代入より前に行われる可能性があります。

そりゃいくらなんでも...
449デフォルトの名無しさん:05/02/15 09:01:53
ヴォラヴォラヴォラヴォラァァー
450デフォルトの名無しさん:05/02/19 10:17:34
volage
451デフォルトの名無しさん:05/03/01 22:39:56
Win32でブロックしているスレッドのブロックを解除する方法ってないのかな?
具体的にはReadFileでブロックしているのを特定の時に解除したいんだけど、
TerminateThreadでスレッドをヌッ殺すのはあんまり良くない見たいだし。
オーバーラップi/oにして、WaitForMultipleObjectsあたりで、ほかのイベントも
受けられるようにしとくしかないのかな。
452デフォルトの名無しさん:05/03/01 23:16:19
>>451
CloseHandle()したら強制エラーリターンしないだろうか。
・・・すまん、試してないので真偽は不明。
453デフォルトの名無しさん:05/03/02 00:29:18
>>451
Overlappedが正解だろ。
454デフォルトの名無しさん:05/03/02 20:54:06
>>452
それはやってみたけど駄目でした。CloseHandleした他のスレッドまでブロックして
戻らなくなってしまいましたよ。
ソケットのハンドルならcloseするとrecvがエラーリターンするからもしやと思って
試してみたんだけどね。

>>453
やっぱ重複i/oですか。UNIX(solaris)で使ってたコードを移植してるんだけど、
UNIXだとシグナルでブロックを中断させてるから似たようなことできないかなぁ
と思ったもんで。重複i/oにしときます。

でもだとすると、同期i/oつかったアプリってブロックを解除する手立てがないとすると、
ウィンドウの×ボタン押されたときってどうやって終了すればいいんだろ?
別スレッドからTerminateThreadとかExitProcessとか乱暴な方法しかないような
気がするけど。それともコンソールアプリでしか使うなって事なのかな。
455デフォルトの名無しさん:05/03/03 00:08:50
>>454
×ボタンだとWM_CLOSEが飛んで来て普通は終わる。無視するのも自由。
無視して動き続けるとタスクマネージャからユーザーに止められる。
シャットダウン中だと暫く待って強制終了。

使われるのはおそらくTerminateProcessかその類似品。

TerminateThreadして動き続けるのはゴミ残るから(・A ・)イクナイ!けど、
ExitProcessはプロセス間で共有するリソースを使ってるような場合を
除いて問題なし。大半のリソースはプロセスと共に解放される。
456デフォルトの名無しさん:05/03/03 02:36:02
Windowsのsignalってどういう設計なんでしょうか。
スレッドではなく、純粋な割り込みと考えてよいのかな?
457デフォルトの名無しさん:05/03/03 02:36:31
いんや
458デフォルトの名無しさん:05/03/03 02:49:37
Windows に signal なんて無かったと思うけど・・・
459デフォルトの名無しさん:05/03/03 07:38:08
CRT/src/WINSIG.c 嫁。
460デフォルトの名無しさん:05/03/04 22:21:07
>>455
WM_CLOSEが飛んで来たとき、何とかしてサブスレッドのブロックを解除後、
サブスレッドを終了。

メインスレッドでWaitFor何がしObjectでサブスレッドが終了するまで待機後、
サブスレッドのハンドルをクローズ。その他諸々のハンドルを閉じてプロセス
終了へ。と言う風に思ってたんだけど

終了時ならそんなにムキになって後始末しなくていいんだ。
461デフォルトの名無しさん:05/03/06 23:41:01
俺様専用チラシの裏

少し前に「Windowsではmutexの静的な初期化が出来ない」という
話があったような気がするが
実際に必要になりそうなケースに遭遇したので、解決法の案。
(double-checked lockingなのは趣味だから気にするな)

static data_t *data;
 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
 pthread_mutex_lock(&mutex);
 if (!data)
  data = get_initial_data();
 pthread_mutex_unlock(&mutex);

pthreadでは↑のように行う処理を、Windowsでやりたい。
 CRITICAL_SECTION *csection;
 if (!csection) {
  CRITICAL_SECTION *p = new CRITICAL_SECTION;
  InitializeCriticalSection(p);
  InterlockedCompareExchangePointer(&csection, p, NULL);
  if (csection != p) {
   // 解放部は場合によっては不要だと思われる
   DeleteCriticalSection(p);
   delete p;
  }
 }
 EnterCriticalSection(csection);
 以下略
面倒ではあるが、こんな感じで正常に動くと思うのだが、どうだろうか。
462デフォルトの名無しさん:05/03/08 15:28:58
環境:
WinXP Pro
VC++ 6.0

マルチスレッドのサーバプログラムを作りたいと思っているのですが、
参考になるようなHP又はアドバイス等ありましたらご教授願います。
サーバの処理内容は、SQLDBに接続して処理結果を
クライアントに返すというものです。
463デフォルトの名無しさん:05/03/09 02:21:10
>>462
自前でマルチスレッドサーバプロセスを作るのは面倒なので、COMコ
ンポーネントを作ってCOM+に登録するというのはどうでしょうか。

スレッドやトランザクションの管理をお任せに出来るのが楽だと思
います。COMコンポーネントの作成に抵抗がなければですが……
464462:05/03/09 09:00:54
>>463
曖昧な質問に答えて頂いて有難うございます。
VC++はあまり弄った事がないので、
まずはCOM+について調べてみたいと思います。
465デフォルトの名無しさん:05/03/09 09:39:05
>>456
構造化例外の成れの果て
だったと思ったけど。
466デフォルトの名無しさん:05/03/09 23:39:05
>>465
だな。準拠のためのやっつけ仕事。
な〜んの役にも立たんぞ。
467デフォルトの名無しさん:05/03/12 02:45:10
マルチスレッドって何?(main()もスレッドらしいけど)
どうやって作るのか教えて下さい。
そもそもその定義とは何ですか?
468467:05/03/12 02:47:10
環境は、VC++.net2003又は、bcc5.5です。
469デフォルトの名無しさん:05/03/12 14:37:30
beginthreadex関数のサンプルを見ろ。
糞初心者が。
470デフォルトの名無しさん:05/03/15 05:37:07
pthreadとboostどちらが可搬性がありますか?
471デフォルトの名無しさん:05/03/15 14:49:30
boostのthreadは、C++コンパイラが古い環境だと動かないだろ
自分でboostやg++をmakeする気持があればどっちも同じ。
472デフォルトの名無しさん:05/03/15 15:15:53
実際古いコンパイラが問題になることなんて無いと思うけどね。
新しくすればいい。
473デフォルトの名無しさん:05/03/15 22:52:31
>>470
boostはWindowsでも使える。
pthreadはWindows上では動かない。
そういう意味ではboostの方がポータブルだな。

・・・まあCygwin使えばpthreadも動くわけだが。
474471:05/03/16 00:17:52
>>473
それはちょっと知識が古いかな。

Pthread Support in Microsoft Windows Services for UNIX Version 3.5
http://www.microsoft.com/technet/interopmigration/unix/sfu/pthreads0.mspx

SFU 3.5はなぜ無償化されたのか
Services for UNIX最新版を無償化したマイクロソフトのマーケティング戦略
http://www.atmarkit.co.jp/fwin2k/insiderseye/20040319sfu35/sfu35.html

一時アメリカの政府機関の導入用件にPOSIX準拠であることを策定したので、
その流れでPOSIX対応じゃないと導入できないところがまだある。
C2 securityしかり。
475デフォルトの名無しさん:05/03/16 01:27:50
>>474
確かにNTにPOSIXサブシステムがあったのはそれが理由だが
SFUは違うというか普通にMacOSX対策じゃない?
476デフォルトの名無しさん:05/03/16 14:15:46
>>475
つかえねーPOSIXサブシステムは捨てたから、
POSIX互換が必要ならSFU使えって事でないの?
477デフォルトの名無しさん:05/03/16 14:22:49
>>476
導入用件をクリアさえすればいいだけで使えるようにする必要は無いんだから
わざわざ買収までしてSFUに切り替える理由がそれだけでは弱い
478デフォルトの名無しさん:05/03/16 15:30:26
使えないと要件クリアしません。

Citrix ターミナルサーバ、Interix SFUは、いい決断だったと思います。
479デフォルトの名無しさん:05/03/16 16:24:52
>>478
>>476-477が言ってる使えないと>>478の言ってる使えないのニュアンスは多分違う
480デフォルトの名無しさん:05/03/18 11:15:29
@/A-----------------------------------------
環境
WinXP Pro
VC++ 6.0

VC++でマルチスレッドを用いた複数端末通信プログラムを作っています。
端末との通信はできたのですが、プログラムが終了するときにメモリリークが発生してしまいます。

プログラム構成は以下の通りです。
MainApp : CWinApp (アプリケーション)
MainSock : CAsyncSocket (アプリケーションメインソケット)
SubThread : CWinThread (各端末毎の接続を担当するスレッド)
SubSock : CSocket (端末とのデータ送受信用ソケット)

MainApp::InitInstance(){
g_Sock = new MainSock(); // メインソケット生成
g_Sock->Listen(); // 接続要求待ち
}

MainSock::OnAccept(){
SubThread* pThread = (SubThread*)AfxBeginThread()
スレッドにソケットを引き渡す
pThread->ResumeThread();
}

SubThread::InitInstance(){
m_SubSock.Attach( 渡されたソケット );
}

void SubSock::OnReceive(){
受信データの読み込み
}
481デフォルトの名無しさん:05/03/18 11:16:00
A/A-----------------------------------------
デバッグウィンドウのメッセージは以下の通りです。
Detected memory leaks!
Dumping objects ->
C:\Server\SubThread.cpp(17) :
{100} client block at 0x005F2F60, subtype 0, 140 bytes long.
a SubThread object at $005F2F60, 140 bytes long
Object dump complete.

SubThread.cpp(17)には、
IMPLEMENT_DYNCREATE(SubThread, CWinThread)
が記述してあります。

端末との接続用に生成したスレッドが終了していない事が原因と考えています。
スレッド内から AfxEndThread を呼べば終了できる事は確認していますが、
スレッドではSubSockオブジェクトを初期化しているだけで
Run()内でループ処理しているわけではないので、外部からフラグ等で終了させる事はできません。
外部から終了するにはどうすればいいのでしょうか?
482デフォルトの名無しさん:05/03/18 12:17:15
そういうスレッドの使い方はしない。
483480:05/03/18 12:46:33
ええっそうなんですか・・・
じゃあ、単純にソケットを複数個用意して、処理を割り当てればいいんですかね・・・?
何か参考になるHPとかあったら教えて頂けませんか?
484デフォルトの名無しさん:05/03/18 13:10:34
MFC ソケットでぐぐると一杯出てくるよ。
お好きなのをどうぞ。

マルチスレッドにするのならヒントとしては、
接続のためだけにワーカースレッドを用意して、
通信はメインスレッドに任せるっていう考え方よりも、
メインスレッド側で接続管理をして、
それぞれの通信管理をスレッドに任せる方が、
スマートだと思うけど。
485480:05/03/18 14:07:42
一応、メインスレッドで接続管理、サブスレッドでデータ通信になってます。

@メインスレッドでメインソケットをListenで待機
AメインソケットのOnAcceptでサブスレッドを生成、サブスレッドのメンバ変数にソケットを渡す
Bサブスレッドのソケットでデータ送受信
Cサブスレッドのソケットを閉じる

というところまではできたのですが、Aで生成したサブスレッドが終了できない、という状況です。

>MFC ソケットでぐぐると一杯出てくるよ。
散々ぐぐって色々見てみたんですが、ソースの一部しか載ってなかったり
プロジェクトの性質から使えなかったり、という感じだったので
足りない部分を自分で作ってみたらこんな感じになってしまいました。
486デフォルトの名無しさん:05/03/18 14:32:44
それは、4の後にAfxEndThreadなりでスレッドから抜けずに、
スレッドは生かしつづけたままって事?

通常はその流れなら、

@メインスレッドでメインソケットをListenで待機
AメインソケットのOnAcceptでサブスレッドを生成、サブスレッドのメンバ変数にソケットを渡す
Bサブスレッドのソケットでデータ送受信
Cサブスレッドのソケットを閉じる
Dサブスレッドから抜ける(スレッドの終了)

と言う様になると思うんだけど。

途中でスレッドを停止させるケースに対応したいっていうなら、
イベントカーネルオブジェクトなりで、メインスレッド<->サブスレッド間の
通知機構を実装しなきゃだと思う。

スレッドを生かしつづけてソケットだけを生成->割り当てとするなら、
スレッドプールの実装も考えた方がいい。

アプリケーションの終了時リークするのは、スレッドが停止していない状態で、
プロセスを終了しているからでは?
それならば、スレッドの終了をきちんと待ってからアプリは終了するべき。
スレッドの緊急停止は最終手段。


487480:05/03/18 14:56:13
>イベントカーネルオブジェクトなりで、メインスレッド<->サブスレッド間の
>通知機構を実装しなきゃだと思う。
VC++あまり弄った事がなくてソケットの部分だけ調べまくってやってたので、
存在を忘れていました。

今回はとりあえず動かなければどうしようもないので、
Run()の中ですぐSubSock.Receive()を呼んでデータを受信し、
ループ処理せずにAfxEndThread(0,true);で終了する、という方法でやる事にしました。

他にも色々いい方法があるようなので、今度調べてみたいと思います。
どうも有難うございました。
488デフォルトの名無しさん:05/03/18 14:59:13
Windowsのマルチスレッドプログラミングを本格的にやりたいのなら、
AdvancedWindows第4版は買っておいたほうがいいよ。
489デフォルトの名無しさん:05/03/18 15:01:14
>>487
AfxEndThread()で終了すると、そのスレッド内で実体化したクラスのデストラクタが呼ばれない。
なので、単にreturnする方がいい。
490480:05/03/18 15:18:32
有難うございます。読んでみます&試してみます。
491デフォルトの名無しさん:05/03/18 21:46:31
>488
どんなことが書いてある(その本でしか読めない)の?
492デフォルトの名無しさん:05/03/19 00:21:09
目次と内容は↓で分かるよ。
http://www.ascii.co.jp/pb/msp/38055/38055.htm
493デフォルトの名無しさん:05/03/19 00:59:08
なかなかよさそうですね
volatile
494デフォルトの名無しさん:05/03/19 03:48:54
asm volatile ( "breakc 0x0" );
495デフォルトの名無しさん:05/03/21 00:11:17
Linuxのシステムで、プロセスをまたいだファイルのアクセスをします。
オススメの排他制御は何ですか?
対象のシステムは、突然電源が落とされる可能性があるものとします。
496デフォルトの名無しさん:05/03/21 00:14:53
>>495
ありません
497デフォルトの名無しさん:05/03/21 00:25:59
>>495
プロセスをまたいだら、既にスレ違い (マルチスレッドじゃない)
だろ。fcntl(2) で F_SETLKW。
てゆうかAPUE(http://pc5.2ch.net/test/read.cgi/tech/1105723117/13)嫁。
498デフォルトの名無しさん:05/03/21 01:15:22
それもそうでした。(スレ違い)
ごめんなさい。
499デフォルトの名無しさん:2005/03/24(木) 09:51:02
>>492
おお、懐かしいな。俺が買った頃はまだ「Advanced Windows NT」
だったけど、Win32スレッドの使い方は大部分それで理解したよ。
最近JavaばっかでWin32方面は色々知らん事も多くなってきたから
また買ってみよ。あんがと。
500デフォルトの名無しさん:2005/03/25(金) 13:54:27
500 ∈(・◎・)∋
501デフォルトの名無しさん:2005/03/26(土) 19:05:24
Windowsでのスレッド同期でクリティカルセクションを使用するのですが
EnterCriticalSectionでSTATUS_NO_MEMORYの例外が発生する可能性があるそうですが、
皆さんどのように対策していますか?

InitializeCriticalSectionではなくInitializeCriticalSectionAndSpinCountを使えば回避できるようですが
Windows95等では対応していないようなので構造化例外処理を使用してどうにかしたいのですが
スマートな方法が思いつきません(´・ω・`)
502デフォルトの名無しさん:2005/03/26(土) 19:34:30
>>501
説明文の構成の仕方が変なのは気付いてますか?
「〜ですが、」ばかりで、丁寧語を使っていたとしても、
これではまるで馬鹿な子を見ている様です。丁寧語も中途半端です。
もっと本を読んだ方が良いでしょう。


私が書き直すとしたら、以下のようにするでしょう。
--------------------------------------------------------------
Windowsでのスレッド同期でクリティカルセクションを使用しています。
EnterCriticalSectionにてSTATUS_NO_MEMORY例外が発生する
可能性があるようですが、
皆さんはどのように対策しておられますか?

1つの対策としてInitializeCriticalSectionの代わりに、
InitializeCriticalSectionAndSpinCountを使う方法がありますが、
Windows95等では未対応のため、構造化例外処理からどうにかしたいのです。
スマートな方法が思いつきません。(`・ω・´)
503デフォルトの名無しさん:2005/03/26(土) 19:38:34
補足ですが、大事なのは最後の眉毛の向きです。
これを読み違えないで下さいね。
それ以外はあまり気にする必要はないでしょう。
504デフォルトの名無しさん:2005/03/26(土) 20:14:07
Yes,teacher. (´・ω・`)
505デフォルトの名無しさん:2005/03/26(土) 20:17:09
では次の方、質問どうぞ。
506デフォルトの名無しさん:2005/03/26(土) 21:31:11
Windowsでのスレッド同期でクリティカルセクションを使用するのですが
EnterCriticalSectionでSTATUS_NO_MEMORYの例外が発生する可能性があるそうですが、
皆さんどのように対策していますか?

InitializeCriticalSectionではなくInitializeCriticalSectionAndSpinCountを使えば回避できるようですが
Windows95等では対応していないようなので構造化例外処理を使用してどうにかしたいのですが
スマートな方法が思いつきません(´・ω・`)
507デフォルトの名無しさん:2005/03/26(土) 22:06:30
Win95を捨てる。
508デフォルトの名無しさん:2005/03/26(土) 22:11:29
MSDNによるとInitializeCriticalSectionAndSpinCountは
Win98以降で使えるみたいだから、捨てるのはWin95だけでいいみたい。
どうせもはやMSのサポート終了した製品だし。
509デフォルトの名無しさん:2005/03/27(日) 00:30:19
Windows以外のOS使え馬鹿
510デフォルトの名無しさん:2005/03/27(日) 02:41:40
http://www.itmedia.co.jp/enterprise/articles/0503/23/news086.html
C#のメモリモデルについての記事。
DCLについても載ってるよ。
511デフォルトの名無しさん:2005/03/27(日) 08:44:29
何気に興味深い記事だな
512デフォルトの名無しさん:2005/03/28(月) 19:45:29
CPU換装したら、ここで試せや↓
http://www5e.biglobe.ne.jp/~liquor/raytrace/
http://www5e.biglobe.ne.jp/~liquor/prime/
マルチスレッドならここに聞け
513釣り:2005/03/29(火) 21:53:11
>510
なるほど、C#ではvolatileでいいんですね
514デフォルトの名無しさん:2005/04/03(日) 17:32:47
               .|   |  | |   |    |  | |   |   |   || | |
               .|   |  | レ  |    |  | |   |  J   || | |
    ∩___∩    |   |  |     J    |  | |  し     || | |
    | ノ\   ,_ ヽ  .|   レ |      |  レ|       || J |
   /  ●゛  ● |   .J      し         |     |       ||   J
   | ∪  ( _●_) ミ             .|    し         J|
  彡、   |∪|   |              .J                レ
 /     ∩ノ ⊃  ヽ
 (  \ / _ノ |  |
  \  "  /  | |
   \ / ̄ ̄ ̄ /
      ̄ ̄ ̄ ̄
515デフォルトの名無しさん:2005/04/03(日) 19:28:11
516デフォルトの名無しさん:2005/04/03(日) 21:53:23
volatileとマルチスレッドは全く一切絶対ひとかけらも関係がない
517デフォルトの名無しさん:2005/04/04(月) 00:30:00
518デフォルトの名無しさん:2005/04/15(金) 14:29:59
クリティカルセクションというのは
Enter〜Leaveの間はプロセス内のそのスレッド以外は動かないと
言う考えであってますか?
例えば2つのスレッドで同じ関数を呼ぶ場合、その関数の頭でEnterして
最後でLeaveしたとするとその関数自体複数のスレッドで同時に呼ばれる事が
無くなると言う事でしょうか?
519デフォルトの名無しさん:2005/04/15(金) 15:55:45
考え方は基本的にあってる。

けど関数は自体は同時コール出来る
関数の中に入った時点で片方のスレッドがロックされる。
520デフォルトの名無しさん:2005/04/15(金) 15:59:07
>>519
回答ありがとうございます。
今そういった感じのアプリケーションを作ってるのですが
どうもその辺りに自信がなかったもので・・・。
521デフォルトの名無しさん:2005/04/15(金) 20:03:04
あるスレッドがクリティカルセッションオブジェクトにEnterしている間、
同じクリティカルセッションオブジェクトに対してEnterするとブロック(一時停止)される。というだけ。
522デフォルトの名無しさん:2005/04/16(土) 00:51:27
>>521

その表現では曖昧じゃね?
他のスレッドは少なくともEnterできないと思うが
同じスレッドが複数回Enterできるかどうかはモノによるような。
523デフォルトの名無しさん:2005/04/16(土) 08:10:24
同じスレッドの複数回Enterでブロックするのならば、即デッドロックなわけだが。
もし「ブロックする」という実装ならば、その旨(複数回Enterするなと)明記されているのが普通と思う。

むしろ、複数回Enterした後、1回のLeaveで解除されるかが
実装依存な部分な気がする。
524デフォルトの名無しさん:2005/04/16(土) 10:49:28
enter/leaveって何の話なんだ?
525デフォルトの名無しさん:2005/04/16(土) 11:00:32
>>523
MSDNのLeveCriticalSection()の解説にこう書いてあるよ。

>クリティカルセクションの所有権を解放するには、各スレッドはクリティカルセクションに入るたびに、
>LeaveCriticalSection 関数を 1 回呼び出さなければなりません。

>>524
CriticalSection=Windows固有のプロセス内限定のリカーシブなmutexみたいなもの。
EnterCriticalSection()でロックされて、LeaveCriticalSection()でアンロックされる。
たぶん....。
526デフォルトの名無しさん:2005/04/16(土) 16:13:40
クリチカルセクション内ではプロセス内のスレッドの切り替えが起こらないというだけだろ。
何を難しく考えているんだか
527デフォルトの名無しさん:2005/04/16(土) 16:24:28
さすがにそれは違うだろう。。。
528デフォルトの名無しさん:2005/04/16(土) 17:02:46
>>527
どこが?
529デフォルトの名無しさん:2005/04/16(土) 17:20:03
>>528
「クリチカルセクション」ってのが EnterCriticalSectionからLeaveCriticalSection間の
ことを指してるんなら、スレッドの切り替えは普通に行われるよ。

Windows 以外の環境の「クリチカルセクション」ってのについては知らないけど。
530デフォルトの名無しさん:2005/04/16(土) 17:31:19
531デフォルトの名無しさん:2005/04/18(月) 00:59:48
スレッドの切り替えはおきる。
ただし、同一 CriticalSection 間にはひとつのスレッドしか入れない。

スレッド A
EnterCriticalSection(&cs)
printf("A");
printf("a");
LeaveCriticalSection(&cs)
printf("1");

スレッド B
EnterCriticalSection(&cs)
printf("B");
printf("b");
LeaveCriticalSection(&cs)
printf("2");
を動かしてみればいい。
"Aa" の間に "Bb" は絶対に入らないが A2a はあるハズ。
532デフォルトの名無しさん:2005/04/18(月) 23:15:23
>526
533デフォルトの名無しさん:2005/04/18(月) 23:41:32
ヒロシです
ワークパイルとワーカースレッドの違いがわからんとです
534デフォルトの名無しさん:2005/04/19(火) 00:07:55
おな ぬ
535デフォルトの名無しさん:2005/04/19(火) 12:09:56
>>532
組み込み用に書かれた OS (というかリアルタイムモニタというか) やプログラムなら、
クリティカルセクションをそんな風に実装することもあるよ。
単に割り込み禁止にしたりしてさ。
536デフォルトの名無しさん:2005/04/19(火) 12:23:55
助けてください!
メインスレッド無限ループ中にKERNEL32でエラーが出てしまいました!

スレッドも最近学んだ程度で、カーネルだって知らない!
助けてください!
537デフォルトの名無しさん:2005/04/19(火) 12:46:11
無理
538デフォルトの名無しさん:2005/04/19(火) 13:04:22
( ´゚д゚`)そんなー
539デフォルトの名無しさん:2005/04/19(火) 13:05:57
>>535
クリティカルセクションでスレッドそのものを制御する事も出来るの?
540デフォルトの名無しさん:2005/04/19(火) 13:15:20
NetBSDに「RAS」という仕組みがあって、ある区間においてコンテキス
トスイッチが起きないようにできます。シングルプロセッサのときは、
RASを使ってpthread_mutex_lock/unlockが実現されています。
541デフォルトの名無しさん:2005/04/19(火) 13:33:16
それだけではよくわからんのでRASとはどのような仕組みか説明してたもれ。
542デフォルトの名無しさん:2005/04/19(火) 13:36:15
ググったら Restartable Atomic Sequences だということだけわかった。
543デフォルトの名無しさん:2005/04/19(火) 14:07:17
コンテキストスイッチを停止する実装では
enter中に数分間の長い処理を行っただけで
他スレッドの処理が止まってしまい困るのでは?
544デフォルトの名無しさん:2005/04/19(火) 14:12:34
>>543
そういうOSの場合、困らないプログラムを動かすから何の問題も無い。
処理が短いとか別スレッドが動かなくてもいいとか。
545デフォルトの名無しさん:2005/04/19(火) 14:20:11
>>543
数分も何らかの排他処理を行いたいなら、
mutexやセマフォを実装すれば良いわけで。
んでそのセマフォなりmutexなりの操作する部分だけを
クリティカルセクションで保護する。
546デフォルトの名無しさん:2005/04/19(火) 14:28:06
一般的な話として、
保護すべき領域をクリティカルセクションと呼ぶのであって、
保護するための仕組みのことではないよね...
547デフォルトの名無しさん:2005/04/19(火) 14:35:33
>>543
ユーザプロセスが異常な振舞いをしたから他のプロセスの実行に支障が出るってのは
まずいだろ。
enterしたままビジーループに入ってしまったらどうすんの?
548デフォルトの名無しさん:2005/04/19(火) 14:46:19
>>547
組み込み系だと普通はWDTで電源落ちにします。
549デフォルトの名無しさん:2005/04/19(火) 14:50:50
タイマー割り込みで点滅させてるLEDがとまるから目で見てわかるんだよ(w
550デフォルトの名無しさん:2005/04/19(火) 14:57:15
>>543
>他スレッドの処理が止まってしまい困るのでは?
>>547
>他のプロセスの実行に支障が出るってのはまずいだろ。
話がずれてますな。
551デフォルトの名無しさん:2005/04/19(火) 14:59:48
そう?
>>543はハードリアルタイムを保証するかどうかどうかで、
>>547は協調的マルチタスクを必要とするかどうかじゃない?

いくらなんでもユーザプロセスがおいたして機能不全に陥いるのはまずいべ。
少なくともUNIXでは普通は予期しないだろう。
552デフォルトの名無しさん:2005/04/19(火) 15:06:40
組み込みで少数のプログラマチームに全ての開発が
任されているならありかなとは思う。
553デフォルトの名無しさん:2005/04/19(火) 15:45:46
NetBSDなんかが出てきたので混乱されている方もいそうですが、RAS は
>ある区間においてコンテキストスイッチが起きないようにできます。
というような乱暴なものではないと思うんだけど・・・

組み込み用OSでは、まずい設計のプログラムを書けば
まずい結果が得られるのはごく普通。
普通のOSでもデバイスドライバ等では同様。
554デフォルトの名無しさん:2005/04/19(火) 20:00:03
そもそもシステムプロセスとユーザプロセスの区別があるとも限らんし。
555デフォルトの名無しさん:2005/04/19(火) 20:08:59
ms-dos + αというイメージだな。
556デフォルトの名無しさん:2005/04/19(火) 20:16:58
マルチスレッドじゃなくてマルチプロセスなんですけど・・
共有メモリに対するアクセスにセマフォを使って
排他制御をかけようとしています。できれば排他ではなくて
reader/writer ロックを実装したいのですが、普通こういうのは
どのように実装するんでしょうか? なんらかのライブラリ?は
なさそうですし・・。ちなみに Linux の C です。

スレ違い、勘違い発言でしたらすみません。。
557デフォルトの名無しさん:2005/04/19(火) 20:23:26
スレ違いだし、そういう概念的な話は本読んだ方が早い
558デフォルトの名無しさん:2005/04/19(火) 23:48:02
>>556
UNIXプログラミングスレ言って、
System V IPCのセマフォの使い方聞け。
(man semop)
559556:2005/04/20(水) 00:03:24
>>557
>>558

コメントありがとうございます。
「最前線UNIXのカーネル」という書籍があったので
自分なりに調べましたが、reader/writerの実装は
結構ややこしそう(めんどくさそう)でした。

現状はセマフォで実装しており常に排他になってしまってますが
まあなんとなくこれでしばらくは我慢しようという気持ちに
なってきたところです。

ともあれ、コメントありがとうございました。
560558:2005/04/20(水) 00:51:15
semaphoreあったら、簡単だろ?
reader/writer lockは。一つカウンタ管理するだけだぞ。
ただスレ違いだから、必要だったらあっちで聞いてね。
561デフォルトの名無しさん:2005/05/01(日) 17:39:45
ps じゃダメなのかな?
ああ、Linuxだと 一個増えて表示されるからややこしいかな?
Solarisならいいんだけど
562デフォルトの名無しさん:2005/05/03(火) 22:49:16
psってプロセス表示のコマンドの事言ってるんだろうか
だとしたら無茶言うな
563デフォルトの名無しさん:2005/05/15(日) 13:30:23
スレッドの生成コストってどのくらいなのでしょう?
564デフォルトの名無しさん:2005/05/15(日) 13:33:26
>>563
>>563 が考えているコストの1.5倍ぐらい。
565デフォルトの名無しさん:2005/05/15(日) 13:56:12
>>564
結構高いんですね。
頻繁に作成消滅を繰り返すよりも、使用しないときはmutexで停止させて眠らせておいた方が良さそうですね。
566デフォルトの名無しさん:2005/05/15(日) 14:52:16
スレッド生成のベンチマークがどっかにあったような
だいたい1msで作れてた気がするな
567デフォルトの名無しさん:2005/05/15(日) 15:06:29
条件がわからんが単純にCPUが1GHzとすると、1Mクロックかかるのか。
568デフォルトの名無しさん:2005/05/16(月) 00:07:59
かかり杉だな
死ねクズって感じ
569デフォルトの名無しさん:2005/05/16(月) 01:16:21
どのOSのことか書いてないけど
Windowsのbeginthreadexの場合はまずCランタイムの初期化とかもあるし、
内部的にVirtualAllocでメモリマップを割り当てたりCriticalSection
とかで排他したりしてるわけだから、
実際計ったことないけど1msで作れれば良いほうだと思うよ。
これに比べるとUNIXのforkなんか目も当てられない。
570デフォルトの名無しさん:2005/05/16(月) 01:20:09
ただ、forkに比べてスレッドに割り当てられるアドレス空間は、
プロセスが割り当てるメモリマップに依存し有限だから、
forkのようにいくらでも作れるというわけじゃない。
Windowsのスレッドはデフォルトで1MBのスタックを個別にマップするわけで、
プロセスのメモリ空間が32bitの範囲のOSなら、約2000個のスレッドを
作れれば良い方だと思う。
スタックサイズを調節したらもっと多くできるだろうけど。

つーか1プロセスの最大スレッド数って定義されてたっけ?
誰か試してみませんか?
571デフォルトの名無しさん:2005/05/16(月) 01:58:55
LinuxはNPTL+kernel2.6で最強になりましたよ。WINDOZE糞杉。
572デフォルトの名無しさん:2005/05/16(月) 11:22:58
>>569
スレッドとプロセスを比べられても…
573デフォルトの名無しさん:2005/05/16(月) 20:53:18
今時の fork(2) はみんな COW じゃないの
574デフォルトの名無しさん:2005/05/16(月) 21:26:14
Atom Heart Mother やね
575デフォルトの名無しさん:2005/05/17(火) 00:39:33
>>571
そりゃ後発で糞だったら目も当てられないw
まあスレッドだけ早くなってもXはもっさりのまんまだし、
UNIXって前途多難だよな。
576デフォルトの名無しさん:2005/05/17(火) 01:42:21
どうでもいいが
> UNIXって前途多難だよな。
2037年が寿命ならもう半分は過ぎてしまったわけで、もう前途はないわけで
577デフォルトの名無しさん:2005/05/17(火) 08:23:21
>Xはもっさりのまんまだし
これはもう、OSの所為ではなくてプロトコルが余りに古すぎる所為なのだが。
タランテラみたいなミドルウェア経由の方がよっぽど速くなる罠。
578デフォルトの名無しさん:2005/05/17(火) 18:35:29
(1)のシグナルを受け取るスレッドが他になかった場合、
(2)で自分のシグナルを受信しちゃいます?

pthread_mutex_lock( &mutex );
pthread_cond_signal( &cond ); // (1)
Value = 1;
do {
pthread_cond_wait( &cond, &mutex ); // (2)
} while ( Value != 0 );
pthread_mutex_unlock( &DataProcMutex );
579デフォルトの名無しさん:2005/05/18(水) 23:30:41
アセンブラ言語で文字列操作の「REP MOVS〜」の繰り返し処理中にスレッド切替は発生するのでしょうか?
580デフォルトの名無しさん:2005/05/19(木) 00:01:10
>Xはもっさりのまんまだし
単純にDisplayの設定を変えるだけで早くなる場合があるがな
581デフォルトの名無しさん:2005/05/19(木) 00:11:27
>>579
Intel PDF IA-32より
service pending iterrupts (if any)
だから切り替えは起きません。
582デフォルトの名無しさん:2005/05/19(木) 00:12:20
×iterrupts
○interrupts
583デフォルトの名無しさん:2005/05/19(木) 00:20:30
>>581
スレッド切替え発生するだろ。

>service pending iterrupts (if any)
それ割り込みじゃねーのか?
584デフォルトの名無しさん:2005/05/19(木) 00:23:25
割り禁中にコンテキスト切り替え起こすのは難しそうだな。。。
585デフォルトの名無しさん:2005/05/19(木) 00:26:18
>>583
コンテキスト切り替えって、何らかの割り込みで起こすんじゃねーの?
586デフォルトの名無しさん:2005/05/19(木) 00:34:17
スレッド2つ立ち上げて、一つは巨大なメモリブロックをREP MOVSなどで繰り返し
転送する重い処理を、もう一つは単純なループなどを実行し、それぞれのスレッド
に実質的に割り当てられたCPU時間を比較してみてもいいな。

あ、でもタイムスライスより長いREP命令なんてなかなかないかも。
587デフォルトの名無しさん:2005/05/19(木) 01:08:19
UDP使ったチャットプログラムを作りたいんだが、スレッドの使い方がよくわからんとです。。
言語はCです。。教えてエロイ人〜!!
588デフォルトの名無しさん:2005/05/19(木) 01:15:53
ならば、まずスレッドをつかわずにやってみたまへ。
589デフォルトの名無しさん:2005/05/19(木) 01:31:34
レスありがとう、エロイ人!
とりあえず文字列がサーバ(?)からクライアント(?)に送れるようにはなったとです。
でもチャットってサーバとかクライアントとか関係なく送信も受信もできなきゃダメじゃないですか・・・。
スレッド使えばうまくいくのかなぁとか思ったとですけど、うまくいかんとです。
もっと良い方法があるとですか??
590デフォルトの名無しさん:2005/05/19(木) 01:41:29
まずプロトコ〜ルを決めたまへ
591デフォルトの名無しさん:2005/05/19(木) 01:53:27
IA-32 インテル アーキテクチャソフトウェア・デベロッパーズ・
マニュアル中巻より

リピート・ストリング操作は、例外または割り込みによって中断されることがある。


とあるから、rep〜中にもスレッドの切り替えはあるでしょう。
592デフォルトの名無しさん:2005/05/19(木) 03:02:22
>>585
割り込みと言っても色々あるのだ。
593デフォルトの名無しさん:2005/05/19(木) 03:08:31
(・∀・)
594デフォルトの名無しさん:2005/05/20(金) 15:02:12
( ・ ∀ ・ )
595デフォルトの名無しさん:2005/05/20(金) 18:47:52
(   ・   ∀   ・   )
596デフォルトの名無しさん:2005/05/20(金) 18:49:12
(──────────∀──────────)
597デフォルトの名無しさん:2005/05/20(金) 19:30:43
(   (・∀・)   ∀   (・∀・)   )
598デフォルトの名無しさん:2005/05/20(金) 19:34:13
599デフォルトの名無しさん:2005/05/24(火) 03:27:33
スレッドに関してお教え下さい.
これまで,スレッドを使用したプログラムではいくつかの動作を
メインループから指示するために
WaitForSingleObjectもしくはWaitForMultipleObjectsを使用し
Signalによって動作を起動させていました.
今回,いくつかのパラメータをスレッドに渡す必要が生じたのです
がどのような方法が簡単で安全でしょうか?
600デフォルトの名無しさん:2005/05/24(火) 05:18:44
>599 CreateThread。
601デフォルトの名無しさん:2005/05/24(火) 07:24:28
WaitForMultipleObjectsExにして、
QueueUserAPCで渡す。
602デフォルトの名無しさん:2005/05/24(火) 12:58:44
UNIXでgetrusageを使って使用CPU時間を取得しているのですが、pthreadを使った場合、うまくいきません。
全スレッドの合計値を得たい場合どうすればよいのでしょうか?
603デフォルトの名無しさん:2005/05/24(火) 13:04:10
/proc の下を直接叩いたらいーんじゃない?
604デフォルトの名無しさん:2005/05/24(火) 14:38:54
pthreadを使っていないのに-lpthreadをつけてコンパイルしても問題なく走りますが、何か弊害はありますか?
605デフォルトの名無しさん:2005/05/24(火) 14:55:34
メモリーの無駄
606デフォルトの名無しさん:2005/05/24(火) 15:02:48
えーと・・・(´・ω・`)
607デフォルトの名無しさん:2005/05/24(火) 23:15:35
>>604
dlopen等でShared Objectをロードする場合なんかは要るかもね。
そいつが-lpthread必要としてたりすると動かないから。

-lpthreadはいくつかのシステムコールとかを上書きするから、
プロセス開始時に一緒にロードされてないと困ることになるはず。

昔の記憶なんで今は違ってたらスマソ。
608デフォルトの名無しさん:2005/05/25(水) 00:30:58
OSやスレッドの実装によるだろう。
609デフォルトの名無しさん:2005/05/25(水) 12:22:03
>>606
言いたいことがあるならはっきり言えよ
610デフォルトの名無しさん:2005/05/25(水) 14:13:50
>>609
チンコかゆい
611デフォルトの名無しさん:2005/05/25(水) 23:34:09
ここの住人の皆様に聞いてみたいんですが、
java.util.concurrent.ConcurrentHashMapって
(*´д`*)ハァハァできまつか?
612デフォルトの名無しさん:2005/06/05(日) 14:31:53
ハッシュ、ハッシュ!
613デフォルトの名無しさん:2005/06/06(月) 00:38:11
pthread_mutex_lockとpthread_spin_lockの違いを教えてください。
似たような感じなんですが、どう使い分けましょうか?
614デフォルトの名無しさん:2005/06/06(月) 01:08:45
>>613
ドキュメントは読んだか?
615デフォルトの名無しさん:2005/06/06(月) 01:17:26
ドキュメントといえば、これでしょね。
http://www.opengroup.org/onlinepubs/009695399/functions/pthread_spin_lock.html

The pthread_spin_lock() function shall lock the spin lock referenced by lock.
The calling thread shall acquire the lock
if it is not held by another thread.
Otherwise, the thread shall spin (that is, shall not return from the pthread_spin_lock() call)
until the lock becomes available.
この辺りは、pthread_mutex_lock()と実質的に変わらん予感。

The results are undefined if the calling thread holds
the lock at the time the call is made.
は、PTHREAD_MUTEX_DEFAULTのmutexと変わらんと思う。

で、どこが違うのだろうか...
唯一違いそうなのが、spinというくらいだから
カーネルやらスレッドスケジューラによらずクルクル回って
スピンしているのか?だしかにspinするって書いてあるが。

だからどうなの?
616デフォルトの名無しさん:2005/06/06(月) 01:23:11
>>615
そこまでわかってるなら、パフォーマンスでも比べてみると良いんじゃないかな?
617デフォルトの名無しさん:2005/06/06(月) 01:43:41
比べてもいいが
それは、たまたま、そのOSの実装でってことだよね。

一般的にPOSIXの定義として
ドキュメントのどこにもパフォーマンスのことなんか
書いていないんだが...俺が見落としているんだろうか?
618デフォルトの名無しさん:2005/06/06(月) 01:43:47
スピンロックは待ってる間もCPUを使うけれど、
スレッドをブロックさせたりとかいうめんどい処理がないので、
ごく短い時間しか待たないならむしろ効率が良い。

んじゃないかなあ...
619デフォルトの名無しさん:2005/06/06(月) 01:46:25
>>617
> ドキュメントのどこにもパフォーマンスのことなんか
> 書いていない

スレッドの仕様にパフォーマンスへの要求を含めちゃうと
いろいろよろしくないっしょ
620デフォルトの名無しさん:2005/06/06(月) 01:47:59
んー、事故解決。

lock期間が長くなりそうな場合はmutex
短い(数ステップ?)ならspin
てな感じでいいや。
621デフォルトの名無しさん:2005/06/06(月) 01:50:22
パフォーマンスが目的でspinを用意しているなら
mutexよりspinの方がパフォーマンスがよろしい(たいていは)。
ということだけでもあってもいいと思いますが。
622デフォルトの名無しさん:2005/06/06(月) 02:01:24
CPUが1つしかないマシンでスピンロックを使う利点てあるかねえ?
623デフォルトの名無しさん:2005/06/06(月) 02:04:17
何で CPU が一つしかない?
624デフォルトの名無しさん:2005/06/06(月) 03:08:28
> パフォーマンスが目的でspinを用意しているなら

んなわけねーだろ
625デフォルトの名無しさん:2005/06/06(月) 17:34:50
>>618がいい要約をやっているのに、>>621は単純化しすぎ。

626デフォルトの名無しさん:2005/06/06(月) 20:05:46
カーネル周りで使うね。spinlock
627デフォルトの名無しさん:2005/06/09(木) 22:00:52
>>626
そりゃ自分以外に頼れるものがない寂しい子だからでしょ。
628デフォルトの名無しさん:2005/06/11(土) 20:30:09
カーネル(のコア)だと sleep 出来ないからだよ
629デフォルトの名無しさん:2005/06/12(日) 12:14:51
質問なんですが
pthread_createでスレッドを作るときメンバ関数は
そのままでは入らないみたいなのでぐぐってみたところ
この関数を入れれば良いとのことでした
static void *ThreadEntry(void *ptr){
  static_cast<CLASS *>(ptr)->Thread(ptr);
  return ptr;
}
しかし、この関数で呼んだメンバ関数Threadはメンバ変数を
使うとSegmentation faultしてしまいます。
なんとかpthread_createでメンバ関数をスレッドとして
立ち上げることはできないでしょうか?
環境はFreeBSD4.11でコンパイラはg++です
よろしくお願いします
630デフォルトの名無しさん:2005/06/12(日) 12:18:58
pthread_createの呼び出し側コードを晒せ
631629:2005/06/12(日) 12:22:15
>>630
pthread_create(&tid[i], NULL, CLASS::ThreadEntry, (void *)i)
これです。"i"はスレッド番号
632デフォルトの名無しさん:2005/06/12(日) 12:24:05
最期の引数の型は?
633629:2005/06/12(日) 12:25:30
スマソ intです
634デフォルトの名無しさん:2005/06/12(日) 12:27:52
その引数の値が ThreadEntry の ptr に入ってくるってのは理解しているのか?
つまるところ
static_cast<CLASS*>((void*)i))->Thread((void*)i);
を実行していることになる。

Cの勉強しなおしたほうがいいんじゃねえの?
635629:2005/06/12(日) 12:36:17
ということは最後のところにインスタンスのポインタを入れればいいってことですよね
・・・自分のオブジェクトってどうやって取得すればいいんでしょうか
適当な関数作って引数として自分のポインタをもらうしかないのかな・・・
636デフォルトの名無しさん:2005/06/12(日) 13:42:29
うん、やはりマルチスレッド以前に
C/C++の基礎を勉強すべきだ。
637デフォルトの名無しさん:2005/06/12(日) 17:57:30
マルチスレッドのプログラムを作っているのですが、CPUの数に応じて、実行方法を変えたいのですが
CPUの数を取得する方法がわかりません。LinuxでCPU数を取得する方法を教えてください。
638デフォルトの名無しさん:2005/06/12(日) 19:22:48
>>637
リナザウしか持ってないから分からんけど、/proc/cpuinfoでも見れば
分かるんじゃないの。わかんなかったらLinux板でも行って聞いて。
ここじゃ板違いだし。
639デフォルトの名無しさん:2005/06/13(月) 00:10:08
>>635
「this」って予約語知らない奴がマルチスレッドか…こんなんだから…

関係ないが (void*) と static_cast<CLASS*>() が混ざってるのもキモイな。
640デフォルトの名無しさん:2005/06/13(月) 00:12:53
でも全部static_cast< にされたら読みたくないよね(w
641デフォルトの名無しさん:2005/06/13(月) 00:17:12
>>640 なんでだよ。
642デフォルトの名無しさん:2005/06/13(月) 00:30:39
static_cast<CLASS*>((void*)i))->Thread((void*)i);

static_cast<CLASS*>(static_cast<void*>(i))->Thread(static_cast<void*>(i))
643デフォルトの名無しさん:2005/06/13(月) 19:28:21
>>640
>>642 の様に長くなって読みづらいけど… cast の種類が明示される方がいいという考え
方もあるのだよ。
Cタイプのキャストだと、reinterpret_cast と static_cast の違いが明確でないし。

って、スレ違いスマソ。
644デフォルトの名無しさん:2005/06/17(金) 08:07:58
1年に1回くらい、>>629 と同じような質問こない?

言語がわからないようなアホは
スレッドなんてやるなって。

って会社で言ったら、
「そんなの難しいのが悪い」と真顔で反論されたことがある。
645デフォルトの名無しさん:2005/06/17(金) 12:28:36
それを簡単にするのがおまいの役目
ラッパークラスでもなんでも作りやがれや
646デフォルトの名無しさん:2005/06/17(金) 14:12:24
スレッドはラップできても言語仕様をラップするのは難しいな
647デフォルトの名無しさん:2005/06/17(金) 14:32:05
プログラマ資格制への移行が期待される今日この頃
まず最初に党員に(ry
648デフォルトの名無しさん:2005/06/17(金) 14:36:05
人命に関わるところなら導入済みだろうけど
金に関わるところですらまだ曖昧なままだし
法で縛らんとだめだろうね
649デフォルトの名無しさん:2005/06/18(土) 00:51:38
>>645
たとえ俺に役目があったとして、
お前の無努力や無能力が正当化されるわけではない。
650デフォルトの名無しさん:2005/06/18(土) 01:00:48
いくらスレッドをラップしたところでデータレースやデッドロックを意識しないで
プログラムを組むのは難しくないか?
651デフォルトの名無しさん:2005/06/18(土) 01:06:10
なんでもAPI一発でインスタントにできると思ってるWin厨の出る幕じゃねえってことだぜ。
652デフォルトの名無しさん:2005/06/18(土) 01:14:37
積分が足し算のように簡単にならないのは積分の馬鹿な仕様のせい。
653デフォルトの名無しさん:2005/06/18(土) 02:57:45
おまえが馬鹿だからだろ
654デフォルトの名無しさん:2005/06/18(土) 09:28:24
>>651
なんでもAPI一発でインスタントにできると思ってる上司に
真顔で一発でできるようにしろと言われたことがある。

まあ、技術は弱いけどマネージメントできる人だからいいんだけど。
655デフォルトの名無しさん:2005/06/18(土) 13:12:48
ここで質問したほうがいいのか?

linux の boost::thread で 400 以上のスレッドを作ろうとすると
リソース不足の例外が発生してそれ以上作れないのだが、
この上限をもっと増やすにはどうしたら良いのだろうか・・・?
656デフォルトの名無しさん:2005/06/18(土) 13:43:38
「終了しているのにスレッドが残ったまま」
とネットワークプログラミングのスレには書いてあったが、何故ここでも書かない?

thread::join()とかpthread_join()は理解できているの?
657デフォルトの名無しさん:2005/06/18(土) 13:54:04
>>655
開いているファイルを閉じる
658デフォルトの名無しさん:2005/06/18(土) 14:00:42
>>655

ごみになっているスレッドを終わらせる

>http://pc8.2ch.net/test/read.cgi/tech/1118469143/
>
>>スレッド終了してもスレッドオブジェクトが残っていて、作れなくなっていた。
>を解決するのが先だろ。なんでシステム上限を上げて対処しようとするかな……
659デフォルトの名無しさん:2005/06/18(土) 16:09:53
>656
残ったままというのはもう解決したから。
しかし、次のステップでは 400 以上平行して走らせたいのだ。
どうやら、スタックのメモリ量が関係しているらしい事までは
掴んだ・・・が、ulimit -s で少なめにしてみても、今度は
システムがスローダウンして・・・なにが起きているのやら・・・
660デフォルトの名無しさん:2005/06/18(土) 18:13:12
400以上のスレッドって…。
64CPUとか128CPUのマシンをパーティショニングせずに運用するのかな。
661デフォルトの名無しさん:2005/06/18(土) 18:42:41
カーネルパラメータ
662デフォルトの名無しさん:2005/06/18(土) 19:45:27
>>659
つーか今度はthread数の上限(ulimit -u)は解決してんじゃん(w
遅いのは仕方ないでしょ。(たぶん)CPUもメモリも喰ってんだから。
663デフォルトの名無しさん:2005/06/19(日) 02:55:00
結論:犬糞は400スレッドも満足に動かせない糞OS
664デフォルトの名無しさん:2005/06/19(日) 10:33:20
つーかswap足りないんじゃない?
空きがなくなりそうになると極端に遅くなるから。(スラッシング)
665デフォルトの名無しさん:2005/06/19(日) 11:22:13
400以上のスレッドが必要な処理ってどんななんだ?
作りがショボい or ハード/OSの選定ミスだとは思うが。
666デフォルトの名無しさん:2005/06/19(日) 12:41:49
>>665
俺も思った。何か致命的な設計仕様上の欠陥がある気がする。
667デフォルトの名無しさん:2005/06/19(日) 12:46:53
そんなに必死になって擁護しなくていいからw
668デフォルトの名無しさん:2005/06/19(日) 13:43:25
犬糞はスレッドが実行されるCPUを限定することができない糞OS
669デフォルトの名無しさん:2005/06/19(日) 22:39:24
スレッド数は問題ないでしょ。
通常のdefaultは2000超えるからね。
それ以上必要で、リソースが十分なら、ulimit -uで増やせばいいだけだよ。

メモリかスワップが足りないだけじゃない?
670デフォルトの名無しさん:2005/06/20(月) 02:47:40
別のメモリ大量マシンでも試してみた ・・・
なんか現象変わらず ・・
ulimit とかでイロイロ試すと、さっきまで
落ちていた場所では落ちなくなったものの ・・
なぜか、スレッド 300 作る辺りまではすごく
高速に生成できるのに、さっきまでエラーで
落ちていた回数を少し超えた辺りから、生成
スピードが指数関数的に遅くなり、330 ぐらい
でシステム全体のレスポンスが極端に遅く
なり ・・・ 固まった。 orz.
なんなんだこれは?
どうにも良く判らないな ・・・

カーネルにスレッド数のパラメータなんてあったっけ?
671デフォルトの名無しさん:2005/06/20(月) 02:56:32
何か致命的な設計仕様上の欠陥がある気がする
672デフォルトの名無しさん:2005/06/20(月) 02:56:48
スレッドの処理中に動的にメモリ確保とかしてないよね?
Solaris だと lockstat, truss, prstat -L あたりで何となく分かる事もあるけど、
Linux のコマンドでも同じ様なのあるでしょ。
673デフォルトの名無しさん:2005/06/20(月) 08:22:51
>>670
実装メモリとCPUパワーが足りないんだよ。
Athron 64 x 4 + Memory 32GBくらいにしてみ?
674デフォルトの名無しさん:2005/06/20(月) 08:29:45
>>670
各スレッドは何してる?
675デフォルトの名無しさん:2005/06/20(月) 10:26:25
676デフォルトの名無しさん:2005/06/20(月) 10:33:45
ども。お騒がせしたが、自己解決した。
ulimit でスタック使用量減らしたら生成できるスレッド数の限界は解決した。
沢山生成で遅くなったのは、スレッドの開放が usleep 呼び出しでできるものと
思い込んでいたのが原因だった。Windows では Sleep() で開放してたんで。
sched_yield() をいれてやったら、アッサリ 3000 以上生成できるようになった。
(ulimit でスタック使用量を 10 分の 1 にした時)
677デフォルトの名無しさん:2005/06/20(月) 11:04:55
>>676
> スレッドの開放が usleep 呼び出しでできるものと思い込んでいた

orz
678デフォルトの名無しさん:2005/06/20(月) 20:51:07
基本もわかってねぇのかよ・・・
679デフォルトの名無しさん:2005/06/20(月) 21:53:51
そんなだからWin厨って言われるんだよ・・・。
680デフォルトの名無しさん:2005/06/20(月) 22:48:26
yieldなんかに頼らないで、条件変数使って初期化終わるまで
待機させて、broadcastして一気に目覚めさせればいいのに。

WindowsだってEvent使って初期化終わるまで待機させた方が
お行儀のいいプログラムになると思うぞ?
681デフォルトの名無しさん:2005/06/20(月) 23:52:51
タイムスライスの放棄のことかよ。
これだから犬厨は。
682デフォルトの名無しさん:2005/06/20(月) 23:53:55
犬糞でもsleep(0)でできなかったっけ?
683デフォルトの名無しさん:2005/06/21(火) 00:14:15
>>676
> スレッドの開放が usleep 呼び出しでできるものと思い込んでいた

< スレッドからのCPU明け渡しが usleep 呼び出しでできるものと思い込んでいた

だろ? orz
684デフォルトの名無しさん:2005/06/22(水) 00:30:03
俺もBoost.threadでテストしてみた。
WindowsXpだと全体で5000くらいが限度みたいで、VC++でもmingwでもおなじ。
CPUはPentium-M、IA32でのスレッド上限は8192個らしいからそんなもんかもしれんが。
メモリ食いなのでリンカのメモリ設定をいじるうまくいく。
mingw-gcc なら -lW,--heap,1024,--stack,4096とか、
1秒に一回 std::string s を s+="x";するだけのスレッドを約5000個起動、
スレッド生成時は100%負荷がかかる、1秒で100個程度しか作れない。
boost::thread_resource_error例外がバンバンでたあたりで、
システム全体の調子が変になり、動作は重くは無いが、他のプロセスが起動できなくなる。
全スレッド生成後タスクマネージャは平均10%の負荷、50MBくらい使う、チクショウ、
タスクマネージャー自体がややフリーズしはじめたので、これはたぶん正確ではない。
なんにせよスレッドがいちどきに最大たったの5000程度しかうごかないのは残念だ、
しかも、OS全体で5000で、プロセスごとに5000が上限ではない、
つまり1000個のスレッドを同時に動かすプロセスは5個が限度というこった。
WIN64やらEM64Tやらなんかではどのくらいまで平気なのか気になる。かゆうま。
685デフォルトの名無しさん:2005/06/22(水) 00:35:40
(゚з゚) ♪De Do Do Do, De Da Da Da...
686デフォルトの名無しさん:2005/06/22(水) 13:18:44
>>684
> CPUはPentium-M、IA32でのスレッド上限は8192個らしいからそんなもんかもしれんが。

(゚Д゚)ハァ?
687デフォルトの名無しさん:2005/06/22(水) 15:47:51
IA-32自体にそんな制限があるわけないが、WindowsではLDTのエントリ
数が上限だった気がする。

688デフォルトの名無しさん:2005/06/22(水) 20:03:38
pthread について質問です。
OS は Linux です。

pthread_cleanup_push によってクリーンアップハンドラを登録します。
そのクリーンアップハンドラの中で、さらに pthread_cleanup_push を呼び出すことは許されるのでしょうか。

というのは、確保したリソースをクリーンアップハンドラで解放したいのですが、この解放処理に排他制御が
必要なのです。
排他処理には mutex を使っているのですが、pthread_mutex_lock の前に pthread_cleanup_push を行って
pthread_mutex_unlock を登録しているのです。
いかがなものでしょうか?

実は別スレで質問したのですが、スレ違いを指摘されてこっちに移動してきたのですが、よろしくお願いします。
689688:2005/06/22(水) 20:07:24
age忘れたので age
690デフォルトの名無しさん:2005/06/24(金) 01:10:35
メッセージキューを使用したい。
詳しく教えてはくれまいか。エロイ人。
691せめてOSくらい明記しようや:2005/06/24(金) 01:15:05
>>690
やだ。
692デフォルトの名無しさん:2005/06/24(金) 01:21:39
Xちゃんとお話したいスレッドA君、B君とXちゃんのあいだにスレッドQ太郎を置く
A君がXちゃんにお話したい時はQ太郎にお願いする
Q太郎はA君のお願いを自分のキューに入れる
B君もXちゃんにお話したい時はQ太郎にお願いする

XちゃんはA君やB君やC君がいようと
Q太郎から単純に順番にお願いをとりだすだけで済む
693デフォルトの名無しさん:2005/06/24(金) 01:27:07
>>692
Q太郎が4人くらい居たら便利?
694デフォルトの名無しさん:2005/06/24(金) 04:46:36
Q太郎はたいがい一人だなぁ
695デフォルトの名無しさん:2005/06/24(金) 04:59:07
XちゃんがQ太郎を通じて「誰かヒマな奴これやっといて」とスレッド達に適当にお願いする、
というシチュエーションはよくある。
696デフォルトの名無しさん:2005/06/24(金) 06:41:37
Q太郎はおひるね中です。
あずかったお願いも、犬に追いかけられているうちに
なくしてしまいました。
でもQ太郎は気にしません。元気がとりえです。
697デフォルトの名無しさん:2005/06/24(金) 11:15:33
NT以降でコンテキスト管理にLDT使っているOSってあるのか?
698デフォルトの名無しさん:2005/06/24(金) 22:16:59
マルチスレッド”プログラミング”の情報はWebにいくらでもあるけど
マルチスレッドのスレッド構成の指針みたいなのはWebに情報ないよね。
と思った。
699デフォルトの名無しさん:2005/06/24(金) 22:39:13
>>688
なんで、
void my_cleanup_handler(void*) {
:
:
pthread_mutex_lock(...);
排他が必要な解放処理;
pthread_mutex_unlock(...);
}
ではダメなの?

SUSにはとくにできるともできないとも記述されてないように見えるけ
ど、素直に実装したら、クリーンアップ中にpushしてももう手遅れな気
がする。
700688:2005/06/25(土) 00:51:15
>>699
その処理が汎用的な処理だから。
生きてるスレッドから呼ばれることもあるんです。
701デフォルトの名無しさん:2005/06/25(土) 00:56:18
なんでそういう処理をスレッドに後始末させるかな
702688:2005/06/25(土) 01:07:04
その処理ってのは多重ロックの実装で、ロックカウンタを操作するのに排他が必要で、それに mutex を使ってる。
ロックを獲得する関数を呼んだならば、それを解放する処理も必ず呼ばなくちゃいけない。
だからその解放処理をクリーンアップハンドラに指定するんだけど、その解放処理自身も mutex を使ってるから、
mutex の解放を確実にするため、pthread_mutex_unlock もクリーンアップハンドラにしたい。
処理を単純化して書くと、こんなかんじ。

void my_lock(void *my_resource)
{
 pthread_cleanup_push(pthread_mutex_unlock, &mtx);
 pthread_mutex_lock(&mtx);
 ロック処理
 pthread_cleanup_pop(1);
}

void my_unlock(void *my_resource)
{
 pthread_cleanup_push(pthread_mutex_unlock, &mtx);
 pthread_mutex_lock(&mtx);
 アンロック処理
 pthread_cleanup_pop(1);
}

で、

 pthread_cleanup_push(my_unlock, &my_resource);
my_lock(&my_resource);
 なんらかの処理
 pthread_cleanup_pop(1);

というわけ。
そんなにおかしなことしてる?
 
703デフォルトの名無しさん:2005/06/25(土) 10:22:27
sem_wait について質問です。
この説明は正しいですか?
http://www.linux.or.jp/JM/html/glibc-linuxthreads/man3/sem_init.3.html
引っかかる点は、「sem で指定されるセマフォのカウントが非 0 になるまで呼び出しスレッドの実行を停止する。」というところです。
「非0 になるまで」ではなくて、「0 になるまで」の間違いではないでしょうか?

あともう一点。
sem_wait は、取り消しポイントということになっています。
ということは、次のようなコードは間違いになりますよね。

 pthread_cleanup_push(sem_post, &sem);
 sem_wait(&sem);
 処理
 pthread_cleanup_pop(1);

では、スレッドがキャンセルされたときにセマフォの解放を確実にしたい場合、どのようにコーディングすればいいのでしょうか?
704デフォルトの名無しさん:2005/06/25(土) 11:41:01
> 「非0 になるまで」ではなくて、「0 になるまで」の間違いではないでしょうか?
非0であってる。
sem_waitは、セマフォが0より大きければ1減らして通過。
セマフォが0なら1以上になるまで待って、1減らして通過。
705703:2005/06/25(土) 16:19:52
>>704
なるほど。
じゃあカウンタの初期値は 1 とかにしておく、ってことですか。
ありがとうございます。
あとは取り消しポイントであることについての疑問が残るのみです。
どなたかよろしくお願いします。
706デフォルトの名無しさん:2005/06/25(土) 16:28:00
え?
sem_waitの最中に取り消されたなら、クリーンナップは要らないだろ。
707デフォルトの名無しさん:2005/06/25(土) 16:39:54
つまり、資源を取得していないうちに、開放するようなコードを書いてはいけない。
 sem_wait(&sem);
 pthread_cleanup_push(sem_post, &sem);
 処理
 pthread_cleanup_pop(1);
708デフォルトの名無しさん:2005/06/25(土) 16:42:35
>>706
問題は、sem_wait が完了した後に取り消されたときなんです。
それに備えてクリーンアップハンドラを登録しようにも、その登録を sem_wait の前でやっても
後でやっても具合の悪いタイミングが存在しますよね?
それとも、sem_wait 〜 sem_post の間には、キャンセルポイントが無いようにしないといけないという
ことなのでしょうか?
709デフォルトの名無しさん:2005/06/25(土) 16:45:50
>>708
sem_wait の後で登録したら、どう具合が悪いの?
710デフォルトの名無しさん:2005/06/25(土) 16:47:38
>>707
それだと、sem_wait がキャンセルされて復帰した場合、セマフォの獲得をしていないにもかかわらず
セマフォの解放を行ったりしませんか?

と言ってみたものの、もしや sem_wait が復帰するときというのは、必ずキャンセルされていないことが
保証されているのですね?
キャンセルされたら、sem_wait から復帰することなく、クリーンアップ処理が走る、ってことでしょうか?
711デフォルトの名無しさん:2005/06/25(土) 16:52:57
意味がわからない。
キャンセルされて復帰したとはどういう事だ?
sem_waitがキャンセルされたなら、事前に登録してあるクリーンナップ
ハンドラが呼ばれて、そのスレッドはそこで終わりじゃないのか。
712デフォルトの名無しさん:2005/06/25(土) 16:56:03
>>711
はい。理解しました。
自分でも何を勘違いしていたのか疑問です。
713デフォルトの名無しさん:2005/06/27(月) 02:16:21
orz って今の今まで、

○| ̄|_  の小さい版とは知っていたが、

四つんばいとは知らなんだ。
拳を握り、目を細めて ウググググ・・・って悔しがってるのかと思ってた。
714デフォルトの名無しさん:2005/06/27(月) 03:11:43
> 拳を握り、目を細めて ウググググ・・・
が分からん。orz
715デフォルトの名無しさん:2005/06/27(月) 03:52:26
漏れもわからん・・・
716デフォルトの名無しさん:2005/06/27(月) 04:32:17
とりあえず漏れの解釈。

顔の線
 ↓
○| ̄|_
↑ ↑ ↑
拳 目 鼻
717せめてOSくらい明記しようや:2005/06/27(月) 04:58:15
>>716

○| ̄|_  ̄|○
718デフォルトの名無しさん:2005/06/27(月) 05:01:52
伝説の予感・・・
719デフォルトの名無しさん:2005/06/27(月) 08:07:34
o/z-/b
720デフォルトの名無しさん:2005/06/27(月) 08:15:57
  @@@
 @@@@
○| ̄|_  ̄|○
  \◎/
   | | ̄|_  ○| ̄|_  orz
721デフォルトの名無しさん:2005/06/27(月) 08:59:46
>>716
見えるぞ、私にも見える!
722デフォルトの名無しさん:2005/06/27(月) 12:15:22
短足だから見間違えたんだな。
○| ̄|_
なら顔には見えまい。
723デフォルトの名無しさん:2005/06/27(月) 13:02:14
  @@@
 @@@@
○| ̄|_  ̄|○
  \ー/ ニヤリッ
724デフォルトの名無しさん:2005/06/27(月) 14:20:34
にしこり
725713:2005/06/27(月) 19:49:48
そうです。
726デフォルトの名無しさん:2005/06/27(月) 23:42:56
新キャラ誕生の瞬間を目撃!?
727713:2005/06/27(月) 23:54:47
顔の線
 ↓
○| ̄|_
↑ ↑↑
拳 目 口

これ、口だから。崩さんといて。<@
728デフォルトの名無しさん:2005/06/28(火) 00:04:57
く、口なのか?
729713:2005/06/28(火) 00:08:58
>>728
そうです。
730デフォルトの名無しさん:2005/06/28(火) 00:20:45
>>702
クリーンアップしてる間はキャンセル禁止(か遅延)にしとけば?
731デフォルトの名無しさん:2005/07/03(日) 22:45:44
クリーンナップ中にpthread_setspecific()したら
再度クリーンナップされるのはPOSIXの正しい仕様ですか?
732デフォルトの名無しさん:2005/07/05(火) 01:44:58
哲学者にレイプされました。アノ人たちにとってアタシは共有リソースだったんです。
三つの穴にとっかえひっかえ入れられて。入れてない哲学者は瞑想にふけて、
順番が来るのを待ってました。
アタシはセマフォなんて信じない。
デッドロックは無かったです。(T T)
733デフォルトの名無しさん:2005/07/05(火) 07:38:24
入れる物が一つならデッドロックはないわな
734デフォルトの名無しさん:2005/07/05(火) 09:33:43
○| ̄|_ ̄|○
735デフォルトの名無しさん:2005/07/05(火) 09:40:38
○| ̄|_ ̄|○ <デッドロックに耐えてよくがんばった!
736デフォルトの名無しさん:2005/07/05(火) 10:04:15
クラス内の関数をスレッド化することを考えています。

    for (int i=0;i<threadnum;i++)
    {
        if(pthread_create(&tid[i],NULL,(THREADFUNC)threadRoutine,(void*)i) != 0)
        {
            perror("pthread_create");
        }
    }

と書くと、3行目のところで
error: invalid use of member (did you forget the '&' ?)
というエラーが出てしまいます。

プライベートメンバ関数の
threadRoutine

void threadRoutine(void* pParam);
と宣言するところを
static void threadRoutine(void* pParam);
にすると、コンパイル可能なようなのですが、今度は、そのメンバ関数内で、staticではないメンバ変数が使えなくなってしまいます。
どのようにすればよいのでしょうか?
737736:2005/07/05(火) 10:06:02
(THREADFUNC)、tidはそれぞれ

typedef void *(*THREADFUNC)(void *);
pthread_t   tid[threadnum];

です。
738デフォルトの名無しさん:2005/07/05(火) 10:06:39
○| ̄|_ ̄|○ <スレッドよりもC/C++の勉強をしたまえ!
739デフォルトの名無しさん:2005/07/05(火) 16:20:26
○| ̄|_ ̄|○

これって、ルイ14世のAA?
740デフォルトの名無しさん:2005/07/05(火) 16:36:55
○| ̄|_ ̄|○ <私は哲学者だ。デッドロックは許さん。
741デフォルトの名無しさん:2005/07/05(火) 18:35:09
○| ̄|_| ̄|○
742デフォルトの名無しさん:2005/07/05(火) 18:41:47
○| ̄|_ ̄|○ <か、かあさん!
743デフォルトの名無しさん:2005/07/05(火) 23:37:12
○| ̄|_ ̄|○ < >>736>>629と同一人物なのか?
なんでこう同じ質問がなんども... _ ̄|○
744デフォルトの名無しさん:2005/07/06(水) 01:40:50
>>740 こんな感じでつか
                      Ψ
            ○| ̄|_| ̄|○
          Ψ                   Ψ
○| ̄|_| ̄|○           ○| ̄|_| ̄|○

            Ψ                Ψ
  ○| ̄|_| ̄|○       ○| ̄|_| ̄|○
745デフォルトの名無しさん:2005/07/06(水) 06:21:06
>>736
関数はstaticにして、クラス内の変数を使いたければ、クラス自体をその関数に
ポインタとして渡すしかない。
746デフォルトの名無しさん:2005/07/06(水) 08:56:21
>>745
○| ̄|_ ̄|○ <君もC/C++の勉強をしたまえ!
747デフォルトの名無しさん:2005/07/06(水) 09:09:19
>>736
Javaつかえ。C++はあまりマルチスレッド向きではない。
748736:2005/07/06(水) 14:25:39
ここは荒れたスレのようですね。他に行きます。
749デフォルトの名無しさん:2005/07/06(水) 14:31:45
○| ̄|_ ̄|○ <君の悩みはスレッドとは関係ないからC/C++のスレにでも逝きたまえ。
750デフォルトの名無しさん:2005/07/06(水) 14:34:21
>>748
745に答えが書いてあるではないか。
751デフォルトの名無しさん:2005/07/06(水) 14:47:59
○| ̄|_ ̄|○ <スレッドとスレッドをかけているのは絶対に秘密!
752デフォルトの名無しさん:2005/07/06(水) 16:40:00
>>750
○| ̄|_ ̄|○ >>745はクラスをファーストクラスのオブジェクトのように語っておるが…
753デフォルトの名無しさん:2005/07/06(水) 16:42:48
A| ̄|_ ̄|A <彼はクラスとオブジェクトの区別がついていないのですね。
754デフォルトの名無しさん:2005/07/06(水) 16:56:32
B| ̄|_ ̄|Bすまん、ただこれが書きたかっただけなんだ
755デフォルトの名無しさん:2005/07/09(土) 02:56:04
C言語+Windows APIを使っているのですが、  
最大化やウィンドウのリサイズを禁止するにはどうすればいいんでしょうか?  
最小化はそのまま使えるようにしたいのですが…  

756デフォルトの名無しさん:2005/07/09(土) 06:21:53
自分でメッセージ処理すればおk
757デフォルトの名無しさん:2005/07/09(土) 09:11:27
B| ̄|_ ̄|B <つーか、何スレ違いに回答してんだよ。
758デフォルトの名無しさん:2005/07/10(日) 11:52:37
Linuxオンチなんで、ちと教えてくださいまし。

- Linuxでマルチスレッド・アプリケーションとなったとき、
  pthreadは'事実上の標準'もしくは'アッタリマエ'か?

- pthradはLinuxの一部ではないが、たいていのディストリビューション
  には添付されている。という認識で正しいか?

- スレッド起こすのにはcloneとかいうsystem-callがあるが、
  こいつはコンテキストの切り替えにプロセスと同じことやる
  ので決して速くはない。は真か?
759デフォルトの名無しさん:2005/07/10(日) 12:06:00
上2つは「どのlinuxでも動くようにしたい」ということか?
最後のはよくわからんが普通にスレッド起こすのは十分速いよ。
760デフォルトの名無しさん:2005/07/10(日) 12:06:16
- 当たり前かつ標準

- pthradは一部でも添付されてもいないが、pthreadは標準

- clone(2)はpthread_create(3)を実現するためのシステムコール。
  あんたが使う類いのものじゃない。
761デフォルトの名無しさん:2005/07/10(日) 13:53:41
>>758
pthreadってのは単なるAPIのこと。
ttp://www.opengroup.org/onlinepubs/009695399/basedefs/pthread.h.html
で、UNIX系のOS上でC言語によるマルチスレッド・アプリケーションを記述するのなら、
pthread APIを使うのが「事実上の標準」。
ただし、pthread APIにはオプション的な扱いの関数などがあり、
これらは実装によっては使えないことがある。

Linux上で動作するpthread APIの実装としては、
- LinuxThreads … glibcに取り込まれたため、事実上の標準。
- Native POSIX Threading Library (NPTL) … LinuxThreadsの後継。これもglibcに取り込まれた。
- Next Generation POSIX Threading (NGPT) … NPTLの対抗馬だったが、あぼ〜ん
などがある。
ほとんどLinuxディストリビューションでは、LinuxThreadsかNPTLが使えるはず。

clone(2)ってのは、LinuxThreads、NPTLなどが内部で使ってるシステムコールであり、
アプリケーションプログラマが直接触るものではない。
762デフォルトの名無しさん:2005/07/10(日) 18:24:17
NPTLもclone(2)使ってるんだ。。。
763デフォルトの名無しさん:2005/07/12(火) 23:40:36
Win32でとある入出力デバイスをバッファ管理しながら
操作するライブラリ書いてるんだけど、
こういった場合スレッドセーフにするにはどこまでやるべき?
バッファやデバイス設定値を読み書きする所全て排他?
それともTLSでスレッド個別にメモリ確保のみ?

TLSだと複数スレッドから同一デバイスに対して
操作するときどうなるかわからんけどこれで許してもらえるかな?
仕様には特に明記されていないので、
俺様ルールでいいのかなとも思うんですが、
やっぱり普通はスレッドセーフにしないと駄目ですよね。
764デフォルトの名無しさん:2005/07/13(水) 01:38:08
デバイスへのリクエストが同期式の場合、
(つまりリクエスト呼び出し復帰時に結果が返る)
排他が必要な場合が結構ある。


765デフォルトの名無しさん:2005/07/13(水) 02:08:13
>>763
どこまでやるべきかは、前提とすべきスレッディングモデルの定義による。
話はそれからだ。
766デフォルトの名無しさん:2005/07/14(木) 01:15:07
どうしてこれは途中でデッドロックしてしまうんでしょう?
printfなどをmutexでロックしても同じでした。
初歩的なことかもしれませんが、よろしくお願いします。
#include <stdio.h>
#include <pthread.h>
void *ThreadFunc(void *pdata)
{
int i;

for (i = 0; i < 10; i++) {
printf("%c", *(char *)pdata);
}
return NULL;
}
int main(void)
{
int i;
pthread_t pthId;
char a[10];

for (i=0;i<10;i++) {
a[i] = i + '0';
pthread_create(&pthId, NULL, ThreadFunc, (void *)&a[i]);
}
for (;;) {
;
}
return 0;
}
767デフォルトの名無しさん:2005/07/14(木) 01:25:25
fflush(stdout);

とかいうオチじゃないだろうな
768766:2005/07/14(木) 02:21:27
>>767
ありがとうございます。
やってみたのですが、バッファリングの問題ではないようです。

書き忘れましたが、どうやらスレッドが終了(return)するとロックするようなのです。
ネットにあるような単一スレッドのサンプルは問題なく動いています。
_beginthreadを使った場合はこのようなことは起こりません。
なんでだろう・・・。
769デフォルトの名無しさん:2005/07/14(木) 07:16:20
>>768
何でpthIdは1個?
770デフォルトの名無しさん:2005/07/14(木) 07:22:43
joimしてない?
771デフォルトの名無しさん:2005/07/14(木) 07:29:36
>_beginthreadを使った場合はこのようなことは起こりません。
つまりCreateThread使ってるってこと?
Cランタイムライブラリを使う場合は_beginthreadを使う必要があると思うんだけど
772デフォルトの名無しさん:2005/07/14(木) 08:11:24
てゆうか
for (;;) {
;
}
ってなんだよ。
MSDOSならともかく、今時のOSで許されるコーディングじゃないぜ。
773766:2005/07/14(木) 08:37:48
>>759
返り値のIDを使わないからです。
配列にして個々にIDを入れても固まってしまいます。

>>770
メインスレッド側はjoinが必須なんでしょうか?
一応joinしてみたのですが、やはり固まります。

>>771
process.hの_beginthreadを使っています。

先ほど>>770さんに指摘されたjoinなどについて調べて、
結果的にはdetachを使用することでテストケースの場合はロックすることはなくなりました。
が、本件の方はdetachしてもロックしてしまいます。
もう少し調べてみます。
774デフォルトの名無しさん:2005/07/14(木) 10:30:59
joinしてもダメだったコードをさらせ。
775デフォルトの名無しさん:2005/07/14(木) 11:31:53
for (i = 0; i < 10; i++) {
printf("%c", *(char *)pdata);
}
fflush(stdout); <-- これ付け足したら動く予感
776デフォルトの名無しさん:2005/07/14(木) 11:51:49
>>768
> > 書き忘れましたが、どうやらスレッドが終了(return)するとロックするようなのです。

お前の言いたいのは、
・出力されません
に過ぎないのと違うのかと…

「ロック」言いたいだけと違うんかと…
777デフォルトの名無しさん:2005/07/15(金) 00:34:30
forでビジーループしちゃいかんだろ、スレッドで。

for( ; ; ) {{
  sched_yield();
}

ってして他のスレッドを動かすのが基本。

○| ̄|_ ̄|○
778デフォルトの名無しさん:2005/07/15(金) 00:48:27
>>777
> ○| ̄|_ ̄|○

○| ̄|_ ̄|○ <お前が喋れよ。登場するだけかよ!
779デフォルトの名無しさん:2005/07/15(金) 00:53:50
>>777
おいおい、それもビジーループなんだよ。
待ってるだけなら pthread_join() を使うのが基本中の基本。
大丈夫かホントに。
780766:2005/07/15(金) 01:36:12
>>776
ロックと書いたのは固まったプロセスを強制終了するのに数秒かかるからです。

先に書いた通り、ロックは防げましたし、その原因も分かりました(join、detachしてなかった)。
しかしまだ怪しい部分があります。
joinしても期待した動作という意味では「ダメ」なのでソース曝します。
ttp://kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/img/723.c
実行毎に表示される数字の個数が違いますし、最後のEndも表示されません。
joinの使い方は間違ってないと思うのですが・・・。
環境がNT4sp6、デュアルプロセッサです。
781デフォルトの名無しさん:2005/07/15(金) 02:05:19
NTでpthread、がとりあえず不思議。
782デフォルトの名無しさん:2005/07/15(金) 02:37:34
NetBSD でやったら "End" まで出たよ。
>>781 と同感なんだがどうやってるの?
cygwin?
783デフォルトの名無しさん:2005/07/15(金) 04:47:19
Linux 2.6も問題なし。
784デフォルトの名無しさん:2005/07/15(金) 09:16:06
>>766
○| ̄|_ ̄|○ <Win2kのcygwinで実行したところ一瞬で終了して以下が表示された。

01021304215360742819536074281953607428195360742819536074281953607428195360742819
53674289536748956789End
785766:2005/07/15(金) 09:35:41
仰る通り、Cygwinです。
マズイな、こりゃOSを疑うべきなのか。
それが分かっただけでも収穫です、どうもありがとうございました。
786デフォルトの名無しさん:2005/07/15(金) 10:04:31
OSつーかCygwinの問題だろう。
Cygwinは「UNIXと同じソースで動いたらラッキー」ぐらいのものだと思っ
といたほうがいい。
787デフォルトの名無しさん:2005/07/15(金) 11:08:06
いやそうなんだが、まさかこういう基本的なところでダメだとは驚いた。
コンパイルできないのはOKだが、誤動作は勘弁してほしいな。

Windows 使う場合は Windows の native thread を使えってことか。
まあ、API は pthread とそんなに違わないから (というか、たぶん
両方とも Mach の cthread の真似だよね、きっと)、wrapper ライブ
ラリ書いて pthread と Windows のどちらでも動くプログラムにする
のは難しくないよ。
788デフォルトの名無しさん:2005/07/15(金) 11:20:12
つうかNTはもうよせ、と
789デフォルトの名無しさん:2005/07/15(金) 11:24:35
cygwin、>>784で動いているやん。
つうかstdoutの排他は?
790デフォルトの名無しさん:2005/07/15(金) 11:33:14
791デフォルトの名無しさん:2005/07/16(土) 02:25:17
>>784で正しく動作しているように見えるけど何が問題なの?
792デフォルトの名無しさん:2005/07/16(土) 02:39:39
Win2kでは動くけど「NT4sp6、デュアルプロセッサ」では動かないということでわ?
793デフォルトの名無しさん:2005/07/17(日) 09:25:35
というかstdout排他してないし…
こんなのはたまたま動いているだけのプログラム。
794デフォルトの名無しさん:2005/07/17(日) 09:26:17
OSを疑うとか片腹痛い。
795デフォルトの名無しさん:2005/07/17(日) 10:26:30
>>780のコードは回りくどい方法だけど一応stdoutを排他制御してますやん。
796デフォルトの名無しさん:2005/07/18(月) 14:29:49
OSを疑うのはどうかと思うが。
cygwinを疑うのは正しい姿勢の予感。
797デフォルトの名無しさん:2005/07/18(月) 14:33:37
cygwinはイロイロやってそうだしなぁ
798デフォルトの名無しさん:2005/07/18(月) 16:54:17
>環境がNT4sp6、デュアルプロセッサです。
ってのに妙に引っかかるな。

デュアルプロセッサで、デュアルプロセッサカーネル使っていないとか
実は、cygwinはデュアルプロセッサに対応していない。とか
799デフォルトの名無しさん:2005/07/18(月) 20:53:37
> cygwinはデュアルプロセッサに対応していない

さすがにそりゃねーべ
今NTで十分テストされているとはあんまり思えないんだが、そのへんかな
800デフォルトの名無しさん:2005/07/18(月) 21:27:03
>>784だが、
うちのWinマシンはデュアルではないけどHTです。
OSからはCPU2個に見えてる状態。
801デフォルトの名無しさん:2005/07/18(月) 21:43:08
cygwinて、glibc?
なんかstdioの排他とかゆってる人いるけど、
glibcのstdioって、スレッドセーフじゃないの?
802デフォルトの名無しさん:2005/07/18(月) 21:57:01
>801
glibc じゃなくて newlib のはず。
803デフォルトの名無しさん:2005/07/18(月) 23:35:30
newlibはデュアルに対応していないというのが俺の評価。
スピンロックによる排他制御のために
x86のxchg命令によるatomicなtest&setを使っているが
これがlockプリフィックスつきでないからね。

newlib/libc/sys/linux/linuxthreads/machine/i386/pt-machine.h
のlong int testandset(int *spinlock)を見よ。

cygwinがnewlibのlinuxthreadをつかって
pthreadを実現していたらだめだろう。
これがx86 linuxというconfigureでのみ使われているんなら
関係ないんだろうけど。
それとは別にcygwinにはpthreadの実装があるから関係無いとは思うが。
正直その辺りの関係は俺もわからん。
804デフォルトの名無しさん:2005/07/19(火) 00:30:16
/* Spinlock implementation; required. */
PT_EI long int
testandset (int *spinlock)
{
 long int ret;

 __asm__ __volatile__(
   "xchgl %0, %1"
   : "=r"(ret), "=m"(*spinlock)
   : "0"(1), "m"(*spinlock)
   : "memory");

 return ret;
}


○| ̄|_ ̄|○ <ダメじゃん。 >>newlib
805デフォルトの名無しさん:2005/07/19(火) 00:48:32
あれ?xchgはLOCKプレフィクスなしでもメモリ相手ならロックかますと記憶してたが。。。
806803:2005/07/19(火) 01:04:02
ftp://download.intel.com/design/Pentium4/manuals/25366616.pdf

The XCHG instruction always asserts the LOCK# signal regardless of
the presence or absence of the LOCK prefix.

逝って来ます。
807デフォルトの名無しさん:2005/07/24(日) 21:50:22
【初心者歓迎】C/C++室 Ver.20【環境依存OK】
http://pc8.2ch.net/test/read.cgi/tech/1121644782/62
にて質問しましたがこちらのスレッドのほうが適切だと思いますのでこちらで質問させてください。

今gcc3.3.3にてスレッドを利用したプログラムを作成しようとしています。
5回程度のスレッド生成はうまくいきますが
Segmentation fault (core dumped)
が表示されてエラー終了してしまいます。
原因が分かりません。
どこがエラーの原因か指摘していただけませんか?
ソースは以下の通りです。

void *thread_test(void *tmp)
{
struct testarg baa;
//終了時にリソース割り当てを解放
pthread_detach(pthread_self());
baa.id = ((struct testarg *)tmp)->id;
baa.cmd = ((struct testarg *)tmp)->cmd;
free((struct testarg *)tmp);
printf("++++++++++++++++++++++++++++++++++++++++\n");
switch (baa.cmd){
case 1:printf("good morning\n");break;
case 2:printf("hello world\n");break;
case 3:printf("good bye\n");break;
default:printf("oh no!\n");break;
}
printf("++++++++++++++++++++++++++++++++++++++++\n");
return (NULL);
}
808807続き:2005/07/24(日) 21:51:42
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>

struct testarg{
int cmd;
int id;
};

void *thread_test(void *);

int main(void)
{
struct testarg *foo;char ss[80], *p, *pp;pthread_t threadID;int i = 0, j = 0;
for(;;){
j++;
printf("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n");
printf("%d回目\n", j);
//メモリ確保
if((foo = (struct testarg *)malloc(sizeof(struct testarg))) == NULL){
puts("malloc() error");
exit(1);
}
809807続きの続き:2005/07/24(日) 21:52:33
//自動操作

i %= 3;sleep(3);
foo->id = i;foo->cmd = i;i++;
//デバッグ用
printf("foo\nid = %d\ncmd = %d\n", foo->id, foo->cmd);
if(foo->id == -1)
break;

//クライアントスレッドを生成
if(pthread_create(&threadID, NULL, thread_test, (void *)foo) != 0){
puts("pthread_create() error");
exit(1);
}

printf("with thread %ld\n", (long int) threadID);
if(i==100)
break;
}
puts("good end");
return 0;
}
810デフォルトの名無しさん:2005/07/24(日) 22:32:54
>>807
うちでは落ちないでいつまでも動き続ける。
gcc は 3.3.5。
811デフォルトの名無しさん:2005/07/24(日) 22:43:48
pthread_detachをメイン側でやれば落ちないみたい
812807:2005/07/24(日) 23:12:26
mainでpthread_create()の後にpthread_detach()を挿入し、
thread_test()の中のpthead_detach()を削除することで解決しました。

>811さんありがとうございます。
すいませんが、一つ疑問があります。
pthread_create()の引数が取ってきたpthread_t型の変数で正しい値ならば
pthread_detach()はいつでもどこの関数でやってもいいんでしょうか?

>810さんありがとうございます。
いまバージョンアップ中です。
gcc 3.3.5にしたらどうなるかも報告したいと思います。

あと、一応私が書いたソースにはバグはなく、
Segmentation fault (core dumped) で落ちてしまうのは
gcc ver 3.3.3のせいだと考えてよいのでしょうか?
813デフォルトの名無しさん:2005/07/24(日) 23:40:18
落ちるのは gcc というより pthread の実装の違いかも。
814807:2005/07/25(月) 20:32:29
struct testarg{
int cmd;
int id;
pthread_t threadID;
};

として、
if(pthread_create(&foo->threadID, NULL, thread_test, (void *)foo) != 0){
・・・
}

void *thread_test(void *tmp)
{
struct testarg baa;
//終了時にリソース割り当てを解放
pthread_detach(((struct testarg *)tmp)->threadID);
・・・・・・
}
としたら問題が解決しました。

pthread_self()の問題だと思いますが、
原因はよくわかりませんでした。

失礼しました。
815デフォルトの名無しさん:2005/07/26(火) 00:33:54
pthreadを使ったマルチスレッドプログラムで、
あるスレッドがfcntlでファイルをロックしているとき、
同じプロセスの別のスレッドが同様にロックをしようとすると、
ロックが取得できてしまうんですか?
816デフォルトの名無しさん:2005/07/26(火) 01:31:45
>>815
fcntlはロックの所有権がプロセス単位だから。
817デフォルトの名無しさん:2005/07/29(金) 22:40:15
age
818デフォルトの名無しさん:2005/07/29(金) 23:05:36
マルチスレッドセーフとは
1.スレッドの中でスレッドを作成した場合にいうのでしょうか
2.一つのプロセスで複数のスレッドを作成した場合にいうのでしょうか。
それとも両方マルチスレッドセーフというのですか?
819デフォルトの名無しさん:2005/07/29(金) 23:07:35
1と2をどう区別していいのか教えてくれ。
820デフォルトの名無しさん:2005/07/29(金) 23:08:54
スレッドセーフの意味わかってるのか?
821デフォルトの名無しさん:2005/07/29(金) 23:34:22
1.
pthread_create(&threadID0, NULL, func0, (void *)foo);
pthread_create(&threadID1, NULL, func1, (void *)fooo);
func0()が実行されている間にメインスレッドにて新しく他のスレッドが作成される。

2.
void *func0(void *arg)
{
pthread_t theadID2;
pthead_create(&threadID2, NULL, function, (void *)arg);
}
メインスレッドから呼び出されたfunc0()の中で別のスレッドを作った。

こういうのを考えて818を書きました。
822デフォルトの名無しさん:2005/07/29(金) 23:41:49
>>821 お前にはマルチスレッドは無理。
823デフォルトの名無しさん:2005/07/29(金) 23:42:02
>>821 お前にはマルチスレッドは無理。
824デフォルトの名無しさん:2005/07/29(金) 23:42:02
>>821 お前にはマルチスレッドは無理。
825デフォルトの名無しさん:2005/07/29(金) 23:45:44
  ,j;;;;;j,. ---一、 `  ―--‐、_ l;;;;;;   
 {;;;;;;ゝ T辷iフ i    f'辷jァ  !i;;;;;  >>821 お前にはマルチスレッドは無理。
  ヾ;;;ハ    ノ       .::!lリ;;r゙      
   `Z;i   〈.,_..,.      ノ;;;;;;;;> 
   ,;ぇハ、 、_,.ー-、_',.    ,f゙: Y;;f   そんなふうにかんがえていた時期が
   ~''戈ヽ   `二´    r'´:::. `!     俺にもありました
826821:2005/07/29(金) 23:55:01
  ,j;;;;;j,. ---一、 `  ―--‐、_ l;;;;;;   
 {;;;;;;ゝ T辷iフ i    f'辷jァ  !i;;;;;  2chネラは真面目な人が多い
  ヾ;;;ハ    ノ       .::!lリ;;r゙      人を馬鹿にするようなことはないだろう
   `Z;i   〈.,_..,.      ノ;;;;;;;;> 
   ,;ぇハ、 、_,.ー-、_',.    ,f゙: Y;;f   そんなふうにかんがえていた時期が
   ~''戈ヽ   `二´    r'´:::. `!     俺にもありました
827デフォルトの名無しさん:2005/07/29(金) 23:59:51
>>821 お前には2ちゃんは無理。
828デフォルトの名無しさん:2005/07/30(土) 00:12:37
>181わぁ、書き方を間違えただけであって、正確にはだな、
マルチスレッドセーフを冒すのは、
1.〜
2.〜
それとも両方マルチスレッドセーフを冒すのでしょうか?
だと、思うのは俺だけか?
俺は、1.2.ともその可能性をはらんでいると思う
お互いを蝕むのを避けるために、踏切りの警報灯のように交互にチカチカ同期採る手法や
片方をlockさせる手法があるのでしょう
>181は気にすることはない
リアルで溜まったウサを晴らしたいヤシが吐き捨ててる場合もあるんだから
そういう肥溜めはシカトしときゃいい
829デフォルトの名無しさん:2005/07/30(土) 00:20:28
∋oノハヽo∈
  ( ´D`) 誤爆れすか?
830デフォルトの名無しさん:2005/07/30(土) 00:25:35
>>828は天然でつか?
831デフォルトの名無しさん:2005/07/30(土) 00:36:13
@| ̄|_ ̄|@ <ある関数が、複数のスレッドから同時に実行されてもハラハラしない時、

A| ̄|_ ̄|A <その関数はスレッドセーフである、とかなんとか言われるのである。

B| ̄|_ ̄|B <きっとね!
832デフォルトの名無しさん:2005/07/30(土) 01:04:39
>踏切りの警報灯のように交互にチカチカ同期採る手法

は、誤解招くから、補足しとくと、
お互いがどこまで進んだか分からないと、迂闊にお互いのデータを使えないから、同期を採って、進行度を相互確認する

それと、親プロセス、子プロセスの関係の、マルチプロセス、要はforkというのもあるけど(知っているかもしれないけど)、
これの弱点は、同じOSのshell上で動くから、処理が重くなる。だから、マルチスレッドが推奨されてるわけだけど、
利点もあって、親が終了しても、子は動き続けられる
833デフォルトの名無しさん:2005/07/30(土) 01:08:52
○| ̄|_ ̄|○ <いいからもう寝ろ
834デフォルトの名無しさん:2005/07/30(土) 11:27:37
835デフォルトの名無しさん:2005/07/30(土) 17:56:41
なんで、そんなにうなぎ連結してんの? キモイよ?
836デフォルトの名無しさん:2005/07/30(土) 20:52:17
一つだと、四つん這いと間違えるから。
837デフォルトの名無しさん:2005/07/31(日) 00:13:53
pThreadでロックをある所有が行い別のやつがアンロックを行うって方法を
使っているのですが、とても微妙な使用方法だと思うのですが改善する方法ないですか?
あとpthreadのデバッグってどうしてますか?
838デフォルトの名無しさん:2005/07/31(日) 06:37:15
>>837
君の頭を改善。
デバッガ。
839デフォルトの名無しさん:2005/08/01(月) 00:16:55
> 一つだと、四つん這いと間違えるから。

わらた
840デフォルトの名無しさん:2005/08/02(火) 20:41:39
誘導されてきました。
C言語でマルチスレッドプログラミングについて教えてもらいたいです。
問題は、
(1)簡単なスレッドプログラミング及びスレッドの動作について解説せよ。
(2)相互封鎖や相互実行が起こるプログラムを作成し、その動作を解説せよ。
(3)マルチスレッドで、turnやflagを使った排他制御のプログラムを作成し、その動作を解説せよ。
(4)消費者・生産者問題のプログラムを解説せよ。

です。宜しくお願いします。
841デフォルトの名無しさん:2005/08/02(火) 20:44:01
>>840
スレ違いです。
↓あたりへどうぞ。

内藤ホライゾンがC/C++の宿題を片付けます 49
http://pc8.2ch.net/test/read.cgi/tech/1122705615/

ぼるじょあがC/C++の宿題を片づけますYO! 48代目
http://pc8.2ch.net/test/read.cgi/tech/1121471445/
842デフォルトの名無しさん:2005/08/03(水) 02:12:13
見事な教えてクンぶりに感動すら覚えた。
誘導先でも煙たがられてるし...
843デフォルトの名無しさん:2005/08/04(木) 21:05:37
グローバル変数や静的変数をスレッドごとに持たせることって可能ですか?
変数をロックして共有するのではなく、メンバ変数みたいな感じで状態管理に使いたいんです。
errornoとかはそうなっているみたいなんですけど。
844デフォルトの名無しさん:2005/08/04(木) 21:35:41
>>543
TLS

ちと調べればすぐわかりそうな気がするが。
845デフォルトの名無しさん:2005/08/04(木) 21:38:29
単純にぐぐるとネットワーク関連の方がひっかかるので補足しておくと、Thread Local Storage な。
846デフォルトの名無しさん:2005/08/04(木) 21:50:33
>>843
"Thread Specific Data" とか "Thread Local Storage" と呼ばれるものだな。

普通はスレッドライブラリのAPIとして用意されているものだし、
最近のC/C++標準では __thread というキーワードで言語仕様にも採り入れられている。

ttp://gcc.gnu.org/onlinedocs/gcc/Thread_002dLocal.html
ttp://www.linux.or.jp/JM/html/glibc-linuxthreads/man3/pthread_key_create.3.html
ttp://www.microsoft.com/japan/msdn/library/ja/vccore/html/_core_Thread_Local_Storage_.28.TLS.29.asp
847デフォルトの名無しさん:2005/08/05(金) 00:11:19
C++で組んでたときはあんまり意識せずに書けたな。メンバ変数はデフォルトではインスタンスローカルだから
Cでも単純にスレッドごとに構造体のインスタンス別々にしてやればいいジャンとか思うの俺だけ?
848デフォルトの名無しさん:2005/08/05(金) 02:02:30
まあポインタで引っ張り回したら何だって出来るんだけど、
スレッド内関数呼び出しのそのレベルでも、
スレッドローカルな大域変数のように扱えるのが、
スレッドローカルストレージフレームワークだから…

Common Lispの*special*変数も似た風に使えるけど、
あれよりはコストが安い。
849デフォルトの名無しさん:2005/08/05(金) 03:02:18
( ´∀`) 気のせいダロ
850デフォルトの名無しさん:2005/08/05(金) 23:56:31
>846
>最近のC/C++標準では __thread というキーワードで言語仕様にも採り入れられている。
9899:1999 でも 14882:2003 でもそんなキーワードは引っかからないぞ。
つーか、__ で始まってる時点で処理系依存の拡張じゃないのか?
851デフォルトの名無しさん:2005/08/06(土) 08:55:10
>>846は、gccのドキュメントの以下の部分を誤読しているんだろう?
C99を__threadで拡張するとすると標準文書はこう変更されるってことなんだけど。

>5.51.1 ISO/IEC 9899:1999 Edits for Thread-Local Storage
>
> The following are a set of changes to ISO/IEC 9899:1999 (aka C99) that
> document the exact semantics of the language extension.

852846:2005/08/06(土) 19:43:25
>>850-851
うん、俺の勘違いだった
スマソ
853デフォルトの名無しさん:2005/08/06(土) 19:47:34
gccの__threadってなんなの?

int pthread_key_create(pthread_key_t *key, void (*destr_function) (void*));
int pthread_key_delete(pthread_key_t key);
int pthread_setspecific(pthread_key_t key, const void *pointer);
void * pthread_getspecific(pthread_key_t key);

のsyntax sugar?
854デフォルトの名無しさん:2005/08/06(土) 19:51:04
スレッドプロシージャをクラス内に実装する裏技(といっても常套手段)使えば
大域変数みたいに使うことはできる。
てかCreateThreadに渡すダミーのスレッドプロシージャにthisポインタ渡してメンバ関数を起動するだけだから。
(Win32での話)
855デフォルトの名無しさん:2005/08/06(土) 20:19:16
>>853
機能的には同じようなものだが、普通は__threadのほうが遥かに高速に動作する。

ttp://people.redhat.com/drepper/tls.pdf
上記PDFにあるように、ローダやダイナミックリンカなどと連係して
間接参照数回程度のコストで動作するようになっている。

まあ、逆に言うと、スレッドライブラリだけでなく、
ローダやリンカも対応してないと__threadは使えないってことになるが。
856デフォルトの名無しさん:2005/08/07(日) 01:27:51
さんざん既出かもしれないけど、質問します。
windowsでpthreadの状態変数みたいなのはどう実現すればよいのでしょうか?
排他変数にMutexをつかうならSignalObjectAndWaitをつかえばよいんだけれども
CriticalSectionを使いたいんです。
857デフォルトの名無しさん:2005/08/07(日) 01:30:48
状態変数に近いのはイベントオブジェクトじゃない?
858デフォルトの名無しさん:2005/08/07(日) 09:09:08
状態遷移マシンの実装を語るスレがほしいな。
859デフォルトの名無しさん:2005/08/07(日) 13:02:32
>>858
○| ̄|_ ̄|○ <オマエ「状態遷移マシン」て言ってみたかっただけだろ!
860デフォルトの名無しさん:2005/08/07(日) 13:03:24
正規表現ライブラリのソースをみるとか
マルチスレッド関係ないな
861856:2005/08/07(日) 13:18:58
> 状態変数に近いのはイベントオブジェクトじゃない?
そうなんですけど、pthreadの場合、 状態変数をwaitするとき
mutexを渡して内部でアトミックにmutexをアンロック→シグナル待ち→mutexのロックをしてて
これをwindowsで実現できないかなと・・・
WindowsのばあいMutexをWait〜系関数で待つことは出来るけど、CriticalSectionは使えない。

たとえばpthreadで状態変数をつかっているようなところを
windowsに移植するときはどうしたらよいのかなと思いまして・・・
862856:2005/08/07(日) 13:20:21
> 状態変数に近いのはイベントオブジェクトじゃない?
そうなんですけど、pthreadの場合、 状態変数をwaitするとき
mutexを渡して内部でアトミックにmutexをアンロック→シグナル待ち→mutexのロックをしてて
これをwindowsで実現できないかなと・・・
WindowsのばあいMutexをWait〜系関数で待つことは出来るけど、CriticalSectionは使えない。

たとえばpthreadで状態変数をつかっているようなところを
windowsに移植するときはどうしたらよいのかなと思いまして・・・
863デフォルトの名無しさん:2005/08/07(日) 13:51:27
aprだと、EventとMutexを使ってcond_wait/signalをエミュレートしてるね。
もちろん、cond_waitに渡すmutexはCRITICAL_SECTIONで良くて、
Mutexを使っているのはWaitForで待つためらしい。
http://apr.apache.org/
864デフォルトの名無しさん:2005/08/07(日) 14:18:12
クラス内のメソッドを並列で実行したいのですが、やり方がわかりません。どこかに参考になるページはありませんか?
865856:2005/08/07(日) 14:46:06
>>863
ありがとうございます。参考になりました。
どうやらcondに渡すのはCRITICAL_SECTIONみたいだけど、
cond内部でMutexを持っていてそれを用いて排他制御を行いつつ、
CRITICAL_SECTIONアンロック→シグナル待ち→CRITICAL_SECTIONロックしているみたい。
(apr-1.1.1\locks\win32\thread_cond.c)
866デフォルトの名無しさん:2005/08/07(日) 15:33:00
>>859
ばれたか。
でもWindowsでWindowMessageを使って実装する例とか、
専用のクラスの実装例とか、どんな問題があってどんなメリットがあるとか
そういうことを勉強したかったのもあるよ。
867デフォルトの名無しさん:2005/08/08(月) 01:01:11
pthread_cond_signal/broadcastの実装には
シグナルとウエイトをアトミックにやる必要がある。
「アトミックに」ってところが重要で
シグナルしてウエイトするというようにバラバラやっていたのではダメ。

それをする手段は、Win32だと、SignalObjectAndWaitしか知らん。
868デフォルトの名無しさん:2005/08/08(月) 03:11:15
?
869デフォルトの名無しさん:2005/08/09(火) 16:17:47
mutex といえば、Boost.Thread の Win32 版 mutex の実装に、
CRITICAL_SECTION ではなくて、Mutex が利用されていたな。

Win32 の Mutex は遅いから、メータードセクションを利用して
実装して欲しかった。
870デフォルトの名無しさん:2005/08/09(火) 19:11:37
>>869
今1.32のソース見たけど、クリティカルセクション使ってたよ
871デフォルトの名無しさん:2005/08/09(火) 20:12:15
>>869
メータードセクションってこれ何時頃から実装されてるの?
MSDNみて、こんなの有ったのかと目から鱗状態なんだけど。
95でも使えるっぽいから、相当前からある様なんだけど。
872デフォルトの名無しさん:2005/08/09(火) 21:36:20
自己レス。
APIとしてSDKに実装されてるわけじゃないのね。
MSDN英に.hと.cのフルソース上がってたからもらってきた。
mutexと置き換えて遊んでみる。>>869ありがと。
873デフォルトの名無しさん:2005/08/10(水) 15:20:21
うろ覚えだが、メータードセクションは、ロックカウントを持っていないので、
クリティカルセクションのつもりでリソースを1にして、
同じスレッドで複数回 EnterMeteredSection すると、あとあと面倒だったかも。
874デフォルトの名無しさん:2005/08/16(火) 18:00:27
メータードセクションなんで初めて知ったよ
みなさんスゴイすね
875デフォルトの名無しさん:2005/08/21(日) 13:45:16
>>873
それなら自分でReentrantな実装にしちゃえば?
876デフォルトの名無しさん:2005/08/22(月) 16:00:40
メータードセクションのReentrantな実装に改良している最中に、
以前AdvancedWindowsのオプテックスを
セマフォ的にしたものを作ったのを思い出した。orz

とても不毛な月曜の午前。
877デフォルトの名無しさん:2005/08/26(金) 14:48:45
基本的な質問します。
stringとかのポインタをスレッドに渡し、スレッドより先にメインが終了してしまった場合、
そのstringはもう生きていないですよね。
こういうときはどうやって処理をすればいいのでしょうか?
878デフォルトの名無しさん:2005/08/26(金) 14:52:35
>>877
寿命管理ができないなら、実体で渡す。
実体渡しが嫌なら、サボらずにちゃんと寿命管理を行う。
879デフォルトの名無しさん:2005/08/26(金) 14:52:34
○| ̄|_ ̄|○ <メインが終了したらプロセス全体が終わるだろ
880デフォルトの名無しさん:2005/08/26(金) 15:11:45
がんがって実態渡ししてみます。
881デフォルトの名無しさん:2005/08/26(金) 15:44:49
メインが終了したらアプリ全体が終わっちゃうから、
スレッドでの処理が終わるまでメインを待たせろつーの。。
882デフォルトの名無しさん:2005/08/26(金) 22:18:12
○| ̄|_ ̄|○ < ああ、面倒くせーな!
883デフォルトの名無しさん:2005/08/28(日) 13:15:09
マルチスレッドアウトな関数multithreadout()があります。
この原因はグローバル変数glbを使っていることです。

通常、同一プロセス内でmultithreadout()を使うと駄目ですが、
multithreadout()をdllファイルにしてもマルチスレッドアウトのままでしょうか?
884デフォルトの名無しさん:2005/08/28(日) 14:06:11
>>883
Yes.
DLL(が読み込まれたメモリ空間) はプロセススコープの資源。
885デフォルトの名無しさん:2005/08/28(日) 14:07:04
はい
886デフォルトの名無しさん:2005/08/28(日) 14:30:37
解決する方法として
1).マルチプロセスにする。
2).multithreadout()だけをexeファイルにして引数を受け渡す(パイプを使う&dllを使用しない)
3).multithreadout()をdllファイルにし、multithreadout()呼び出し専用の
  exeファイルを作り、パイプを使う

2).3).の違いはmultithreadout()が静的か動的かなのですが、
他に解決する方法はありますか?間違った解決方法を考えていませんか?

また、処理のほとんど(90%以上)はmultithreadout()が行います。
呼び出し回数は数回程度です。
887デフォルトの名無しさん:2005/08/28(日) 14:40:34
グローバル変数を使わないように、multithreadout()を変更する
と言う選択肢もあるはず
888デフォルトの名無しさん:2005/08/28(日) 14:42:41
multithreadout() を multithreadout_real()
か何かにリネームして、
multithreadout()は、
multithreadout()
{
static CriticalSectionとかMutexとか lock;
Lock(lock);
multithreadout_real();
Unlock(lock);
}
あたりにすればいいんじゃないかと思う。
例外処理とか、lockの初期化は適当に。
889856:2005/08/28(日) 17:35:49
以前紹介してもらったaprのミューテックスなんだけど、よく見ると怪しい部分があるような気がしてきた。
broadcastのときwaitしているスレッドを数えるためにカウントしているんだけど、
イベント待ちの直後そのカウンタをインクリメントする必要があって、その部分がクリチカルになっていない。
どうなんだろう?自分は怖いんでカウンタをCRITICAL_SECTIONで囲んだけれども。
890856:2005/08/28(日) 17:46:49
あう、mutexじゃなくてconditionだった。スマソ
891デフォルトの名無しさん:2005/08/30(火) 06:42:29
signalとかbroadcast待ってる香具師ってスピンしてんの?
古いイベントで使うようなselectとかとどっちが速い?
892デフォルトの名無しさん:2005/08/30(火) 06:44:41
×古いイベント
○古いイベント志向

すまそ。
893デフォルトの名無しさん:2005/09/01(木) 23:51:20
selectって古いイベント志向といういいかたするのか?
ま、それはさておき、遅いか早いかは

実装による。

以上だ!
894デフォルトの名無しさん:2005/09/01(木) 23:51:28
selectって古いイベント志向といういいかたするのか?
ま、それはさておき、遅いか早いかは

実装による。

以上だ!
895デフォルトの名無しさん:2005/09/02(金) 00:20:22
>>893-894
ちゃんと排他制御しろよ
896デフォルトの名無しさん:2005/09/02(金) 00:41:56
この読みが外れればそれを口実に日本に戦争を仕掛けるつもりだったのか
897デフォルトの名無しさん:2005/09/02(金) 00:43:20

誤爆しました。メンゴ
898デフォルトの名無しさん:2005/09/02(金) 03:07:40
>>893-894
イベントとか割り込みって、中でselect使ってんじゃね?
899デフォルトの名無しさん:2005/09/04(日) 08:45:05
Solarisだと、select(3C)はpoll(2)を使ってる
900デフォルトの名無しさん:2005/09/04(日) 13:10:28
>>899
それは昔の話で、select(3)の実装がpoll(2)を使わないように2,3年前に変わらなかったっけ?
901デフォルトの名無しさん:2005/09/04(日) 18:49:22
そんな重要そうな事もはっきりしないのがUNIX文化ってやつですね
902デフォルトの名無しさん:2005/09/04(日) 19:39:03
selectもpollも対して変わらんよ。じゃあ
「イベントとか割り込みって、中でpoll使ってんじゃね?」
と言えばいい?
903デフォルトの名無しさん:2005/09/04(日) 21:32:12
ちゃんとCPU返してくれればどうでもいい。

たまにビジーループぶん回すのがいるからのう…

904891:2005/09/05(月) 00:08:39
>>903
えっと、まさにそこを聞きたかったんすけど。

ループしてるか見分ける方法ってある?
905デフォルトの名無しさん:2005/09/05(月) 10:46:59
>>898
んなわけねー(w

>>904
お前以外にループする奴はいない。in お前のプログラム&カーネル。
906891:2005/09/05(月) 23:58:31
何言ってるのかわかんないんだけど。
907デフォルトの名無しさん:2005/09/06(火) 14:49:26
>>899
windowsはどうなんですか?
908899:2005/09/06(火) 21:37:49
Windowsは詳しくないから分からない

というか、こんなの聞いてどうなるものでもないような
909デフォルトの名無しさん:2005/09/06(火) 22:23:37
>>891
> signalとかbroadcast待ってる香具師ってスピンしてんの?

ロックが競合したときにmutexの入口でスピンすることはあっても、
signalとかbroadcastを待ってる状態(つまり条件変数をwaitしている状態)で
スピンし続けてCPUを離さないってことはありえない。
そんな実装があったら、条件変数の意味が無くなるだろ。
910デフォルトの名無しさん:2005/09/06(火) 22:44:19
スピンとポーリングって何が違うの?
911デフォルトの名無しさん:2005/09/06(火) 22:54:37
スピン = 無期限連続ポーリング
912デフォルトの名無しさん:2005/09/06(火) 23:21:03
>>910
spinってのはSMPで一つのCPUだけがポーリング対象の資源を
得ることが出来るようなポーリングの仕方のことを言う。

皆がアクセスできる皿と、自分の手元の皿を夫々がくるくる入れ替えて
手元に来た皿に肉が乗ってたら食べていい、みたいな感じ。
913デフォルトの名無しさん:2005/09/07(水) 03:41:53
>>912
一面的な説明で「仕方のことを言う」はいかがなものか。
914デフォルトの名無しさん:2005/09/07(水) 03:55:32
>>913
文句だけじゃなくて、一面だけというのなら別の面からとか
包括的な説明とか、内容あるレスつけようぜ。
915デフォルトの名無しさん:2005/09/07(水) 07:23:03
スピンしないポーリングって可能なのか。
スレッドとかシグナルってハードレベルでどうなってるのか
わからなくて効率が全然読めないんだが、
その辺をユーザーレベルで理解できる本、サイトない?
916デフォルトの名無しさん:2005/09/07(水) 09:07:10
WindowsならAdvancedWindowsという本かな。
これ読むとWindowsでポーリング待ちなんて馬鹿げてると思うはず。
917デフォルトの名無しさん:2005/09/07(水) 09:13:54
>>916
Windowsよく知らないので、詳しく!
918デフォルトの名無しさん:2005/09/07(水) 09:14:46
最前線UNIXのカーネル
http://www.amazon.co.jp/exec/obidos/ASIN/4894711893/
Solarisインターナル−カーネル構造のすべて
http://www.amazon.co.jp/exec/obidos/ASIN/4894714582/

この辺りの本が詳しいけどね。どのOSでも基本は同じだし。
この辺りが難しいようなら、

OSの基礎と応用−設計から実装、DOSから分散OS Amoebaまで
http://www.amazon.co.jp/exec/obidos/tg/detail/-/books/4894712067/

なんかが定番になっているけれど、同期関係は記述が少ないし、
そもそもこの本は全般的におおざっぱな解説に終始するな。
919デフォルトの名無しさん:2005/09/07(水) 09:53:00
詳しく!
920デフォルトの名無しさん:2005/09/07(水) 09:54:38
分散OS ”あ萌え場”って何でしょうか?
921デフォルトの名無しさん:2005/09/07(水) 12:05:28
>>917
「Advanced Windows」嫁
あとは「Win32 マルチスレッドプログラミング」
つーかこの話で本が1冊出来るかもよ
922デフォルトの名無しさん:2005/09/07(水) 12:58:32
>>915
非SMPではspin lockなど使わずにタダのループによるポーリングで十分
(カーネルモードで、割り込みを考慮しないとして)。

また、競合するスレッド/プロセスがいない場合には、SMPだろうが割り込みが
あろうが単純ループのポーリングで十分。

効率的な点については、spin lock の一サイクルはメモリ<->レジスタ間の
値の入れ替えで完了するので、行儀良く短いクリティカルセクションから
なるコードの場合は(並列度にもよるけど)、わざわざスケジューラをいじって
スレッドをシグナル待ちにするような処理よりも単にspin lockの方が効率が良い。
923デフォルトの名無しさん:2005/09/07(水) 13:14:22
>>922
> (カーネルモードで、割り込みを考慮しないとして)。
> また、競合するスレッド/プロセスがいない場合には、

殆んどあり得ない仮定を置いて、何を言っているんだが…
924デフォルトの名無しさん:2005/09/07(水) 13:30:57
>>923
バカ?スピンロックについての話なら、普通割り込みも競合もあるけど、

915は「スピンしないポーリングって可能なのか。」って聞いてるわけで、
単に「ポーリング」って言った場合には>>922の条件は良く有ることだと
思うけど。
925デフォルトの名無しさん:2005/09/07(水) 14:06:08
ポーリング儲は糞プロセス量産してんだろうね
926デフォルトの名無しさん:2005/09/07(水) 14:22:09
ものすごい短時間しか待たないことがわかってるなら、ポーリングの方が効率いいこともあるべ。
927デフォルトの名無しさん:2005/09/07(水) 14:33:01
>>915
同期無しでただ読むだけで済むように設計すればいい
928デフォルトの名無しさん:2005/09/07(水) 16:24:15
>>921
Windowz使ってないので、「Advanced Windows」読んでも意味ないし
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`)マンドクさくなるしデッドロックの危険も出てくる。
一般解や俺ならこうしてるってのがあればよろ。