トップページ⇒tech
986コメント340KB

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

レス数が950を超えています。1000を超えると書き込みができなくなります。
0001デフォルトの名無しさんNGNG
マルチスレッドプログラミング相談室
0002デフォルトの名無しさんNGNG
ブロードキャストプログラミング相談室
0003デフォルトの名無しさんNGNG
ピーコとおすぎのファッションプログラミング相談室
0004無党派さんNGNG
淀川長治の冥界ホモジニアス環境プログラミング相談室
0005デフォルトの名無しさんNGNG
g++でマルチスレッドなプログラムを書くときにオススメのクラスライブラリありますか?プラットホームはUNIX全般、
コーディング目的は暇潰しです
0006デフォルトの名無しさんNGNG
>>5
暇つぶしなら自分で作れば?
0007デフォルトの名無しさんNGNG
>>6
っすねー・・。
0008デフォルトの名無しさんNGNG
環境に依存しないネタでスレッドプログラミングについて
語りたいならJavaやC#やるのが手っ取り早い。

環境依存ならWindowsが一番楽しいかも
0009無党派さんNGNG
>>5
> g++でマルチスレッドなプログラムを書くときにオススメのクラスライブラリありますか?

http://lin.fsid.cvut.cz/~kra/index.html#QpThreadとか。

ただ、libraryがmultithread-safeじゃないし、

ちなみに*BSDやLinuxは、pthreadがマトモじゃないから、

> プラットホームはUNIX全般、

は面倒。場合によっては不可能。
どこが準拠じゃないかはそれぞれのlibraryのREADMEを。
0010デフォルトの名無しさんNGNG
MT-safeがしっかりしているライブラリが揃った環境って
どういうのがありますか?
0011デフォルトの名無しさんNGNG
フリーのOSで一番pthreadがちゃんと実装されてるのって何?
まさかLinuxの分けはないよね?
0012デフォルトの名無しさんNGNG
フリーの定義によってはSolaris?(笑
0013デフォルトの名無しさんNGNG
Javaスレッドプログラミング
http://www.shoeisha.com/book/Detail.asp?bid=9
http://g.oswego.edu/dl/cpj/
http://www.amazon.com/exec/obidos/ASIN/0201310090/103-8053412-8027047

漏れには難しすぎた・・・。
オライリーから出てるの買えばよかった・・・。

Concurrency: State Models & Java Programs
http://www-dse.doc.ic.ac.uk/concurrency/
http://www.amazon.com/exec/obidos/ASIN/0471987107/103-8053412-8027047

↑おもしろそう・・・。
0014デフォルトの名無しさんNGNG
>>11
FreeBSD3.xと、Linux2.0.xではLinuxの方がよかった。
IRIXもわりとしっかりしてた。
NetBSD、OpenBSDは全く知らん。
スレッドまわりは、OS・カーネル・ライブラリ(libcとか)での差が激しいので、
環境の違いが少ないWin32プラットホームが一番やりやすい。
0015デフォルトの名無しさんNGNG
やっぱりSolarisですか・・・
001614NGNG
>>15 猛烈に同意。でも、Solarisはカーネル以外の部分を含んだシステムと
しては、使いづらい。
0017デフォルトの名無しさんNGNG
fork !!!!
0018デフォルトの名無しさんNGNG
Win32の話ですが
InterlockedIncrement()はなんでガードしないと行けないんですか?
4バイトのインクリメントならアセンブラでincとかになるから、
ロックはいらない気がするんですが。
0019デフォルトの名無しさんNGNG
ちなみにLinuxのcloneって関数、あれforkなんでしょ?
0020デフォルトの名無しさんNGNG
>>18
たぶんX86以外のプラットホームで問題が起きるからでしょ。
X86ならメモリの値をインクリメントする命令があるけど
RISCはそんな複雑な命令なさそうだし。
winbase.hでもInterlockedIncrement()の定義の前は
---
#if (defined(_M_MRX000) || defined(_M_ALPHA) || (defined(_M_PPC) && (_MSC_VER >= 1000))) && !defined(RC_INVOKED)
---
ってなってるし。
0021デフォルトの名無しさんNGNG
一番揃ってるのはwin32っぽいですね。
unixだとスレッド使うよりpiped forkやIPC使ったほうがよさげな気がしませんか。
0022デフォルトの名無しさんNGNG
非Win32な環境でスレッドローカル変数を効率的に扱うにはどうすればいいでしょうか?
pthread_[gs]etspecificなんていちいちやってられないし…
0023デフォルトの名無しさんNGNG
windowsはプロセス起動がunixに比べて重過ぎるから、
仕方無くスレッドが発展したらしい>21
0024デフォルトの名無しさんNGNG
forkがcloneで実装されてるってだけですね
0025デフォルトの名無しさんNGNG
posixあげ
0026無党派さんNGNG
>>19
> ちなみにLinuxのcloneって関数、あれforkなんでしょ?

メモリ空間とか共有するリソースがあるfork。BSDのrforkに似ている。

で、threadは特殊なprocessだから、
signalのsemanticsがpthreadとちょっと違う。ただ違うのはここだけ。

linuxthreadsのREADMEより、
- Signal handling does not fully conform to the Posix standard,
due to the fact that threads are here distinct processes that can be
sent signals individually, so there's no notion of sending a signal
to "the" process (the collection of all threads).
More precisely, here is a summary of the standard requirements
and how they are met by the implementation:
(略)

*BSDよりはPOSIX conformance度は高い。
0027無党派さんNGNG
>>21
> 一番揃ってるのはwin32っぽいですね。

そんなことはない。スケジューラとか非常に貧弱。
POSIX 4相当(準拠でなくてもいいが)には全然足りない。
0028無党派さんNGNG
>>22
> 非Win32な環境でスレッドローカル変数を効率的に扱うにはどうすればいいでしょうか?
> pthread_[gs]etspecificなんていちいちやってられないし…

これは必要な時に使うもので、必要でなければ使わなければ良い。
どう利用するかによって、どうすればいいかは変わってくるから、
これ以上答えられない。
0029デフォルトの名無しさんNGNG
>>24
え?それはぎゃくじゃない?
sys_cloneからdo_fork呼んでるように見えるけど。
arch/i386/kernel/process.cなんか見ると。
おれの勘違いだったらごめん
0030デフォルトの名無しさんNGNG
>>27
スケジューラって具体的に何を指してますか?
あと、POSIX4相当であれば十分、というのは何を根拠にしてます?

自分が必要だなーと思う基準ですが:
- 周辺ライブラリ(libc含む)がMT-safeかどうかを考慮されたもので構成されているか
- それらがOSからのサポートを受けているものか(ユーザーが作ったwrapperではなく)
- それらの情報が揃っているか
- 実際に役に立つライブラリがあるか(藁

というのを考えると、一番win32、時点SolalisもしくはJava じゃないですかね。
単一ベンダが OS、開発環境、アプリケーション作ってりゃ当たり前なんですけども。

OSオタクでなく、実際にアプリケーションを書いている人の意見を求めます。
003130NGNG
"であれば十分" → "であることが必要"
ですねスミマセン
0032デフォルトの名無しさんNGNG
>>13
その本面白そうだね。
Javaやる人って必ずGoFやると思うんだけど、
あれやっても構造に関しては一応それらしいものが作れるようになりましたって
なるけど、Javaの利点の一つのクラスにスレッドを簡単に割り当てられる、
これをどう活用したらいいのか?これにはあんまり参考にならないんだよね。

買ってみるかな。評者の★の数が全部満点なのがなんか怪しいがw
0033デフォルトの名無しさんNGNG
>>18
読み込み→インクリメント→書き込みのフェーズになるから、SMPではロックし
ないと他のCPUと競合する可能性がある。NTじゃなきゃ起きないけど。
0034無党派さんNGNG
>>30
> あと、POSIX4相当であれば十分、というのは何を根拠にしてます?

そんな事言ってない。「一番揃っている」のはwin32じゃないと言っただけ。
Solaris 8はPOSIX 4をほとんど実装しているが、win32はそうではない。

>>21
> 一番揃ってるのはwin32っぽいですね。

という文章に対してさ。

それ(一番揃っている)を要件にすると、

> というのを考えると、一番win32、時点SolalisもしくはJava じゃないですかね。

一番Solaris、次点win32、その他、
Javaはplathomeによる(VMの完成度が違うので)、じゃないかな?
(MacOS X, AIX, Tru64などマイナー系は省いた)

> というのを考えると、

って言ってるけど、新しく要件作れば、そりゃどんな順序にでも出来るでしょ。
俺は>>21の「一番揃ってる」に対して言ってるんだよ。頼むぜ。わけが分からん。
そもそも発端の>>11の"freeの"からも外れていってるしさ。

> スケジューラって具体的に何を指してますか?

スケジューラですけど?

>>30以外関心ないかも知れないのでsage
0035デフォルトの名無しさんNGNG
>>30の基準から考えるとマイナーながらBeOSが一番揃ってるね。
0036デフォルトの名無しさんNGNG
>>35
BeOSはあるバージョンアップのときに、大きな変革をやらかしたおかげで
既存アプリが大打撃を食らったそうだ。Mediaなんとかだっけかな。

そういう意味での安定性も必要だと思う。
0037デフォルトの名無しさんNGNG
>>34
POSIX準拠って何か役に立つの?
もしかして、すっげーくだんねえ話してる?
0038デフォルトの名無しさんNGNG
POSIXに準拠したスレッド、バリバリ使ったアプリとかあるの?
あるならおせーてくれ!
0039デフォルトの名無しさんNGNG
スレッドと言ったらやっぱりNTでしょ
Linuxは、スレッドは実装してないんでは???
0040デフォルトの名無しさんNGNG
POSIXは今後出てくる(であろう)OSに対する設計方針としての
標準インターフェイスを目指してるのかもしれないから、
既存のOSが準拠すべきものではないのかも。

POSIXに準拠していようがしてなかろうが、最終的にはその
実装、性能でしょ。SMPに対するスケジューリングの効率。
沢山プロセッサの乗ったマシンなんて使ったことないから
分からないけどNTのスケジューリング悪くないらしいよ。
聞きかじりの話だからあてにならないけどさ。
0041無党派さんNGNG
>>37
必要ない人は、別に気にする必要ないんじゃないの?
必要ない人に話しても(゜Д゜)ハア?でしょ。

>>40
SMPのscaleだけ話してるわけだよね。
それだけが要件の人は、それだけ考えればいいんじゃないのかな?
それだけを要件にしてもSolaris>>NTだけどさ。

けど、スケジューラの機能ってそれだけじゃあないよ。(1CPUの時でさえ)
NTの場合は、まともなdatabse構築する場合には、
kernelのsource codeが必要になって、スレッド関連だとスケジューラをいじることになる。

(゜Д゜)ハア?な人は必要ないということだから、この点について考える必要がない。
>>30が言っているように、判断は総合的にすればいい。

いずれにせよ、>>10,11にはSolaris, source code付きを勧めるよ。

http://www.sun.com/smcc/solaris-migration/docs/courses/threadsHTML/contents.html
http://www.sun.com/software/white-papers/wp-realtime/
このくらいは読んだ方がいいよ。> thread語りたい人
004211NGNG
>無党派さん
>いずれにせよ、>>10,11にはSolaris, source code付きを勧めるよ。

どーもーです。
たった今からダウンロード開始します。
バイナリの方はインテル版だけですが・・・
ところでこれってFreeSolarisをダウンロードすれば
カーネルのビルドができるんですよね?

http://www.amazon.co.jp/exec/obidos/ASIN/0130224960/ref=pd_sim_fb_dp_1_1/249-1864945-9054761
ついでにこれも注文しました。
0043デフォルトの名無しさんNGNG
Sunはスレッドをsuspend/cancelしたがる癖があるんだよなあ。

pthreadでは穏やかになってるけど、いちいちcancellableかどうか調べるのか?
http://www.sun.com/smcc/solaris-migration/docs/courses/threadsHTML/cancel.html

Javaでもsuspend/cancelを導入した前科があるね。
http://java.sun.com/j2se/1.3/docs/api/java/lang/Thread.html
0044デフォルトの名無しさんNGNG
話変わっちゃうんだけど、自前でセマフォって作れるの?
俺、頭悪いから良く分からないんだけど、どうなの?
0045デフォルトの名無しさんNGNG
>>44
とりあえず入手が楽なlinuexthreadsかpmpthread(*BSD)のsourceでも眺めてみたら?
linuxthreadsにはsemaphore.cってのがあるよ。
0046デフォルトの名無しさんNGNG
>>43
Javaのthread仕様は、pthread規格策定時の研究が反映されてなかったね。
0047デフォルトの名無しさんNGNG
だれかソース見せてもらえませんか?
0048デフォルトの名無しさんNGNG
zthread はどうよ?
http://www.cs.buffalo.edu/~crahen/projects/zthread/
0049デフォルトの名無しさんNGNG
>>47
ブルドックが出てくるよ
0050デフォルトの名無しさん01/08/29 23:03ID:ufAQmXP2
signal()でSIGALRMを補足して関数を実行させる事を
マルチスレッドで行いたいのですが、うまくいきません。
スレッドではなくプロセスが補足してしまうからなのですが
これをスレッド毎に行う良い方法は無いでしょうか?
できれば参考となるソースが読みたいのですが
なかなかありません。
0051デフォルトの名無しさん01/08/30 00:01ID:C3TsWUik
>>50
OSは?thread libraryは何か分かる?
0052デフォルトの名無しさん01/08/30 00:11ID:MsTaBnpA
遅レスで C++ のライブラリ
http://www.cs.wustl.edu/~schmidt/ACE.html
00535001/08/30 08:25ID:ZcipkBQk
>>51
OSはLinuxで、thread libraryは、POSIX.1c
です。
0054デフォルトの名無しさん01/08/30 14:00ID:C3TsWUik
>>53
> OSはLinuxで、thread libraryは、POSIX.1cです。

linuxthreadsなのかな?
linuxthreadsは、規約にあってないところがあって、それが>>50とも関連していると思います。
詳しくはREADMEをの最後の辺りを読んでください。>>26も。

それから、この制限はlinuxthreads自体に由来するのではなく、
clone(2)自体に由来しますから、他のthread libraryを使っても駄目です。
close(2)を使わないuser level threadであるpmpthreadsも芳しくありません。
0055IDEなんてクソ01/08/30 22:01ID:ZAelFQ6s
pthredとBSD系のシグナルは競合するから同時に使わない方がいい。
ついでに言うと、pthreadでシグナルは極力使わない方がいい。
どうしても使いたいときはシグナル受信スレッドをpthredのシグナル関数群を
使って実装して、他のスレッドはシグナルを受信しないようにマスクする。
このあたりはアスキーから出ている実戦マルチスレッドプログラミングを
熟読するとわかると思うよ。
0056デフォルトの名無しさん01/08/31 01:50ID:JrJLvbeM
>>55
> ついでに言うと、pthreadでシグナルは極力使わない方がいい。

つーか、かなり注意して使わないと、ってことじゃないかな。
同期し協調して動くthread群に、非同期で割り込んでくるわけだからね。
「どうしても」以下に書いてあるような工夫を応用毎に考えないと。

ダグ何とかさんのJavaのthreadの本もいいよね。高いレベルの設計話としては。
00575001/08/31 20:34ID:rIUxoozo
>>51
>>54
>>55
>>56
返事遅くなりました。
情報どうもです。なるほど〜、やっぱりマルチスレッドでの
シグナルは難しいしバグの温床にもなりやすいので
やらんほうがいいわけですね。私もあの後いろいろ
本を調べてみたのですが、シグナルハンドラ用のスレッド
を別途設けて他スレッドからのシグナルを全てその専用
スレッドで取り扱うようにするのが一般的みたいですね。
この場合不思議なのは、どのスレッドから発せられた
シグナルかを区別しないといけない場合どうやって区別
するのかということです。
0058 01/08/31 23:34ID:K2I6K2jM
シグナルを受け取ったプロセスは、終了するのが基本だったんだけど
いつのまにか、プロセス間の通信に使われるようになって
おかしなことになってる。
0059デフォルトの名無しさん01/08/31 23:34ID:JrJLvbeM
>>57
> この場合不思議なのは、どのスレッドから発せられた
> シグナルかを区別しないといけない場合どうやって区別
> するのかということです。

signalはそういう機能(発信元告知)を提供してくれない。
けど、process内部のthreadからのsignalならば、
process内の事は自分で管理できるよね?

いずれにせよ、本当にsignal、つまり非同期的である必要があるのか?
必要があるとすれば、受け手側が割り込まれていいのはいつか?
signalは同時多発的に起きるかどうか?
なんて事を考えないといけないわけだけど、
よくよく考えると最後の部分は「割り込み」でやるんじゃなくて、
同期的にやった方が簡単だよね? (もちろんそれでいい場合は)
lockを保持したまま割り込まれちゃう事なんかを考えると。

pthread_cancelについて調べると、この辺の設計の指針が得られると思うけど。

> 本を調べてみたのですが、シグナルハンドラ用のスレッド
> を別途設けて他スレッドからのシグナルを全てその専用
> スレッドで取り扱うようにするのが一般的みたいですね。

となる理由も良く分かるだろうし。
0060これ定説?01/09/01 00:05ID:8UdnvL3A
Javaスレッドはクソ
00615701/09/01 00:47ID:YEBV7iy6
>けど、process内部のthreadからのsignalならば、
>process内の事は自分で管理できるよね?
ふむ、何となくわかった気もする。

>pthread_cancelについて調べると
これ調べてみますです〜。
0062IDEなんてクソ01/09/01 01:11ID:N2P03Y3g
UNIX歴長い人はすぐにシグナル使うけど、
マルチスレッドを使う場合は、極力シグナルを
使わない。素直にmutexを使った方がいいと思う。
プロセス間で通信する場合は、共有メモリでやれば、
シグナルより柔軟にできる。
それが難しいなら、マルチスレッドではなく古典的な
マルチプロセスでやったほうがいいよ。
0063デフォルトの名無しさん01/09/01 01:40ID:/npc6JZk
>>60
> Javaスレッドはクソ

メモリ管理しないでいいところとか、
VMに囲われていてOSのnative API使えないところとか、
thread programmingのいやらしいところに首突っ込まないですむから楽。

もちょっと過去の研究の成果を踏まえて欲しかった部分もあるけど。
0064デフォルトの名無しさん01/09/05 22:39ID:6B5pO.k2
>>60
定説。synchronizeキーワードが特に酷い。

いわゆる普通のthreadでなので、その点においては、
プログラミングの上で特に楽になるということはない。

むしろ中途半端な仕様のせいで混乱する可能性が高い(yieldのタイミング等)。
初心者には勧められない。

利用者に徹するなら問題ないと思うけど、それは他の言語(系)でも同じ。
提供者になるなら、標準パッケージのソースは一度見ておくこと。
嫌になるよ。
0065デフォルトの名無しさんNGNG
13の本はとってもいい本だったYO
0066デフォルトの名無しさんNGNG
マルチたん・・・
0067デフォルトの名無しさんNGNG
>>64
>標準パッケージのソース
っていうのは、java.lang.Thread.javaのことではない?
見てみたら、nativeばっかりで、実体はわからなかった。
>synchronizeキーワードが特に酷い
というあたり、少し具体的に教えてもらえませんか。
0068デフォルトの名無しさんNGNG
>>67
>っていうのは、java.lang.Thread.javaのことではない?

たとえば、PipedInput/OutputStreamとか。

synchronizedについては...

1: protectedなメソッドが継承クラスでsynchronizedになっちゃった。
という状況で何が起こるか考えてみよう。

2: synchronizedで待ってるスレッドを中断させることができるか
できないか、について考えてみよう。
0069デフォルトの名無しさんNGNG
Σ(゜д゜lll)ガーン  沈み掛けてる
0070デフォルトの名無しさんNGNG
>1: protectedなメソッドが継承クラスでsynchronizedになっちゃった。
>という状況で何が起こるか考えてみよう。
クラスを使うがわの認識不足でバグがでる可能性がある

>2: synchronizedで待ってるスレッドを中断させることができるか
>できないか、について考えてみよう。
プログラミングテクニックが必要だけど、できる
0071デフォルトの名無しさんNGNG
ファイルロック使うんだと。
ださすぎ。
0072デフォルトの名無しさんNGNG
>>70
synchronizedでlockを得られないで待っているスレッドを中断させる
のは一般には、できないことになってるけど、どうやるの?
0073デフォルトの名無しさんNGNG
javaさぱーりだけど興味有り監視中
0074デフォルトの名無しさんNGNG
wait/notifyを使ってsynchronizedと同等の動作を作り込んでやれば、待っているThreadの中断も可能。
っていみじゃないかな。
0075デフォルトの名無しさんNGNG
synchronizedで待っている、というのは大前提じゃないのか。
とりあえず、sage
0076デフォルトの名無しさんNGNG
>>74
wait/notifyは、そのオブジェクトのロックを持っているスレッドから
しか呼び出せない。つまり、synchronizedメソッド(ブロック)の中で
呼び出す必要がある。
0077デフォルトの名無しさんNGNG
synchronized ブロックの中で wait すればモニタ手放すんじゃ?
茶々気味だが...
0078デフォルトの名無しさんNGNG
つーか、wait/notify と Thread#interrupt() か。
0079デフォルトの名無しさんNGNG
>>74
> wait/notifyを使ってsynchronizedと同等の動作を作り込んでやれば、待っているThreadの中断も可能。
> っていみじゃないかな。
synchronizeキーワードは使うなって結論?
0080デフォルトの名無しさんNGNG
元の問題は、
>2: synchronizedで待ってるスレッドを中断させることができるか
だろ。
この意味は、synchronizedメソッドまたはブロックに入るために、
ロックの獲得を試みて、得られなく(他のスレッドが持っている)、
待っている、ということだよね。
こんな状況で、どうやってwait/notifyとかできるのよ。
0081デフォルトの名無しさんNGNG
だからモニタ持っているスレッドが wait すればモニタ手放して別の
スレッドが synchronized ブロックに入るじゃん。
0082デフォルトの名無しさんNGNG
ていうかマルチスレッド難しすぎ。
ここの人達がどれだけマルスレッド使いこなしてるのか疑問。

ていうか難しいと思ってるのは漏れだけかな(自爆
0083デフォルトの名無しさんNGNG
初歩的質問で悪いんだけど、マルチスレッドで気をつけることの、
・変数を保護しないと、途中で値が(他のスレッドにより)変更される事がある。
っていうのは分かるんだけど、
・リエントランスを防がなくてはいけない。
ってどういうことなの?
0084デフォルトの名無しさんNGNG
>>83
 状況をもっと書いてもらった方がいいと思うけど?

 リエントラントを許してもマルチスレッドにする方法はあるけど?
0085デフォルトの名無しさんNGNG
>>82
マルチスレッド自身は別に難しくもなんともないよ。
javaの実装がヘタレなだけ。
0086デフォルトの名無しさんNGNG
>1: protectedなメソッドが継承クラスでsynchronizedになっちゃった
そもそも設計ミスを言語仕様のせいにしてるところが問題なのでは?

>2: synchronizedで待ってるスレッドを中断させることができるか
できないけど
なんの問題もない

これが問題だと思ってるなら、才能が無いと思って
プログラマーやめた方がいいと思うよ
0087デフォルトの名無しさんNGNG
他人の設計ミスをかぶらなきゃいけない
締め切り間近の追いつめられたプログラマもいたりして
0088デフォルトの名無しさんNGNG
>これが問題だと思ってるなら、才能が無いと思って
>プログラマーやめた方がいいと思うよ

こんなことをいうのは802だけだから気にしなくていいよ
0089デフォルトの名無しさん NGNG
やめちまえ!!

なんか昔の職人さんみたいw
0090デフォルトの名無しさんNGNG
才能が無ければ普通はやめた方がいいと思うが
それとも、プログラミングが一番得意だったりして(笑)
0091デフォルトの名無しさんNGNG
じゃあ、802師匠は大学院生にもなって童貞ですけど男をやめたほうがいいのでしょうか?
それともオナニーが一番得意だったりして(藁)
0092デフォルトの名無しさんNGNG
板違いかも知れませんが御案内です。
クロスポストですみません。
今、801板で2ちゃんねるの有志が集まった同人ゲームの
開発が進んでいます。
801板住民で本気でボブゲを作るスレッド2
http://www2.bbspink.com/test/read.cgi?bbs=801&key=1001692226
主人公「ひろゆき」(名前変更可能) が周囲の少年・青年を
調教していく801Hゲームです。
現在、プログラムの方も募集中ですのでもし興味をもたれたら
のぞいてみてください。
0093デフォルトの名無しさんNGNG
磨・屡・稚・棲・麗・怒!
0094デフォルトの名無しさんNGNG
>>68
2についてはsynchronizedで待っているスレッドは原則として中断できない。
(Thread#stopで停止はできるが、これは危険!)
ただし、synchronizedとwait,notifyを使って中断可能な
mutexやセマフォを作ることは可能。
(当然synchronizedを使うが、どのような状況でもsynchronizedで長期間ブロックしないように実装すればよい)
...というのが正解。

1についてはsynchronizedメソッドをfinal指定するか、
もともとsynchronizedしなくてもいいように読み出し専用
オブジェクトにしてしまうというのも手だな。
java.util.Collectionsなんかがやってることも参考になるので見てみれ。

Javaスレッドの正しい使い方、問題点は以下のリンクを参照。
外人の言う事はためになるので読め。
http://www-6.ibm.com/jp/developerworks/java/010427/j_j-thread.html
http://www-6.ibm.com/jp/developerworks/java/010302/j_j-king.html

64はパッケージのソース見れって言うけど、
移植性の高いプログラム書こうという人は
そんなことしちゃいけないんだぞー
0095横槍君NGNG
synchronized
にしているってことは
その処理をしている間は他から一切いじられては困るはず

stopで強制終了させてしまうと触られてはまずい状態のまま
同期は解除されてしまう

とゆう単純なはなしですよね。

分かっててやるぶんには問題ないのだろうけど
ほとんどアプリの強制終了くらいにしか
おいらはうまい用途が思い付かない。
そんならexit()でいいじゃんってことに、、、

ところで自分はJavaのスレッドくらいしか知らないんだけど
世の中にはもっとスゴイ便利なしくみやライブラリが
ありそうなきがするです。

※のスレッドはほにゃららで凄いんだぜ
とかほげほげで便利だぜ
とかいうのを識者にぜひ自慢していただきたい所存
0096デフォルトの名無しさんNGNG
>>95
スゴイ便利な仕組みと言えば「セマフォ」
大昔からある同期機構なのに、これさえあれば
Javaのwait/notifyのようなことはもちろん、
mutexもリードライトロックも作れる。
できないのは、タイマーや、Javaで言うyieldみたいな
スレッドのスケジューリングに係わることかな。
それ以上のレベルのことをスレッドライブラリ自体に求める
必要は必ずしもないと思うが。
こういうことは、もっと上位のライブラリか
アプリケーションで実装すればいい。
足りないのは便利なライブラリではなくて、
並行プログラミングをちゃんと理解している人間の方。

余談だけどDBのトランザクションが一番身近で
スゴイ同期機構だと思うぞ。
厨房でも理解できるし。
0097デフォルトの名無しさんNGNG
Adaのランデブーよ、今こそ復活せよ!
0098デフォルトの名無しさんNGNG
>>94
>2についてはsynchronizedで待っているスレッドは原則として中断できない。
>(Thread#stopで停止はできるが、これは危険!)
Thread#stopで、lockの獲得を待っているスレッドを停止できる、とは言えないのでは?
例えば、スレッド1がロック1を持ち、スレッド2がロック2を持っていて、
スレッド1がロック2を獲得しようとして、同時にスレッド2がロック1を獲得しようと
する、いわゆるデッドロックの状態で、別のスレッドからスレッド1のstopを呼んでも、
スレッド1は停止(中断)しない。結局、デッドロックは解消しない。
元の問いが、synchronizedで待っているスレッドを中断する、ということだから、これは
stopでもできないというのが正解では?
mutexなどの利用については、その通りだと思うけど。
0099デフォルトの名無しさんNGNG
定説1:メインスレッドから複数のスレッドを呼んではいけない。
(Javaに限らず、パターンか何かでありませんでしたっけ?)
0100100getNGNG
>>99
え、そうなの?
ワーカースレッド(代表)経由で呼べって事かい?
0101デフォルトの名無しさんNGNG
>>98
もしかして、デッドロックが起こるような状況でしか
synchronizedで待つことはないと思ってる?
010298NGNG
>>101
何かお互いに誤解があるようだね。
漏れは、「synchronizedで待つ」、の意味を、例えば、
 synchronized void doSomething(){}
というメソッドをあるスレッドが実行しようとして、thisのロックを他の
スレッドが持っているために、待たされている状況を想定している。
もちろん、ロックを持っているスレッドが、そのロックを手放せば、問題ないけど
そうでない場合に、どうか、ということ。
それ以外に、synchronizedで待つことを、問題にする理由がわからない。
synchronizedがロックの獲得を待つのは、問題、ではなく仕様。ただし、
タイムアウトの手段はない。例え推奨されないstopメソッドでもね。
デッドロックの例をあげたのは、この点を理解しやすいと思ったからだよ。
それを問題として捉えるかどうかだけど、タイムアウトが必要な場合は、
mutexとかで対応すればいい。
逆に、synchronizedの手軽さは、javaのメリット、というのが漏れの判断。
0103デフォルトの名無しさんNGNG
>>99

それはもしかして、

「UIスレッドは出来る限りロックしてはならない」

という類のこと?
0104_NGNG
Win32なんですけど、
MFC並みのC++用マルチスレッドライブラリって何かありませんか?
0105デフォルトの名無しさんNGNG
mfc並って、つまりなんもやってないどころかよけいな手間が増えるすばらしいライブラリがほしいのか?

素直にWin32 APIかpthreadつかえ。
0106デフォルトの名無しさんNGNG
CreateThreadってなんか継承とかあったりしてやたらめんどくさかった
記憶があり。ヘタレにはちとつらいな。
0107デフォルトの名無しさんNGNG
CreateThreadを直に使うことは普通ないと思う。
0108デフォルトの名無しさんNGNG
>>106
何を指して継承といってる?
0109デフォルトの名無しさんNGNG
ハンドルの継承でないの?
0110デフォルトの名無しさんNGNG
>>107 ばしばし使っとります。
0111デフォルトの名無しさんNGNG
MFC使ったってハンドルの継承の問題はあるぞ!
0112白痴NGNG
fork とスレッドは似たようなものだと思っていました age
0113デフォルトの名無しさんNGNG
>>110
C runtimeは一切使わないってことか・・・大変そう
0114デフォルトの名無しさんNGNG
C runtimeは不用意に使わないってだけだよ
0115デフォルトの名無しさんNGNG
浮動小数点も使わないとなるときついなあ
0116デフォルトの名無しさんNGNG
浮動小数点なんて使ったこと無い。
あったとしてもprintfの%出力ぐらいか。
0117デフォルトの名無しさんNGNG
TLSも不具合ありそう。
0118名無しさん@EmacsNGNG
pthreadでさあ、read(などのブロッキングするシステムコール)してる
他のスレッドに割り込んでreadをやめさせたいときは、普通どうするの?
0119デフォルトの名無しさんNGNG
>>118
なんでread止めさせたいのか判らないです。

readして物理的な待ちに入ったら内部でスレッド切り替えてるけど??
0120名無しさん@EmacsNGNG
socketから情報がくることがあるからです。
pipe/select使えばいいのかな?
ちと面倒だけど。
0121デフォルトの名無しさんNGNG
pthread_kill( reader_thread, SIGINT )
じゃなくて?
0122デフォルトの名無しさんNGNG
>>120
shutdown()しちゃえばいいじゃん
0123名無しさん@EmacsNGNG
殺したいわけではないです。
次に移らせたいのです。

pipe/selectでできましたよ。
これでいいのかな?
0124名無しさん@EmacsNGNG
pthreadでWaitForMultipleObjects(いずれか)みたいなことって
どうやればできるんだろう。わからなくて泣きそう
0125デフォルトの名無しさんNGNG
>>124
無理。だからバカみたいにスレッドを増やすしかなかったりする。
0126デフォルトの名無しさんNGNG
>>125
pthreadってたいしたこと無いんだね。
俺が作ったマルチスレッドのアプリで
WaitForMultipleObjects使ってないものはない
0127名無しさん@EmacsNGNG
WaitForMultipleObjects(すべて)なら簡単だけどね。
0128名無しさん@EmacsNGNG
同じことで悩んでる人発見
http://cocoa.2ch.net/unix/kako/975/975847617.html
0129デフォルトの名無しさんNGNG
WaitForMultipleObjects(いずれか); って、例えばどういうときに
必要なんですか?
0130名無しさん@EmacsNGNG
たとえば、入力ポートがいくつかあって、
どこかにデータが入ってきたら動作を開始するとか。

Win32のsignalオブジェクトに相当するものは
条件変数を使って簡単に作れたから、
WaitForMultipleObjectsに相当するものを汎用的に作るには、
そのsignalオブジェクトを使って
スレッド一つにつき一つずつただjoinするだけのスレッドを作って、
joinがすんだらシグナルを立てるようにすればいいのかな。

効率わる〜
もっといい手はないのだろうか。
0131デフォルトの名無しさんNGNG
シグナル用のオブジェクトを Singleton にするんじゃ
だめなんか?
0132デフォルトの名無しさんNGNG
OpenMPっていうのはどうなの?
これってPthreadと似たようなものなんでしょ?
C++で書く事も前提になってるみたいなんだけど・・・
0133デフォルトの名無しさんNGNG
>>124-130
>>131 が正しい。スレッドが個々に Signal オブジェクトを
持つのではなく、単一の Signal オブジェクトに複数のスレッド
から notify を行うようにデザインする。
0134デフォルトの名無しさんNGNG
>>133
それだとスレッドがシグナルオブジェクトを知らなければならない。
もっとシンプルに〜
0135デフォルトの名無しさんNGNG
>>134 スレッド開始前にシグナルを渡せば良いじゃん。

Thread t = new AbcThread(signal);
synchronized(signal){
  t.start();
  signal.wait();
}

てか、どこをどうシンプルにしたいの?
引数渡しすらやりたくないの???
0136デフォルトの名無しさんNGNG
スレッドってjavaだけじゃないし
0137135NGNG
複数スレッドで WaitForMultipleObjects 相当のコード:

Object signal = new Object();
Thread[] t = new Thread[10];
synchronized(signal){
  for(int i=i; i<t.length; i++){
    t[i] = new AbcThread(signal);
    t[i].start();
  }
  signal.wait();
}

public class AbcThread extends Thread{
  private Object signal = null;
  public AbcThread(Object signal){
    this.signal = signal;
    return;
  }
  public void run(){
    ...
    synchronized(signal){
      signal.notifyAll();
    }
    return;
  }
}
0138デフォルトの名無しさんNGNG
>>135
言いたいことは分かったが、
WaitForMultipleObjects(OR)みたいな美しさがなくていいなら、
pthread_cond_waitで十分できるので。
0139135NGNG
WaitForMultipleObjects がシンプルで美しいか?
まずそこら辺の美的感覚が違うな...。まぁ趣味的な
相違を深く突っ込む気もないので好きにしてくれ。
0140名無しさん@EmacsNGNG
スレッドをWin32イベントとして扱えるのは素直に
美しいと思ったが、何か偏見があるのじゃないか。
0141デフォルトの名無しさんNGNG
sleep()をVC++6.0SP5(WinNT4.0SP5)でマルチスレッドで使ってるんです。
あるマシンではsleep(2)とかが正常に動作している
(PIOボードに出力させてそれをオシロで見た結果)
のに、別のマシンでは、小さな値を渡しても10msec以下になりません。
対処法ありますか?
0142デフォルトの名無しさんNGNG
timeBeginPeriod
0143デフォルトの名無しさんNGNG
WaitForMultipleObjectsだとすっきり、かつ、美しく書けるんだが
これに相当するもののない環境って意外に多い。というかwin32だけ?
0144デフォルトの名無しさんNGNG
threadが発達してるのはwinだねぇ。
そもそも、マルチスレッドがデフォルトっていう概念は、
winが最初じゃない?
0145デフォルトの名無しさんNGNG
>141
sleep()でmsecオーダーの動作を期待することがイタい。
0146デフォルトの名無しさんNGNG
スレッドを1msec未満の時間スリープさせるなんてことは
できるのでしょうか?
WinNT+VC++で
0147デフォルトの名無しさんNGNG
>>146
割り込みをマスクしてタイマーを監視してればいいだろうが、
システム全体がパフォーマンスダウンして不安定になるだろう。
0148デフォルトの名無しさんNGNG
NTで割り込みをマスクするってデバイスドライバでもムリかも。
何をやりたいのか書けば?>>146
0149デフォルトの名無しさんNGNG
いわゆるunixだとthreadは完全に後付けだね。
machが研究的にあれこれやってたみたいだけど、
実用OS上でインプリし、かつ実用しているのはwin32が最初かも。
0150デフォルトの名無しさんNGNG
そもそも一ミリ秒以下の間隔でデータの受信が
複数のデバイスで発生したときに、アプリが
割り込ませてくれなければ、ちゃんとシステムは動かない。
どうしてもやりたきゃネットワークもハードディスクも
ないワンボードマイコンでやるしかないだろうと思われ。
0151デフォルトの名無しさんNGNG
RS232Cで送受信できるプログラム作ってます
"123456789"のcharデータを送信するプログラムと
それをスレッドで受信するプログラムを使い、テストしました
結果は
123456789
12543789 123456
などスペースが勝手に入ったり、改行したりしなかったり
順番が入れ替わったりしました
正確な受信をすることはできるのでしょうか?
お願いします
0152146NGNG
言葉足らずですみません。
【目的】
あるスレッドでパルスモータをPIOボードを通じて回したい。
【課題】
PIOボードへの出力後、スリープさせたいが、
1msec単位でしかスリープできないと、回転速度をきめ細かく設定できない。
0153デフォルトの名無しさんNGNG
forkとスレッドって代替するものなの?
forkはもういらないって事?
0154デフォルトの名無しさんNGNG
>>153
んなこたぁない
forkの方が便利な場合も依然としてある
0155デフォルトの名無しさんNGNG
>>151
まずはスレッドを使わないでちゃんと受信ができているかテスト。
0156デフォルトの名無しさんNGNG
>>152
どう考えてもマルチスレッドの質問じゃないと思われ。
0157デフォルトの名無しさんNGNG
>>153
モジュール間の結合度が低くてデータのやりとりがIPCで十分な場合、
forkを使う方がいいと思ってる。
0158デフォルトの名無しさんNGNG
メモリ空間を共有するならスレッド。
0159デフォルトの名無しさんNGNG
>>152
分かってないなあ。
正確さをあきらめるならタイトループを
ベンチマーク的に測定してテキトーに。
たぶんきれいな方形波でなく、
不揃いのパルスになる。

正しくパルスを送るんなら、そのデジタルI/Oボードに
そのパルスを発生させるICを何とかして繋ぐのが正攻法。
H8なんかはPWMとRS232を内蔵していて便利。
0160名無しさん@お腹いっぱい。NGNG
ちょっと古い話ですみません(>>18のWin32のロックについて)。

>InterlockedIncrement()はなんでガードしないと行けないんですか?

マルチプロセッサ環境で問題が出ます。
inc命令といってもリード/ライトサイクルがあり、その間に他のCPUが処
理する可能性があります。実際、マルチプロセッサマシンでそんな不具合
が起きそうなプログラムを書いて試してみてください。

非x86のときは、x86の命令に対応するものに展開される保障はありません
(>20も少し触れている)。
0161デフォルトの名無しさんNGNG
>>157
やっぱマルチプロセスもいいよね。プロセスの死亡は痛くないけどスレッドの死は
痛い。あと信頼度の低いものをまとめあげるときには、疎な結合のほうが
いいから、プロセスを防波堤として使うのも好き。

にしてもマルチプロセスのときのプロセス間の連絡って皆どうしてんの?
POSIX IPC? System V IPC? pipe? socket?

それともRPC? またはCORBAとか分散オブジェクト使うの?
0162デフォルトの名無しさんNGNG
>>161
とりあえずsocket。
0163152NGNG
>156
言葉足らずでしたか。スマソ
ステッピングモータを回すスレッド以外に、通信や表示のスレッドがあって、
モータを回す際にスリープを正確にさせたい。
0164デフォルトの名無しさんNGNG
>>163
159みれ >>159
0165152NGNG
>>164
みたけどー。
要はmsec未満のスリープはできないのね。
0166デフォルトの名無しさんNGNG
>>152
そこまでの解像度を持つタイマが必要なら
もはやNTの出る幕ではないのでは…?
リアルタイムOSとか必要なんでは? よく知らんけど。
0167デフォルトの名無しさんNGNG
[参考]マイクロ秒単位の話:
以前NT用のセントロボードの読み出しドライバーで、
割り込みの奴とストローブをCPUで監視する奴の2種類
付属している奴があった。
その注意書きに、割り込みなしの奴は取りこぼしあり
とあり、保証なしだが、全く使えないわけではなく、
テキトーもありなんだとちょっと感心した。
0168デフォルトの名無しさんNGNG
マルチメディア系のライブラリなら、
マイクロ秒単位でタイマーの監視は出来そう
でも、それをやるとCPUがそれにかかりきりで、
ほかのスレッドを動かせなかったりするんでは。
0169デフォルトの名無しさんNGNG
>>166
だから>>159見ろと何度も言われてるのに取り合わない馬鹿は
ほっといて勝手に困らせとけ。
0170デフォルトの名無しさんNGNG
>>169
165に見たと書いてるけど。。
0171デフォルトの名無しさんNGNG
>169
ただのヴァカ
0172デフォルトの名無しさんNGNG
いにしゃらいずくりちかるせくしょん
0173かなみNGNG
複数のスレッドから同じ関数を呼び出しちゃマズイですか?
関数内ではstaticな変数は使っていないんですが、、、
0174デフォルトの名無しさんNGNG
基本的にはなんら問題ない。競合問題というのはデータに対して起きるもので、
コードに対して起きるものではないから。
実は同じオブジェクトを引数に渡してて、そいつが競合してるとか?
0175かなみNGNG
ありがとうございます。
大丈夫なんですね。
0176名無しさん@XEmacsNGNG
>>173
> 関数内ではstaticな変数は使っていないんですが、、、

MT(multi-thread) safeな関数しか呼び出しちゃ駄目よーん。
例えば、UNIXだとgethostbynameはMT-safeじゃない。
gethostbyname_rがMT-safe版。
0177デフォルトの名無しさんNGNG
>>176
呼び出す周囲をMutexでくるむという手もある
すべての箇所で出来るという保証があればの話だが
0178デフォルトの名無しさんNGNG
>>173
別にマズくないです。
同じメモリ領域に、複数のスレッドで同時に書き込んだり、
あるスレッドから書き込むと同時に別スレッドで読み込んだり、
しない限り全然大丈夫です。
0179かなみNGNG
「同時に同じ領域へアクセスしなければ特に排他処理をしなくても問題ない」
と理解しましたが、それでOKですか?
0180デフォルトの名無しさんNGNG
>>176
たまに表示が化けたり原因不明のエラーを出すの得意だろ
0181デフォルトの名無しさんNGNG
>>179
同時に読み出しだけならOKです。
書き込みが混じるときは気を付けましょう。
0182デフォルトの名無しさんNGNG
>>177
ラッパー関数かけ。
0183デフォルトの名無しさんNGNG
便乗で質問させてください。
時刻の取得⇒文字列として表示、にlocaltime, ctimeを使おうと思ったのですが
スレッド安全ではないために、localtime_r, ctime_rで記述しました。

ところがコンパイルは通るものの、実行すると上記箇所にて
coreを吐いて死んでしまいます。
(localtime, ctimeで記述時の動作は、期待通りです)

Solaris8, gcc295を使用しているのですが、
"*_r"関数には、何かしらの制限等があるのでしょうか?
0184デフォルトの名無しさんNGNG
取得から表示(もしくは中身のコピー)をするまで、クリティカルセクションで挟んどけ。
mutexでもいいぞ。
0185デフォルトの名無しさんNGNG
>>183は単にメモリを確保してないと思われ。
0186デフォルトの名無しさんNGNG
萎えるな、それ。
0187デフォルトの名無しさんNGNG
>>183
とりあえず「スレッドセーフ」って読んだほうが良いかと...。
>>179
どういう構造でmulti-threadが実装されているのか理解するまでは
愚直に危うそうな資源を排他するのをおすすめします。
「同時に同じ領域へアクセスしなければ特に排他処理をしなくても問題ない」
という表現に危うさを感じます。
たとえば、排他をしないでどうやって同時でないことを保証しましょう?
0188名無しさん@XEmacsNGNG
>>179
マルチスレッドセーフって概念も理解したかどうか不安。

>>180 何でしょ?なにか用ですか?
0189デフォルトの名無しさんNGNG
localtimeもctimeもスレッドセーフだと思うのは俺の気のせいか?
0190デフォルトの名無しさんNGNG
*_rは、結果文字列バッファを引数で渡すので、ちゃんと確保してればスレセーフ。

フツーのlocaltimeとかctimeとかは、ライブラリ内部の?共通バッファに
結果を展開するので、別のスレで使われると、書き換えられる可能性がある。
ということじゃなかったかな?

まあ、あんまりセーフかどうかを気にしなくてもいいのかもしれんが、建前上はスレセーフではない。
0191_NGNG
VCだと*_rがないけど、マルチスレッドライブラリのリンクで
保障されるのかな
0192183NGNG
皆様のご指摘どおり、メモリを確保していないために
起きた現象でした。

メモリ確保をすることによって無事解決をしました。
ありがとうございます。

メモリを確保する必要があるのですね、知りませんでした。
その必要性は、以下のような解釈でよろしいですよね。。。

localtimeは、関数内static領域を保持することを前提に設計された関数であり
localtime_rは代替関数である。この関数はライブラリ内部の共通バッファを
使用しないことによってスレッドセーフを実現しているため、当然
自前でメモリを確保する必要性がある。
0193デフォルトの名無しさんNGNG
>>191
VC++の場合、マルチスレッド用のランタイムは内部で
動的なバッファを確保してる。
0194デフォルトの名無しさんNGNG
VCはランタイムライブラリの持つグローバル変数は全部TLS(スレッドローカル領域)
なので、大丈夫だよ。>>191
0195デフォルトの名無しさんNGNG
全部じゃないだろ。そんなことしたら排他制御もできん。
0196デフォルトの名無しさんNGNG
排他制御はOSの機能でやってるんでしょ
ま、「全部」ではないと思うが
0197デフォルトの名無しさんNGNG
質問よろしいでしょうか?
常駐処理をスレッドで作成しています。
スレッドが終わった場合に、もう一度起動するように
しようとしているのですが、
終わった筈のスレッドなのにGetExitCodeThreadでのコードが
STILL_ACTIVEになってしまいます。
何かおかしいでしょうか?コードは次のようなものです。
よろしくお願いします。

void main()
{
  〜略〜
 while(1)
  GetExitCodeThread( (HANDLE)hThread, &ExitCode );
  if( ExitCode != STILL_ACTIVE ){
    hThread=_beginthread( ThreadProc, 0, (VOID *)NULL);
  }
 }
}

void ThreadProc( void *p )
{
  /*処理*/
  return;
}
0198デフォルトの名無しさんNGNG
mainもThreadProcも戻り値必須だボケ
0199194NGNG
>>195 全部ってのは言いすぎでしたん。スマソ
0200デフォルトの名無しさんNGNG
てか、ちゃんとスレッドプロシージャの型を見ような。
cdeclとstdcallとではスタックの解放の仕方が違うんだよ。
大方、リターン直後でスタック破壊を起こしていると思われ。
0201デフォルトの名無しさんNGNG
>>192=183
ちょっと話題がずれるけど、ポインターをやりとりする時に
実態の領域を誰が用意するかはドキュメントを読まないと
判らないのはC言語の限界ですよね。。。
用意するにしても、領域の大きさも表現できないし。
>localtime_rは代替関数である。
代替かなぁ?
localtimeの仕様が気に入らない人が多くって、
thread-safeにするついでに関数の定義を直しちゃったとか?
0202デフォルトの名無しさんNGNG
>>201
sprintf→snprintfという変化もあるよ
thread-safeとはまた別に。
0203名無しさん@XEmacsNGNG
>>201
> thread-safeにするついでに関数の定義を直しちゃったとか?

1. 仕様を変えないとMT-safeにならない。
2. 勝手にmallocするようにしないとMT-safeにならない。

という究極の選択で、1を選んだという事。
Lisp, Java, C#が2を選んで、

> 実態の領域を誰が用意するかはドキュメントを読まないと
> 判らないのはC言語の限界ですよね。。。

を克服するためにGCを採用した(知る必要なし)のはご存知の通り。
0204デフォルトの名無しさんNGNG
>>194-196
thread safeじゃない物はstruct _tiddataでまとめてTLS管理してる
ようだが。crt/src/mtdll.h辺り参照。
0205デフォルトの名無しさんNGNG
Windows&VC++環境で親スレッドから子スレッドを終了したいのですが、
どうしたらいいので良いでしょうか?
自分で調べた中では、自分自身(呼び出し元)を終了させる方法しか
見つかりませんでした。
0206デフォルトの名無しさんNGNG
誰かが(親でも子でも、別EXEでも)社内掲示板(同期オブジェクト)を使って、リストラの通知をする
↓
仕事しながらたまに社内掲示板を待ち時間ゼロとかで調べる
↓
終了通知が来てたら、仕事を辞めて首をつる
↓
スレッドハンドルとかを待機して解雇を確認する
スレッドハンドルで解雇の確認ができないときは、死に際に
遺書(同期オブジェクト)を残す
↓
解雇完了
0207デフォルトの名無しさんNGNG
TerminateThread
0208デフォルトの名無しさんNGNG
だせーよおまえ
0209デフォルトの名無しさんNGNG
>>207
どうもです。
TerminateThreadについては、参考書に例として載っていましたが、
リスキーなので使わない方が良いと書かれていました。
他に安全な方法は無いでしょうか?
0210デフォルトの名無しさんNGNG
>>206をよく見なさい
0211デフォルトの名無しさんNGNG
>>209
206の解説:子供スレッドはある変数を監視し、それがある値に
なったら終了するようにしておく。親スレッドは、終了させたく
なったら、その変数をセットする。

当然だけど、子供スレッドは定期的にその変数を監視しないといけない。
かなり面倒。通信量が少ないなら別プロセスのほうが楽かもね。

任意のタイミングで無理矢理殺せるスレッドライブラリは少数派。
つかSolaris以外に知らない。
0212デフォルトの名無しさんNGNG
>>211
>任意のタイミングで無理矢理殺せるスレッドライブラリは少数派。
ただのpthreadでは...。(普通のUNIXで採用しているthreadね(かなり略))
0213デフォルトの名無しさんNGNG
単純に終了のための変数参照でもいいし
メッセージループと同様の作りでもいい、こっちの方がメッセージ
遅れるので融通利く
0214デフォルトの名無しさんNGNG
みなさんinet_ntoa()ってどうしてます?
私は代替にスレッドセーフなやつを適当に
自作してつかっちゃってるんだけど・・
0215 NGNG
俺はinet_ntop()を使うようにしてる。ついでにv6対応にして(゚д゚)ウマー。
0216デフォルトの名無しさんNGNG
通信デバイスにアクセスすると、たまに「ERROR_OPERATION_ABORTED」という
エラーが返ってくるんですが、これってどんなことが起こってて、どう解決していけば
いいのでしょうか?

VC++なんか初めてなのにマルチスレッドのプログラムのデバッグやらなきゃ
いけなくてヘルプ見てももうさっぱりです。
他のスレッドが使っているのだろうか?などとも考えたのですがそれをどうやって
調べればいいのかもわからないです・・・

ホントどうしようもなくシロートで申し訳ないんですが、よろしくお願いします。
0217デフォルトの名無しさんNGNG
>>214
WindowsNT以降ではinet_ntoaはスレッドセーフ(同じスレッドで再度Winsock関数が呼び出されるまで返された文字列は有効)だ。strtokも同様。
0218デフォルトの名無しさんNGNG
>>212
そのpthreadはニセモノだね。
0219デフォルトの名無しさんNGNG
普通のunixで採用しているthreadって何?
0220デフォルトの名無しさんNGNG
>>211
解説どうもです。
>>213
やっぱり、皆さんの提案されるような小技をつかわないと実現できない
のでしょうか?
シンプルに命令一つで実現できないものかと調べています。
あっても良さそうな命令なんですが、やっぱ別スレッドを終了させると
言う事はあまり良くない事(いろいろと問題がある)なのでしょうか?
仕様上、今の所は別プロセスを作る事は考えていません。
0221名無しさん@XEmacsNGNG
>>220
> シンプルに命令一つで実現できないものかと調べています。

何作ってるか書かないと、
そのthreadが取得しているlockはどうするんだ?
とかいうアドバイスをしにくいぞ。
0222デフォルトの名無しさんNGNG
スタック以外何も占有していなければ、外部からTerminateしても問題なし。
そのスレッド内で使用するあらゆるリソースのためのマネージャを、メインスレッドが管理すればいい。
ただし、トランザクション中だけ、メインスレッドが待機する仕組みを必要とする。

で、そういうプログラムを以前1回仕事で作ってみたけど、問題なく動いてはいるね。
(子スレッドが使用するリソースがある程度限定できたからだけど。)
0223デフォルトの名無しさんNGNG
>>220
理解しやすいように具体例を挙げると、こういうことです。
次のようなスレッドがあるとします。

void thread()
{
 FILE* fp = fopen("a.txt", "r");
/*ここで色々な処理をする*/
fclose(fp);
}

メインスレッドからこのスレッドを終了させようとする場合、
このスレッドは、まだ処理実行の途中ですよね?
スレッドを途中で終了させたら、fclose は実行されないですよね?
困りませんか?

ここでfcloseが確実に実行されるためには、

(1) メインスレッドで fclose を実行する
(2) 子スレッドが自分で終了処理して fclose を実行する

のいずれかですが、FILE* fp がローカル変数だったら、
メインスレッドからファイルを閉じる方法は実行不可能です。

メインスレッドから子スレッド終了させると、
子スレッドは fclose を呼ぶヒマなく終了させられますからダメです。

そーすると、終了フラグを立てるなりして
子スレッドが自主的に終了するよう仕向けるしかないわけです。

おわかり?
0224デフォルトの名無しさんNGNG
>>222
但し書きのないいつ殺してもいいスレッドなんて
業務プログラムでは皆無だな(藁

ゲーム系ならあるのか?
0225デフォルトの名無しさんNGNG
>>220
残念ながら命令ひとつてポンってのはないよ。

スレッド管理をしてくれる魔法のつえなんてどこにもない。
ほとんどの場合同期処理が絡んでくるから、
設計は慎重に、コーディングは明快かつ丁寧にやるように。
0226212NGNG
>>218
>そのpthreadはニセモノだね。
(単語の認識に違いがあるかもしれませんが、)
pthread_kill()は意図した動作と違うのでしょうか?
0227デフォルトの名無しさんNGNG
pthread_kill()
send a signal to a thread

SYNOPSIS
#include <pthread.h>

int pthread_kill(pthread_t thread, int sig);

DESCRIPTION
The pthread_kill() function is used to request that a signal be delivered to the specified thread. As with kill(), if sig is zero, error checking is performed but no signal is actually sent.
0228212NGNG
>>227
マニュアルは私も引けるのですが、意図はいかがなものでしょう?
「任意のタイミングで無理矢理殺せるスレッドライブラリ」は
ニセモノ?ホンモノ?
0229デフォルトの名無しさんNGNG
227をどう読むと「無理矢理殺す」になるの?
0230デフォルトの名無しさんNGNG
>>228
pthread_killを使えばシグナルを遅れるが、
受け取り側のスレッドが正しくシグナルを処理できないと、
後で悲惨な目に遭うよ。
0231212NGNG
>>229(=227?,=218??違うかな?)
UNIXではSIGKILLを送ればシグナルのハンドルできずに終了です。
0232デフォルトの名無しさんNGNG
212がニセモノというオチだったのか
0233212NGNG
あう?
言われていることの意味がわからんです。
そろそろ眠いけど、教えてほしいです。
0234デフォルトの名無しさんNGNG
元質問者はWinのはずなのになぜpthreadの話になってる?
0235デフォルトの名無しさんNGNG
>>221-225
どうもありがとうございます。

> 何作ってるか書かないと、そのthreadが取得しているlockはどうするんだ?
> とかいうアドバイスをしにくいぞ。
はい、其の通りですね。情報が少なくてすみませんでした。

1つのプロセスがあり、親スレッドと子スレッドが常駐しています。
子スレッドでは通信処理(無限ループ処理で、イベント待機していて
イベントが発生すれば通信を行う)を行っています。

今、考えている流れは、
1)メインプロセスから、このプロセスに終了の依頼(アプリ終了処理依頼)
 ↓
2)親スレッドが子スレッドに終了依頼をかける
 ↓
3)子スレッド内の処理で通信中であっても通信を強制的に終わらせて
 子スレッドを正常に終了させる。(ローカル変数もろもろを全て開放)
 ※但し、通信中の内容については保証しなくても良い。
 ↓
4)親スレッドから子スレッドが正常に終了したのを確認した上で、親スレッドを終了。

要は、子スレッドにおいて通信処理を行っている最中に割り込みをかけて
子スレッドを終了したいと考えています。

<現在>
子スレッド(無限ループ)
・イベント待機
・・イベント発生⇒通信処理

<変更>
子スレッド(無限ループ)
・終了依頼チェック
・・終了依頼あり⇒子スレッド終了
・イベント待機
・・イベント発生⇒通信処理

上記のようにも考えてみたのですが、これだと終了依頼をかけても通信中の場合だと
通信が完了して、ループが先頭に戻ってくるまで終了できません。通信中であっても
すぐに子スレッドを終了させたいと考えています。(通信内容については保証しなくて
もいい)
以上、よろしくお願いします。
0236デフォルトの名無しさんNGNG
なんと言うかスレッドの問題じゃなくて非同期通信にしろってだけじゃないのか?
0237 NGNG
親スレッドで通信のイベント感知して、
スリープしておいた子スレッドを起こした方がよくない?
0238デフォルトの名無しさんNGNG
Windowsはよくしらんけど、もしpthreadなら上にでてるpthread_killでいいじゃん。
SIGALRMを送って、子スレッドの関数がEINTRで返ったのをみて
終了すればいいような…
0239デフォルトの名無しさんNGNG
>>235
窓だったら子スレッドをMsgWaitForMultipleObjects使わせて待機させ、
親スレッドは子スレッドにメッセージを投げることで終了依頼とする
通信を完全に非同期で行なえばメッセージを待つだけでも出来る

UNIXだったらパイプをポーリングすれば親の終了依頼とクライアントとの
通信を同時に待機できる

細かい使い方は自分で調べろ
0240デフォルトの名無しさんNGNG
>>239
>>235は強制的に終らせてなどと言ってるので通信は
ブロッキングでしたいのだと思われ。
0241デフォルトの名無しさんNGNG
>>224 うわ、頭の硬い奴。
0242デフォルトの名無しさんNGNG
他のスレッドに例外を発生させる方法って、あったっけ。
0243デフォルトの名無しさんNGNG
Javaなら。
スレッドを外から強制終了させよーとすると ThreadDeath 例外が走る。
0244デフォルトの名無しさんNGNG
すまん、舌足らずです。

Win32&C++で、あるスレッドから別のスレッドに例外出せたら、
ちょっと悦なんですが。
ざっと調べた範囲ではなさそうだったんだけど、
見落としてるかもしれんので。

なんか情報あったらください。
0245 NGNG
Sub Macro1()
Dim i As Double
Dim iAnswer As Double

X = Worksheets(1).Cells(13, 2)
A = Worksheets(1).Cells(11, 7)

For i = X To A Step 0.0000001

iAnswer = i

Next

sAnswer = Str(iAnswer)

Worksheets(1).Cells(13, 8) = sAnswer

End Sub
-----------------------------------------
X=C10
A=IF(A13="",""ROUND(B13+E13+F13,6))
と、それぞれのセルには数式が入っています。
Aのセルは
sAnswerのセル(13, 8) に数値が入らないとAの答えが出ないから
「#DIV/0!」となってます

この状態で実行すると
For i = X To A Step 0.0000001
のとこで「型が一致しません」とエラーなります。
「#DIV/0!」だとダメなんでしょうか?
0246デフォルトの名無しさんNGNG
たとえば、そのほかのスレッドで頻繁にアクセスされるインスタンスなどを
ゼロクリアしてしまえば、そのスレッドがそのポインタをさわった瞬間に
Access Violation例外が発生するようにできますが。

やはりメッセージを受け取って、例外を送出するという方が無難でありましょうか。
0247デフォルトの名無しさんNGNG
>>243
イキナリThreadDeathのはなしより、普通は
「WAITスレッドにInterruptかけてInterruptedException」
のはなしが先でしょうに。
0248デフォルトの名無しさんNGNG
>>242
共有メモリのフラグを時々見に行って、フラグが
落ちていたら例外投げればいいじゃん。
0249名無しさん@XEmacsNGNG
>>244
> ざっと調べた範囲ではなさそうだったんだけど、
> 見落としてるかもしれんので。

「Win32 マルチスレッド プログラミング」J. Beveridge, R. Wienerでは、
第五章「スレッドを制御する」に「何時間にもわたる調査の結果、
私は確信を持ってWin32 APIは別のスレッドに対して例外を送出するための
標準的な手段はサポートされてないと断言する事が出来る」だってさ。
// ここで言う「非標準の」はdebug APIで>>246など。

Compilerはかなり大変だよ、非同期に例外送出されると。
どの命令間でも例外が発生すると思って"exception safe"を維持するなんてさ。
けど、欲しい機能だけどね。pthreadのcancel pointみたいに限定局面でいいから。
0250242=244NGNG
むー、やはりそうか。情報ありがとうございます。>みなさま
0251デフォルトの名無しさんNGNG
マルチスレッドとsignalって共存可能かにゃ?
0252デフォルトの名無しさんNGNG
>>251
する。と思うけど。
0253デフォルトの名無しさんNGNG
あと、何らかの手段で、そのスレッドのeipをとってきて、
スレッドが切り替わらないうちに、throw xxx;相当のコードに
書き換えてしまう、という手段がひょっとするとあるかもしれませんな。
まぁ、マルチプロセッサシステムでどうなるかは知りませんが。
0254デフォルトの名無しさんNGNG
排他制御ってどういう時に必要なのでしょうか?
銀行の預金の例、以外には無いのでしょうか?
0255デフォルトの名無しさんNGNG
銀行の預金の例ってなによ?
0256デフォルトの名無しさんNGNG
>>249
QueueUserAPC使えば近いこと出来そうな気がする
あくまで気がする程度だけど……無理かな?
0257デフォルトの名無しさんNGNG
>>254
複数のスレッドから1つの変数、ファイル、その他の資源を
アトミックな1つの操作(≒間に割り込みが入らない機械語1命令など)
ではすまない書き込み、あるいは更新
を行う必要がある個所ではすべて必要です。
0258デフォルトの名無しさんNGNG
>>254
自販機のボタンを同時押しされたときに
押した分だけ缶コーヒーが出てくる仕組みにしたくないときに
排他制御しろ。
0259253NGNG
debug API使って、別スレッドに例外を送出するやばめな方法。
http://www.geocities.com/ghanyan/throw_thread.html
x86 & Win32限定で使い道は全くないけど、まぁ、作ってみまたり。
0260結樹NGNG
まもなくアホでも理解出るようにと思って書かれたスレッドプログラミングの
本がでます。ご期待ください。
買ってくださったら感謝します。
0261デフォルトの名無しさんNGNG
>>258 ボタンの数だけスレッド(タスク?)が動いているのか!
スゴイ設計だな
0262デフォルトの名無しさんNGNG
>>260
あほが作ったマルチスレッドのプログラムって怖いな(w
0263デフォルトの名無しさんNGNG
>>261
オブジェクト指向を始めて学んだときは
そういう設計をして楽しんだよ。
すぐに止めたけど
0264デフォルトの名無しさんNGNG
自販機のボタンを適当に置き換えて読め。

ビデオ鑑賞専用の個室とか、
トイレとか、
なんでもいいぞ。
0265結樹NGNG
>>262
レス感謝します。
0266結樹NGNG
>>265
すみません。慌てて書き込みました。

たしかにあほが作ったマルチスレッドプログラムは怖いですね。
時間ができたら、あほのためのマルチスレッドプログラミングの
ためのパターンランゲージを書いてみたいと思います。
良いアイデアがでました。感謝します。
0267DPの名無しNGNG
あほあほって云わんといてください。
本は買うと思うけど、あほが多数で実装しても困らない設計の進め方を
開発手法の観点から誰かと共著(don't treat)で、web公開してください。
(これぞ救済
あほじゃないやい。あほじゃないやい。DQNなんです。
0268デフォルトの名無しさんNGNG
そろそろ書籍名と出版社を明かしても良いのでは?
0269デフォルトの名無しさんNGNG
>>249
別スレッドの話はともかく、VC だと /EHa で非同期例外処理モデルになるね。
0270デフォルトの名無しさんNGNG
アホほどスレッドを使いたがるから困る
ちゃんと教育してほしい
0271デフォルトの名無しさんNGNG
効果的なとこに使えばよい。
なんだってそうだろ?
0272デフォルトの名無しさんNGNG
人のことあほあほいうやつはばか
0273デフォルトの名無しさんNGNG
>>270
ここで言っても仕方ない。それは「アホ」なヤツの上司に言え。
0274デフォルトの名無しさんNGNG
お前が教育しろ。>>270
0275デフォルトの名無しさんNGNG
TerminateThread()を実行した後にCloseHandle()でTerminateさせてハンドルを
クローズする必要は無いのでしょうか?
CloseHandle()で例外が出るのですが・・・
0276デフォルトの名無しさんNGNG
クローズしなくちゃだめです
0277デフォルトの名無しさんNGNG
>>275
例外が発生するのはおまえのプログラムが間違ってるからだ。
CloseHandleはしとけ。

TerminateThreadのヘルプはしっかり読んだか?
0278名無しさん@EmacsNGNG
なんでそんなにけんか腰なんだ
0279270NGNG
教育したい相手が先輩だったりするんですが
0280デフォルトの名無しさんNGNG
>>279
ご愁傷様です

でも板違いなので、プログラマー板に逝ってね。↓このあたりに、ソースコードを編集して
貼り付けると良いかと。

この会社辞めようと思ったソースコード#2
http://pc.2ch.net/test/read.cgi/prog/1001076034/
0281270NGNG
部分的に貼り付けても、分からないのがマルチスレッドの怖いところなんですけどもね。
グチになってますので去りますすみませんsage
0282デフォルトの名無しさんNGNG
要は「おれはマルチスレッドのテクニシャン」だということかね?
0283デフォルトの名無しさんNGNG
正直、posix threadは本でしか読んでない。
実務ではwin32上でしかマルチスレッドアプリ作ったことない。

でも(゚д゚)ウマー
0284 NGNG
すいません、windowsで以下のような事できるんでしょうか。

スレッドを作って、そのスレッドの中で、オブジェクトを作って
そのハンドルをグローバルにセットして、親からそのハンドルで
メソッドを呼び出す事ってできるんでしょうか。
0285デフォルトの名無しさんNGNG
できるがそのハンドルって何なんだよ。
メソッドって何なんだよ。

所有権の管理と同期はきちっとやれよ。
0286デフォルトの名無しさんNGNG
>>285
おそらく、GDCやなんやのグラフィックオブジェクト
ハンドルのことではないか?
依然意味不明だが。
0287デフォルトの名無しさんNGNG
235です。
返事遅くなりましたが、>236-240さん、ありがとうです。
まだ自分の中では解決案は出ていませんが、今までの情報を元に
がんばってみたいと思います。
0288真希NGNG
電器機の営業をしてます。エクセルとかアクセスとか使って、顧客名と商品購入年月日を入力しておけば、
商品の買い替え時期(買った日からちょうど4年後)に、自動的に表示されるようなプログラム組むことって、できますか?
エクセルを少し習っただけの初心者なもので。。
0289デフォルトの名無しさんNGNG
>>288
それはマルチスレッドと、どのような関係がありますか?
0290デフォルトの名無しさんNGNG
>>288
大袈裟なソフト作らなくても
時々4年前の日付で検索かければいいだけじゃないの?
でスタートアップにショートカット入れとけば?
0291デフォルトの名無しさんNGNG
>>288
なんかかわいい♥
0292 NGNG
>>285
サーバーを作ってるんですが、とりあえず以下の様な事
ができないかなと思ってます。
初心者なもので、ほんとに出来るのかどうか、かなり
不安な状態です。

1.サーバーとクライアントのクラスを作っておく。
2.親がサーバーのインスタンスを作り、accept処理するメンバ関数を
 外部関数を通してスレッド呼び出しする。
3.クライアントからの要求があったら、accept処理するメンバ関数は
 クライアントの処理をするスレッドを呼び出す。
 その中でクライアントのインスタンスを作り(ハンドルをグローバル
 にセット)、recv処理をするメンバ関数でWhileで回る。
4.sendする場合は、親がセットされたハンドルを通して、クライアント
 のsend処理のメンバ関数を呼び出す。




親から、
0293あぁNGNG
>>292
俺も今、チャットサーバ作ってるんで、知恵を出し合おう。
ていうかほぼ完成してるがね。
0294デフォルトの名無しさんNGNG
>>292
悪いことは言わない、スレッド使うのはやめたほうがいい。
0295293NGNG
>>294
ま、それは目的によるわな。何百件のクライアントを処理しなけりゃ
ならんようなサーバーではスレッドはキツイが、内輪で使うような
せいぜいクライアント数人のチャットサーバならスレッドでOK。
0296デフォルトの名無しさんNGNG
たしかに学習目的ならまったくもってOKというか好例だね。
0297デフォルトの名無しさんNGNG
>>294
よければその理由を教えてください。
0298デフォルトの名無しさんNGNG
Linux 上でマルチスレッドを使ったプログラムを作ることになったのですが、
参考図書あるいは URL でおすすめがあったら教えてください。
英語のものでもかまいません。
0299shigeNGNG
http://www.oreilly.co.jp/BOOK/pthreads/
表紙がキライだが
0300デフォルトの名無しさんNGNG
>>294
??
0301デフォルトの名無しさんNGNG
>>298
これなんかどうでしょう?
自分がこれから買うつもりなだけなんだけども(w

>POSIXスレッドプログラミング アスキーアジソンウェスレイシリーズ
>―Ascii Addison Wesley programming series
>David R.Butenhof (著), 油井 尊 (翻訳), 宗方 あゆむ (翻訳)
0302デフォルトの名無しさんNGNG
>>297
趣味なのか仕事なのかを教えてください
0303デフォルトの名無しさんNGNG
趣味だと動作不良起こしても良いと言う意味だろうか??「
0304デフォルトの名無しさんNGNG
スレッドをオブジェクト化しようとしてスレッド関数を
メンバ関数にしようとしてもスタティックじゃないと、
できない。しかし抜け道が。
0305デフォルトの名無しさんNGNG
オブジェクトじゃないじゃん。
0306デフォルトの名無しさんNGNG
本買うようなことか?
0307297NGNG
>> 302
仕事です。(ちなみに、私は 292 ではありません)
以前、Windows2000上で >>292 と同じような処理をするプログラムを
作ったことがあったので。
0308デフォルトの名無しさんNGNG
>>299,>>301
Thanks, こんど都内に行ったら大きな本屋に寄って見てみます
0309デフォルトの名無しさんNGNG
>>259
9xだと非常にやばい。
NTだとクリティカルなコードはみんなカーネルモードにあるので
おおむね問題ないけど。
0310デフォルトの名無しさんNGNG
Winな話です。
メインスレッド+ワーカースレッド複数個のときに、
それぞれのワーカースレッドからメインスレッドへ
SendMessageして特定の処理をしたいのですが、
あるワーカースレッドのSendMessageによって
メインスレッドのコールバック関数内に入っている
ときに、別のワーカースレッドがSendMessageを
送ってきたとすると、コールバック関数内の
コードが並行して走ることになるのでしょうか。
つまり、SendMessageに応答するコールバック関数内の
コードで、グローバル変数などの排他制御が必要なのか
ということです。
0311デフォルトの名無しさんNGNG
他スレッドからのSendMessageは、
自スレッドからのPostMessage同様、一旦メッセージキューに入る。

Advanced Windows読め。
http://www.ascii.co.jp/pb/msp/21292/21292.htm
0312デフォルトの名無しさんNGNG
Pthreadの説明したサイト誰か教えれ
0313U21NGNG
>>312
わたしはここで勉強しました。

http://www-6.ibm.com/jp/developerworks/linux/010119/j_l-posix3.html

3回物でこのページからたどって1回目からどうぞ。
わかりやすいと思います。
0314デフォルトの名無しさんNGNG
>>313
ありがとまんこ
0315デフォルトの名無しさんNGNG
あるスレッドが持つバッファに処理が終了して書いたデータを別の共有バッファにコピーし
その共有バッファが見えているもう一つのスレッドに、Notification を送りたいのですが、
(その猛一つのスレッドはそのNotificationを受けるまで待っていて、受けたらそのデータ
を処理します。) 普通どう実装するものでしょうか? スマートな方法とかありますか?

0316デフォルトの名無しさんNGNG
>>316
処理系くらい書けば?
0317デフォルトの名無しさんNGNG
下のようなプログラムをVC++6.0で書いていますが、
スレッド数が10ぐらいなら正常に終わるのですが、
スレッドを100とか1000にすると、なかなか終わりません。
原因は何でしょうか?

#define THREAD_MAX 10

volatile int stop[THREAD_MAX];

void thread_start(void *i) {
  while(1) if ( stop[(int)i] == 1 ) break;
}

void test_thread(void)
{
  int i;

  for (i=0;i<THREAD_MAX;i++) {
    _beginthread( thread_start, 0, (void *)i );
  }

  for (i=0;i<THREAD_MAX;i++) stop[i] = 1;
}
0318デフォルトの名無しさんNGNG
while(1)×1000 が CPU 食いまくっているので
for(...) stop[i]=1; の処理が回りにくいから。
ついでに 10 くらいだと thread_start が始まる前に
その stop フラグが立ってしまう可能性アリ。

#うそかもしれん。
0319デフォルトの名無しさんNGNG
>>318
ありがとうございます。
100個の時は100分の1のタイミングで切り替わるのではなく
重たいループに優先的にCPUが使われてしまう、と考えていいのでしょうか?
0320デフォルトの名無しさんNGNG
下のようにSleepを入れたら、スレッドが2つでも
終了しなくなりました。
マルチスレッドは難しい・・・。

for (i=0;i<THREAD_MAX;i++) {
  Sleep(1000);
  stop[i] = 1;
}
0321デフォルトの名無しさんNGNG
あー、なぜイベントを待たないのかね?
0322デフォルトの名無しさんNGNG
スレッドのwhileループの中に Sleep(0) でも入れてみ。
0323 NGNG
>>320
ビジーループを使う理由は?
マルチスレッドの前にコンピュータの基礎を勉強してみれば?
0324デフォルトの名無しさんNGNG
Win32でスレッド使っうならAdvanced Windowsくらい読んだ方がいい。
0325デフォルトの名無しさんNGNG
専門書って高いよな……
これではずれだった日にはもう……
0326デフォルトの名無しさんNGNG
またブチキレですよ。
0327デフォルトの名無しさんNGNG
POSIXスレッドをLinuxで勉強はじめたものなのですが、階層的な構造体のある一部分
だけMUTEXでロックしたいのですが、その場合、pthread_mutex_t 変数を宣言する場所
は、例えば struct B の部分にのみロックをかけたい場合、以下のような風にすれば
よろしいのでしょうか?

struct A {
int a;
int b;
struct B bb:
} stA:
struct B {
pthread_mutex_t hoge:
int c;
int d;
} stB:

struct stA aa;
0328デフォルトの名無しさんNGNG
え?
0329デフォルトの名無しさんNGNG
327

スマソ、宣言が何か変でした、もいっかい…

struct stB {
pthread_mutex_t mutex:
int c:
int d:
}
struct stA{
int a:
int b:
struct stB bb:
}
struct stA aa:
0330デフォルトの名無しさんNGNG
>329
そのレベルなら好きにすれば?(´ー`)y-~~
0331名無しさん@XEmacsNGNG
>>327
ロック変数は、ロックする対象と一対一に対応させて利用しさえすれば、
対象となる構造体の一部である必要はない。

struct T a;
pthread_mutex_t lock_for_a;

でもよい。

>>317,>>319-320
どうしてそうなるかは、Windowsの仕様ではなく、
Windowsの実装や動作環境に依存する話だから、
そんな物に依存しない様に同期を取りながらプログラムを記述せねばならない。

> 重たいループに優先的にCPUが使われてしまう、と考えていいのでしょうか?

そういうことはない。Busy loopがCPUを占有するだけ。
0332デフォルトの名無しさんNGNG
327

>>331

ご返答ありがとうございます。なるほど、ロック対象の対応をきちんとすれば
ロック変数の宣言はどこでもいいんですね。しかし一つ疑問が生じます。
pthread側はどこでロック対象のスコープ範囲を知る事ができるんでしょうか?

2つのスレッドAとBがあったとき、AがロックしたリソースをBは解放されるまで
アクセスできないとしたときに、Aがロックするものというのは何でもよいわけですよね?
構造体のインスタンスでも、一つの変数でも、構造体のリンクリストのずっと先の方でも…
ロックされる範囲をBはどのようにわかるのでしょう?
それとも単にAがソースコード中でロックとアンロックをした範囲内のデータは全て
ロックがかかるという事でしょうか?(つまりソースコード依存)
その間に構造体メンバーやグローバル変数が出てきたらそれらは全てロックがかかる
のでしょうか?
0333超先生@プログラム板NGNG
  ∧_∧
< `ш´>.。oO(C言語のスコープは関係しない)
pthread_mutex_lockにて明示的にロックし、
pthread_mutex_unlockにて明示的にアンロックする。
保護がかかるのはあくまで*コード*であり、直接データが保護されるのではない。
データにアクセスするコードをmutexで保護することによって、
データへのアクセスがアトミックであることを保証することができるのだ。
0334デフォルトの名無しさんNGNG
331様、333様、どうもありがとうございました。

>>333
どうも勘違いして mutex lock を理解していたようです。これで疑問が氷解しました。
ありがとうございました。m(__)m
0335デフォルトの名無しさんNGNG
>>334=327 でした。スマソ。
0336デフォルトの名無しさんNGNG
複数のスレッドのデバッグ情報を1つの画面に吐き出したいのですが、
「Win32マルチスレッドプログラミング」を読むと1つのデバイスコンテキストに
複数から描画するのはまずい、とあり、実際、プライマリスレッドが
作ったデバイスコンテキスト(hDC)に別スレッドからアクセスしても
フォント情報、背景色など、正しく情報を持って来れません。

やりたいことは、TRACE()の結果をIDEではなく、別Windowsに表示させる、
といった感じになのですが。
0337デフォルトの名無しさんNGNG
DebugViewでも使え
http://www.sysinternals.com/
0338デフォルトの名無しさんNGNG
>336
PostMessageでUIスレッドにメッセージ投げれ。
UIスレッドでは、そのメッセージをうけて、何か描画すれ
0339デフォルトの名無しさんNGNG
リエントラントでない rand() をマルチスレッドで使いたい場合みなさんどうしてますか?
あとpfintf()はリエントラント? デバッグように出したりしてるんですが
0340デフォルトの名無しさんNGNG
randはだめでしょ。
どうしてもつかいたければ単体の乱数発行スレッドでメッセージ通信とか
すれば良いと思う。
printfはふつー再入可能じゃないのかなあ。まあ処理系に依存するよ。
0341デフォルトの名無しさんNGNG
rand()?
リエントラントでないならロックすれば言いだけじゃないの?
0342デフォルトの名無しさんNGNG
339

>>340
別スレッド作るのはいやん

>>341
そうかロックしちゃえばいいのか
0343名無しだけれどもNGNG
>>339
> あとprintf()はリエントラント? デバッグように出したりしてるんですが

printf()はstdoutが共有リソースだから、
競合するようなら排他せざるを得ないでしょう。
printf()毎にライブラリがジャイアントロックする環境なら、
アプリ作成者がやる必要はないけど。
(ただしそのことをリエントラントとは呼ばない。MT-Safeではあるが)

fprintf()であれば、出力先が違う場合があるわけだから、
MT-Safeでかつリエントラントである実装が最近は多いはずだけど。

いずれにせよ、使っている環境のマニュアル読むこと。

func () { // MT-Safeではあるが、リエントラントとは言わない。
static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; // ジャイアント
pthread_mute_lock(&lock);
ほげほげ;
pthread_mute_unlock(&lock);
}
0344デフォルトの名無しさんNGNG
rand()の目的からいえば、別にlockしなくてもいいのでわ?
とかいってみる。l
0345デフォルトの名無しさんNGNG
同じ乱数を再現する必要があるんじゃないの?
対戦テトリスとか。
0346デフォルトの名無しさんNGNG
sleep()で眠らせてるスレッドを強制的に起こす、またはそのスレッドを強制的に終了
させる良い方法ないですか?

0347名無しとは?NGNG
sleep()はやめて、pthred_mutex_lock()等で待て。

> そのスレッドを強制的に終了させる

極めて有害。
0348デフォルトの名無しさんNGNG
>>346-347
言語は合ってるのか?w
0349デフォルトの名無しさんNGNG
>>347
一定時間止めておきたい場合はどうするの?
pthread_mutex_lockで待つのはいいとしても。
0350デフォルトの名無しさんNGNG
>>347
>>348
ptheadでもなんでもいいです。一般的にどうするのがいいのかなと…
やりたいのは一定時間眠らせておきたい(止めておきたい)んだけど
終了させたい時にはすぐにそのスレッドを終了させたい。
pthread_mutex_lock()の場合ロックハンドルを待つということは別途
一定時間を計るタイマーを持てと?タイマースレッドの実装って美ジ
ーループでしょ?やだな。
0351デフォルトの名無しさんNGNG
pthread_mutex_timedlockがあれば使う
無ければptherad_cond_timedwait
0352デフォルトの名無しさんNGNG
複数のmutexを同時に、あるいはどれか一つを取得するにはどうすればいいですか?
0353名無しとは?NGNG
>>352
1. pthread_cond_*()を使う
2. 通知する側が条件を調べて真の時に通知するようにする。(condと基本的に同じ)
3. 条件を調べて通知するthreadを作る。

0354デフォルトの名無しさんNGNG
あげ
0355デフォルトの名無しさんNGNG
UNIX板では答えが貰えなかったのでこっちで質問させて下さい。
FreeBSDの<pthread_np.h>に以下の関数が宣言されています。

int pthread_attr_setcreatesuspend_np __P((pthread_attr_t *));
int pthread_multi_np __P((void));
int pthread_resume_np __P((pthread_t));
int pthread_single_np __P((void));
int pthread_suspend_np __P((pthread_t));
int pthread_mutexattr_getkind_np __P((pthread_mutexattr_t));
int pthread_mutexattr_setkind_np __P((pthread_mutexattr_t *, int));
void pthread_set_name_np __P((pthread_t, const char *));
int pthread_switch_add_np __P((pthread_switch_routine_t));
int pthread_switch_delete_np __P((pthread_switch_routine_t));
int pthread_main_np __P((void));

これらの関数が何をするものなのか知っていたら教えて下さい。
0356デフォルトの名無しさんNGNG
FreeBSDならソースが読めるだろ。
後に_npついてるのはPOSIXに規定されてないと思う。
0357デフォルトの名無しさんNGNG
>>356
今、MSのFreeBSD向けCLIがLinuxでも動作するよう移植してるんですが、
PALのスレッドの辺りが上手く動かないからちと困ってます。
FreeBSDのmanpageにもでてこないし、検索してもまったく引っかからないし
やっぱりソース読むしかないかなぁ。。
0358名無しとは?NGNG
>>355
_npってのは、NOT POSIX。
だからpthread_np.hってのは、pthread関連ではあるが、
POSIXのpthread規格に入ってない関数等のheader。

// pthread_*_npって命名自体POSIXに規定されてるんじゃなかったかな。
0359デフォルトの名無しさんNGNG
>>358
_npはnot portableだと思ってたが。
0360デフォルトの名無しさんNGNG
2CPUが全く同時に同じところにアクセスしたらメモリはぶっ壊れますか
0361デフォルトの名無しさんNGNG
「まったく同時に同じところにアクセス」することを許すような
イカれたメモリコントローラの下では、
「まったく同時に同じところにアクセス」しなくとも、
メモリが煙を吐いて壊れるのは予想しうる事ではないでしょうか。
0362デフォルトの名無しさんNGNG
はい、ぶっ壊れます。
0363デフォルトの名無しさんNGNG
マジですか。ぶっ壊れますか。
0364デフォルトの名無しさんNGNG
それは大変だ。
0365デフォルトの名無しさんNGNG
Windowsでそれは有り得る?
0366デフォルトの名無しさんNGNG
みんなイジワルだな(w
0367デフォルトの名無しさんNGNG
僕は意地悪されてたんですか。
>>361さんの書き込みで安心してたんですが、
これも意地悪なのですか。
0368デフォルトの名無しさんNGNG
普通は「まったく同時に」なんかアクセスされないようになってるから大丈夫。
0369デフォルトの名無しさんNGNG
安心しますた。
0370デフォルトの名無しさんNGNG
>>368
ウソはよくないぞ
0371デフォルトの名無しさんNGNG
不安です。
0372名無し人間NGNG
>>360は、
・"one writer, some readers"
・atomic
・cache coherent
って概念を勉強して自分で考えられる人間になるか、さもなくば、
自分の知りたい場合について詳しく説明しながら質問すること。
0373デフォルトの名無しさんNGNG
>>372
それらを勉強するのに適した書物等あれば、おせえてください
0374デフォルトの名無しさんNGNG
Apache2.0の正式リリースあげ!
0375デフォルトの名無しさんNGNG
マルチスレッドって、2穴同時挿入とかそういうイメージですか?
0376名無し人間NGNG
>>373
http://www.amazon.co.jp/exec/obidos/ASIN/482228056X/qid=1020141523/sr=1-1/ref=sr_1_2_1/250-4858489-2345044
とりあえずこれ。

後はタンネンバウムかなー。(良書とは言えないけど…)
http://www.amazon.co.jp/exec/obidos/ASIN/4894710471/qid=1020141710/sr=1-2/ref=sr_1_2_2/250-4858489-2345044
http://www.amazon.co.jp/exec/obidos/ASIN/4894712245/qid=1020141710/sr=1-4/ref=sr_1_2_4/250-4858489-2345044
0377デフォルトの名無しさんNGNG
これってどうですかね。Javaだけど一般的な知見もあると思う。

Javaスレッドプログラミング―並列オブジェクト指向プログラミングの設計原理
http://www.amazon.co.jp/exec/obidos/ASIN/4881359185/250-7376397-1451448
0378名無し人間NGNG
>>377
むっちゃ面白いよ。Javaやらない人も一読の価値あり。
>>372とは違って、ソフトウェア設計の話だけどね。
0379デフォルトの名無しさんNGNG
保守
0380デフォルトの名無しさんNGNG
質問です。

WinsockAPIを使おうと思うんですが、
これってWSA~ 以外の関数もMT-Safeなのですか?
MT-Safeのこともよくわかっていないので、もしよろしければ、
MT-Safeの定義を教えてください。
0381デフォルトの名無しさんNGNG
>>380
へー、WindowsでもMT-Safeっていう概念あるんだ。

SolarisでMT-Safeと言ったら、複数のスレッドから同時に呼び出しても
安全で、かつそれなりのconcurrencyで動くことを言う。

全体をロックしちゃって、1度に1つのスレッドしか入れないように
なってるやつは「Safe」と呼ぶ。
0382デフォルトの名無しさんNGNG
reentrantだったらMTSafeだろ
0383デフォルトの名無しさんNGNG
>>381の言ってることが変だと思う俺は素人ですか。
0384デフォルトの名無しさんNGNG
>>381-382
おお。ありがとうございます。
複数のスレッドで安全に動けばとりあえずMT-Safeということですよね?

過去ログでのWinsockのことと、CygwinのライブラリがMT-Safeでないとか、
Googleったら出てきたんで、不安になって聞いてみました。
(MSDN Libraryにも資料ないですし。)


ご教授ありがとうございます。
0385381NGNG
>>383
どこが変ですか?
0386デフォルトの名無しさんNGNG
>>381
>へー、WindowsでもMT-Safeっていう概念あるんだ。
ってとこじゃないですか?

おれは>>383じゃないですけど
0387381NGNG
>>386
Safe, Unsafe, MT-Safe, Async-Signal-Safe, Fork1-Safe
という分類はSolaris独自かと思ったんですが。
Winでも同じ定義かどうかは正直知りませんです。
0388デフォルトの名無しさんNGNG
少なくとも一般では(Solarisは死欄)MT SAFEは
複数のスレッドからどんなタイミングで呼び出されても
正常に動作することが保証されていることを指す
0389デフォルトの名無しさんNGNG
>かつそれなりのconcurrencyで動くことを言う。

そんな説明はmanにありません
0390名無し人間NGNG
>>381
http://msdn.microsoft.com/vfoxpro/downloads/updates.aspの
「Visual Studio 97 Service Pack」のところ読みなよ。

>>387
> Async-Signal-Safe, Fork1-Safe

それは今関係ないじゃん。
0391デフォルトの名無しさんNGNG
WIN32質問です。
ミューテクスと自動リセットイベントは何が違うのでしょうか。
先生方、どうかご教授を
0392デフォルトの名無しさんNGNG
mutexでの所有権を放棄するかわりに、EventをSetすることで
mutexと同じような動作をすることも、できないわけではない。
おそらく「自動リセットイベント」は、この際に疑似所有権を
譲渡されるタスクを1つに限定する(のでmutexと同じ)と
いうことだろう。

ただそうすると、mutexでは、それを所有しているタスクが
何らかの事情で死亡したときに、所有権がOSにより放棄される
(=他の生きているタスクに渡る)のに対し、Eventによる
疑似所有権は、(放棄が明示でしかありえないがゆえに)
放棄されず、きわめてまずい事態(所有権の喪失=永久待ち)を
引き起こす恐れがあるので、おすすめできない。
      民名書房刊、「Auto Reset EventによりMutexは不要か」
0393デフォルトの名無しさんNGNG
先生、よくわかりました。
先生頭よすぎです!
0394デフォルトの名無しさんNGNG
民名書房かよ。
0395デフォルトの名無しさんNGNG
>>392
Windowsはスレッドが途中で氏んでもMutexを開放しない罠。
0396デフォルトの名無しさんNGNG
MSDOSでマルチスレッド(もどきでいいので)のプログラム作るにはどうしたら言いの?
だれかおしえてくらさい。
0397デフォルトの名無しさんNGNG
setjmp/longjmp
0398デフォルトの名無しさんNGNG
>>397
やはりそれしかないか・・・
ためしたんだけど、longjmpしたあとのreturnとかがうまくいかないです。
0399デフォルトの名無しさんNGNG
>>398
んじゃ、タイマ割り込みを使って自前でコンテキストスイッチ
0400デフォルトの名無しさんNGNG
スレッドってコンテクスト切り替えてるんですか?
その場合、切り替えのタイミングは大麻割り込み??
0401デフォルトの名無しさんNGNG
>>400
大きく分けてユーザーランドのスレッドと、カーネルサポートのスレッドがある
その中でも実装によって異なるかもしれない(特にユーザーランド)
あとは本などで勉強してね(はぁと)
0402デフォルトの名無しさんNGNG
>>398
「うまくいかない」とだけ書かれてモナー。
とりあえずvolatileが必要に1000setjmp。
0403デフォルトの名無しさんNGNG
>>398
というか、setjmp/longjmpがどうやって動作しているのか理解してる?
コンテキストスイッチをsetjmp/longjmpでやるんなら、
まず自前で複数のスタックを確保して、jmp_bufを初期化してやんなきゃ。

とにかく最低限レジスタとスタックの保存と切替ができるようにしないとな。
本格的にやるならシグナルハンドラとかマスクとかも考えなきゃならんが。
0404398NGNG
>>403
一応生成されたアセンブラコード見てなんとなくは理解しますた。
だけど、コンテキストスイッチとかサパーリです。。。

まだまだ勉強不足です。
出直してきます。

レスくれた人ありがとう
0405testNGNG
>>396
文章からすると小学生くらいだと思うが、答えてやろう。
MS-DOSのコマンドではプログラムは作れません。
Javaでも、VC++でも使えば幾らでもスレッドプログラミングできます。
GUIを出したくなければ、GUIを使わなければいいだけで無関係。
0406デフォルトの名無しさんNGNG
>>405
痴呆
0407デフォルトの名無しさんNGNG
>>395
ちゃんとWAIT_ABANDONEDで帰ってくるが。
クリティカルセクションなら解放しない。
0408フォルトの名無しさん NGNG
MSKK SQLのマーケが10年以上まえのトレンドを
気が狂ったように宣伝しています。
http://www.microsoft.com/japan/sql/choice/
並列処理ではマルチプロセスよりマルチスレッドの方がすべての面で
優れていると主張しています。で、最後にOracleよりMS SQLのほうが優れてる
と書いています。ヒャッヒャッヒャ。
マルチプロセス・マルチスレッド・マルチファイバ・ステートプログラミング、
どれが優れているのか・開発しやすいのか、語ってください。

0409デフォルトの名無しさんNGNG
マルチスレッドです。
ひたすらダーティーに。

0410デフォルトの名無しさんNGNG
>>408
そういう場合、Oracleより劣るところはどこか聞いてみると良い。
0411デフォルトの名無しさんNGNG
スレッドをバカにするとSolarisマンセー野郎に怒られますよ。
0412デフォルトの名無しさんNGNG
マルチスレッドは、デバッグ辛いのよね、正直。
0413デフォルトの名無しさんNGNG
設計が悪い
0414デフォルトの名無しさんNGNG
一つのオブジェクトに複数のスレッドが非同期にガシガシアクセスするという
設計のコードをデバグさせられそうになったのですが

逃げました
0415デフォルトの名無しさんNGNG
>>414 は、開発もできないしデバグと言う名のテスト要員にもなれませんでし
た。まあ,プロジェクトとしては助かったけどね。
0416デフォルトの名無しさんNGNG
保守
0417デフォルトの名無しさんNGNG
保守
0418デフォルトの名無しさんNGNG
ほしゅ
0419デフォルトの名無しさんNGNG
一周年記念カキコ
0420デフォルトの名無しさんNGNG
>>415
めでたくプロジェクトは潰れました
0421デフォルトの名無しさんNGNG
息の長いスレだね。
スレッドよりはコルーチンで作りたくなることが良くある。
0422デフォルトの名無しさんNGNG
win2kってworker thread/thread poolingがアプリから自由に使えるのな
IOCPの俺様実装とかできそうな感じ
0423デフォルトの名無しさんNGNG
よろしか上げ
0424おぱいNGNG
BCC5.5のコンパイラで32ビットのマルチスレッドアプリを作りたいんだけど、
Error: 外部シンボル '_main' が未解決(C:\BORLAND\BCC55\LIB\C0X32.OBJ が参照)
のエラーが出ます。

ソースは実験のためのシングルスレッドのスケルトンです。
bcc32 -W test.cpp
ではコンパイルできます。
DLLのソースなら
bcc32 -WD dll.cpp
でコンパイルできました。
スケルトンで
bcc32 -WM test.cpp
で、'_main' が未解決っていうことは、マルチスレッドならWinMain()
じゃなくて、別の関数名なんですか?
0425名無し人間NGNG
>>424
WinMainって一体なんなのか調べてみれ。mainとの違いを。
0426おぱいNGNG
'_main' が未解決っていうことは、main()が無い
って注意されていると思ったから、ハローワールドの
ソースで、bcc32 -WM hello.cpp
ってやったらコンソールのマルチスレッドがコンパイルできました。
32ビットコンソールなら
bcc32 -WC hello32.cpp
でできました。
BCC5.5では32ビットマルチスレッドのアプリは作れないんですか?
0427デフォルトの名無しさんNGNG
>>426
ボーランドに聞けよ...
0428おぱいNGNG
>>427には聞いてないよ。オマエ勘違い。藁。
0429おぱいNGNG
ここもレベル低いね。こんな簡単な質問に答えられないの?バッカみたい。
板ごと削除依頼しよっか?
0430デフォルトの名無しさんNGNG
>>429
必死だな。
0431デフォルトの名無しさんNGNG
簡単だったら何で質問するんだよ・・・
0432sageNGNG
'_main' が未解決っていうことは、main()が無い
って注意されていると思ったから、ハローワールドの
ソースで、bcc32 -WM hello.cpp
ってやったらコンソールのマルチスレッドがコンパイルできました。
32ビットコンソールなら
bcc32 -WC hello32.cpp
でできました。
BCC5.5では32ビットマルチスレッドのアプリは作れないんですか?










激しく( ´_ゝ`)フーン
0433K&RNGNG
おいおいレベルさがってるぞ〜。
おばいくーん、こまるなー、ほんと、いるよねー、こーゆーひと
0434おぱいNGNG
429と430は同一人物。
BCC5.5を使ってない人には聞いてないいょぅ。
0435デフォルトの名無しさんNGNG
>>428ですでに信用がた落ちだからな・・・。
0436おぱいNGNG
だから、知らねー奴には聞いてないってば。
だいたいなー、ボーランドへの質問は18cm未満の人は
質問禁止なんだよ。知りたいならオマエが聞け。
0437デフォルトの名無しさんNGNG
>18cm
ティムポの長さですか?
0438デフォルトの名無しさんNGNG
おぱいだからアンダーとトップの差では?
0439おぱいNGNG
BCC5.5ではマルチスレッドでもシングルスレッドでも
コンパイル時のオプションは必要ないと分かりました。
bcc32 -W test.cpp
で32ビットGUIマルチスレッドもできました。
0440デフォルトの名無しさんNGNG
・・・ホームラン級のバカ?
0441おぱいNGNG
>>440
もう用は無い。うせろ。ワラワラ
0442デフォルトの名無しさんNGNG
基本がわかっていないので教えてください。
お願いします。(Win32環境です)

int G = 0;

void init_G(void)
{
 if(G == 0) {
  if( バージョン判定式 ) G = 1;
  else G = 2;
 }
}

上記のような場合でもやはり init_G()内の処理は
排他を考える必要があるでしょうか?

複数のスレッドが、あらかじめ init_G()を呼び出した後で
グローバル変数Gを読み取りのみに使います。(書き込みはしません)

また、バージョン判定式 の部分は どのスレッドから
何回評価しても同じ結果を返し、かつ
この判定自体はスレッドセーフであるとします。

同時読み書きや同時書き込みが発生するが、
メモリ上のデータの整合性(一貫性)は保たれるので
排他の必要はない と考えるのは間違いでしょうか。
0443デフォルトの名無しさんNGNG
>>442

考え方はあっている。

書いてあるプログラムも、「いったん判断式を評価したら、二度と評価しない」
となっているので、その点もよい。

0444デフォルトの名無しさんNGNG
(バージョン判定式)が
・何回行っても処理に問題はなく
・スレッドセーフであり
・常に同じ値を返す
のであれば、排他制御は必要無い(はず)。

一般には(上記のどれかを満たさないorコストがかかる場合)、Gをvolatileで宣言しておいて
void init_G()
{
 if (G == 0) {
  lock();
  if (G == 0) {
   if (...) {
    G = 1;
   } else {
    G = 2;
   }
   unlock();
  }
 }
}
のように、初期化が必要になる可能性がある場合のみ、
ロックしてから再度判定する場合が多いと思う。
0445442NGNG
>>443,444
どうもありがとうございます。
基本的な考えは間違っていないようで、安心しました。

> 書いてあるプログラムも、「いったん判断式を評価したら、二度と評価しない」
> となっているので、その点もよい。

この理由がよくわかりませんでした。

私が if(G == 0) を付けたのは、
「判断式を評価する時間がもったいないから」というだけで
深い意味はなかったのですが、
他にも意味があるのでしょうか?
(判断式を何度評価しても動作に支障がない場合)

また、444 さんのコードの意味もよくわかりません。
void init_G()
{
 lock();
 if(G == 0) {
  if (...) G = 1;
  else G = 2;
 }
 unlock();
}
だけではまずいでしょうか?
lock() にかかる時間的コストを考慮?
lock() と unlock() が対になっていない点も疑問です。
0446444NGNG
ごめん。unlockの位置は{}とインデントをつけた時にミスった。

G==0を2度やっているのは、コストの問題。
本当にlockする必要があるのは最初だけで、それ以降は常にG!=0なのだから、
そのためだけに毎回lockするのは時間的に無駄だから。

例えば、Singletonなんかでインスタンスを初期化/取得する場合でも、
毎回実行する部分は出来るだけ軽くすべきであり、
最初以外はlockせずに値を取得出来るようにするため。
0447444NGNG
よく見たら、
>lock() にかかる時間的コストを考慮?
って書いてあった。その通りです。
0448デフォルトの名無しさんNGNG
>>444
そのコードだとGをvolatile宣言する必要はナシ。
そもそも、volatile宣言された変数へのアクセスって
意外とコスト高なんで注意すべし。

ちなみに>>444のアルゴリズムはDouble-Checked Lockingと
呼ばれているんだが、場合によってはうまく動かないことが
知られている。

具体的には、初期化の対象がatomicなアクセスが保証されている
primitive型の変数ではなく、緩いメモリモデルを採用している
プラットホーム上で動かした場合に、うまく動かない可能性がある。
緩いメモリモデルの例としてはJava memory modelとかがあるから
参考として以下の記事なんかを読んでおくのもいいよ。
http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html
0449444NGNG
どうもありがとう。
C/C++でも、volatileは必要無いのかな?
つまり、lockした後の再判定時に、コンパイラの最適化で
レジスタ等にキャッシュされた値を読んでしまうのを防ぐ必要があるかなと。

コスト的にも、C/C++なら、スタック以外の変数(の読み出し)にかかるコストは、
volatileでもそう変わらないと思ったし(読み出しが一回だけの場合)。
Javaなら、インスタンス変数をキャッシュする関係で差がつくのはわかるけど、
>>444は元々C/C++を想定していたから。
ただ、スタック上の変数の場合は、C/C++でもレジスタ割り付けの関係で差が付きそう。

あと、問題があることは知らなかった。
操作対象がatomicに操作できなくても、判定するためのフラグを用意すれば
一般的に解決できる問題なのかな?
とりあえず、リンク先読んでみる。
0450444NGNG
とりあえず、マルチプロセッサ環境において、
・コンストラクタが実行されて初期化されるまでの間
・(C/C++などのCPUキャッシュの同期が保証されていないものでの)メモリからの読み出し時
に問題があることはわかった。
その他はまだよく理解出来てないけど。
0451442NGNG
>>444
どうもありがとうございます。
おかげ様で大変よくわかりました。感謝感謝です。

今度は
>>448の
volatile宣言の必要がないというのがわかりません。

(444さんと同じ考えですが) volatileが無いと、
lock とunlock が通常の関数呼び出しとして実装されている
なら大丈夫としても、
仮にこれらがインライン展開される関数やマクロだった場合に、
・lockの直後のif文で G がメモリから再ロードされるかどうか
・更新後の Gの値がunlockの前でメモリに書き込まれるかどうか
が保証されないのでは? と思えます。
0452デフォルトの名無しさんNGNG
>>451
たとえば
mutex L;
int data;
として、スレッドAで
 lock(L);
 dataに代入; // …(1)
 unlock(L);
とした後、スレッドBで
 lock(L);
 dataの利用; // …(2)
 unlock(L);
ってしたとき、たとえvolatile宣言がなかったとしても
(2)において(1)の変更が見えないのはマズイ。
だから、
> 仮にこれらがインライン展開される関数やマクロだった場合に、
> ・lockの直後のif文で G がメモリから再ロードされるかどうか
> ・更新後の Gの値がunlockの前でメモリに書き込まれるかどうか
> が保証されない
なんてことがあったら、それはスレッドライブラリ側のバグ。
さらに、緩いメモリモデルをとっているアーキテクチャ上の
スレッドライブラリではlock, unlockの際に適切なメモリバリア命令を
実行していたりもする。

IA-32ではメモリ書き込み順やキャッシュ一貫性の保証があるんで
こういう話とはほとんど無縁だけど、pthreadの本とかでは
ここらへんが重要な話として載ってるよ。
0453名無し人間NGNG
>>452
> それはスレッドライブラリ側のバグ。
> さらに、緩いメモリモデルをとっているアーキテクチャ上の
> スレッドライブラリではlock, unlockの際に適切なメモリバリア命令を
> 実行していたりもする。

これは標準Cから逸脱している特定のシステムの話では?
0454デフォルトの名無しさんNGNG
>>453
当然逸脱してるけど、それを満たしていなかったらスレッドライブラリとして
使い物にならないって言う事じゃないの?
違ってたらスマソ
0455お役立ちサイトです。NGNG



究極の総合リンク集

http://home9.highway.ne.jp/cym10262/


0456名無し人間NGNG
>>454
>>452=458だと思てるんで、

> そのコードだとGをvolatile宣言する必要はナシ。

も含めてちと言い過ぎじゃないのかなと。


0457名無し人間NGNG
アウ!

>>456
> >>452=458だと思てるんで、

< >>452=448だと思てるんで、
0458442NGNG
>>452
なんとなくわかりました。

たとえvolatileがなくても、lock/unlock の前後では必ず
メモリに反映されるような実装になっている(はずである)。
ということですね。

どうもありがとうございます。
0459452=448NGNG
>>456
ちょっと言い過ぎだったかもしれんが、
もしvolatile宣言が必要な処理系があったとしたら、
>>454の言うように「スレッドライブラリとして
使い物にならない」のは確か。

ポインタをvolatileと宣言しても、その指し示すデータは
volatileにならない(ちょうどconst宣言と同じ)から、
リストとか木とかちょっと大きめのデータ構造を
ロックしようとしたときにえらく面倒になってしまう。
0460デフォルトの名無しさんNGNG
つまりJavaのスレッドは使い物にならない、と。
0461デフォルトの名無しさんNGNG
>>460
誰もそんなこと言ってませんが?
0462デフォルトの名無しさんNGNG
pthreadのpthread_t(スレッドハンドラといういい方でいいのかな、WIN32だと
ハンドラというけど)型の変数や、pthread_cond_t型の変数を他のint型やchar型
のデータ構造体の中にいっしょに詰め込んでmallocして使ったらメモリー破壊
されまくり。ポインタにして分けてmallocしたらうまく動きますた。
何故何故??
0463デフォルトの名無しさんNGNG
ハンドラとは言いません。ハンドルとはぜんぜん意味の違う言葉です。
0464デフォルトの名無しさんNGNG
つかぬ事をお聞きしますが、
マルチスレッド処理が必要なときって何?
0465名無しさんNGNG
>>462
> 何故何故??

あなたの書いたプログラムにバグがあったから。
0466デフォルトの名無しさんNGNG
>>462
pthread_t
pthread_cond_t
だけ?
pthread_mutex_tがなきゃpthread_cond_tは意味を成しませんが。
どのような使い方をしているのか理解出来ないのですが・・・
0467デフォルトの名無しさんNGNG
>>464
必要な例:
いわゆるUNIXでは、fd(pipe/socket等)のポーリングと、sysv IPCの同期待ちと、
プロセス終了待ちと、pthreadの同期待ちを単一のスレッドで同時にはできない。
これは個別にスレッドを立てるしかない。

これ以外は再利用の都合じゃないでしょうか。
独自のループを持つ既存のモジュールを使いまわせるとか。
0468デフォルトの名無しさんNGNG
>>464
467の他に「CPUが複数あるマシンで速く計算するため」というのもあるな。
0469デフォルトの名無しさんNGNG
みなさん、↓はどう思います?
http://slashdot.jp/article.pl?sid=02/09/11/0131222&mode=nested
0470デフォルトの名無しさんNGNG
どうと言われても・・・
0471デフォルトの名無しさんNGNG
みなさん、↓はドゥー思います?
http://slashdot.jp/article.pl?sid=02/09/11/0131222&mode=nested
0472デフォルトの名無しさんNGNG
シラネーヨ
0473デフォルトの名無しさんNGNG
>>471
XEON買え、買えないなら諦めろ。
以上
0474デフォルトの名無しさんNGNG
そこでほとんど語られてんじゃん。
0475デフォルトの名無しさんNGNG
mutexを2種類使うケースってどんな場合があるのでしょうか?
0476デフォルトの名無しさんNGNG
>>475
質問の意味がわからん・・・
0477デフォルトの名無しさんNGNG
すみません。質問の仕方がまずかったかも
pthread_mutex_t 型のmutex変数を2つ以上使う場合ってどんな場合なのかなと
思いまして質問しました。
0478デフォルトの名無しさんNGNG
>>477
リソースが複数ある時とか。
セマフォと同じ用途。
0479デフォルトの名無しさんNGNG
マルチスレッドの入門書でも読んだ方が早いな
0480デフォルトの名無しさんNGNG
2つ以上必要な時はデッドロックに気をつけてな
0481デフォルトの名無しさんNGNG
>>480
確かにアタマが割れるようにイタイ!!!!
それはヘッドロック
てへ★ミ
0482デフォルトの名無しさんNGNG
>>467
> sysv IPCの同期待ちと、
> プロセス終了待ちと、pthreadの同期待ちを単一のスレッドで同時にはできない。
 スレッドを使わずとも、selectや、sigactionを使って同期を取れますが・・?

> これ以外は再利用の都合じゃないでしょうか。
> 独自のループを持つ既存のモジュールを使いまわせるとか。

 その糞モジュールが本当にスレッドでまともが使えるのか結構疑問にかんじますが。


>>486
> 467の他に「CPUが複数あるマシンで速く計算するため」というのもあるな。
 た、たとえばどんな?
 計算させたって、計算終わるまで結果待ちしてるヤシがいるのはずだけど、そいつは何してるの?
 画面描画?画面描画のための計算処理が重いのではないのか?

 「Windowsプログラミングでメッセージ処理とソケットの同期がスレッドでないと取れない」ぐらいしか漏れには思いつかない。
0483デフォルトの名無しさんNGNG
芳しいのが登場したからsage
0484デフォルトの名無しさんNGNG
gcc-2.96, glibc2.2上でMTなプログラムを書いています。そろそろプロファイラにかけたい
と思い、-pg付きでコンパイル・実行してみたのですが、gmon.outが出力されません。

プログラムは、^Cで止めるまで動き続けるものです。どうやらexit()がgmon.outを書き出す
らしいとわかったので、sigactionでSIGTERMをハンドルするようにしましたが、駄目でした。
なにか知恵をください。

0485484NGNG
>>484
SIGTERMはSIGINTの誤記です。ちなみに^Cではなく、
killall -INT program_name にしてます。
0486デフォルトの名無しさんNGNG
>>484

pthreadはよく知らんのだが、

#include <stdio.h>
#include <signal.h>
void h(int x){ exit(1);}
int main(void){ signal(SIGINT, h); while(1); return 0; }

漏れの環境では、single threadの上のは^Cでgmon.out出る。

0487484NGNG
>>486
似たようなコードでも、MTにしたとたん出ないです。
0488デフォルトの名無しさんNGNG
マルチスレッドとマルチプロセスってどう仕組みが違うんですか?
このバカに教えてください。
0489デフォルトの名無しさんNGNG
主に同じアドレス空間で動くかどうか
0490デフォルトの名無しさんNGNG
>>488
失せろバカ。
0491デフォルトの名無しさんNGNG
>>490
お前が消えろ
0492デフォルトの名無しさんNGNG
>>488
バカに理解させるのは疲れるのでいやです
0493488NGNG
>>489
アドレス空間とは・・・な、なんですか(鬱)

>>490
うっさい死ね

>>491
ありがとう

>>492
そんなこと言っちゃイヤンなので教えてください。
0494484NGNG
バカのお蔭で俺の質問が消えてく…
0495デフォルトの名無しさんNGNG
>>493
>>489が完璧。
0496デフォルトの名無しさんNGNG
アドレス空間。
あるアプリケーションが h0番地からhn番地までのメモリを使える時、
h0番地~hn番地までの範囲が、そのアプリケーションのアドレス空間。
プロセスp1とプロセスp2のアドレス空間は全く重ならないけど、
スレッドt1とスレッドt2のアドレス空間はぴったり一致する。
0497488NGNG
>>495
?
アドレス空間が完璧ってどういうことですか?
0498488NGNG
>>496
ありがとうございますm(..)m
禿しく理解できました。
ついでにこれも聞いていいですか?
本を読んでWIn95はプリエンティブなマルチタスクでは無いとかなんとか
と書いてありました。
これはどういうことですか?
0499>>498NGNG
>498
今さらそんなことが書いてある本があるのか?
Win95はプリエンティブなマルチタスクですよ。

つーか、ム板民なら、そのくらい解れ。
0500デフォルトの名無しさんNGNG
preemptive  
a(形容詞). 先制(攻撃)の; 先買権のある. preemptively ad(副詞).
投機実行があるという意味でしょう。
メモリに存在している複数のスレッド(一部は特定の仮想マシンを共有している)
間の投機実行が行われるという意味。実行中のスレッドを一時停止させ
別のスレッドを投機実行させる。non-preemptiveな場合はそういうことは
ない。ま、win3.1にはスレッドという概念すら無いに等しいが。
0501デフォルトの名無しさんNGNG
ハァ?
0502デフォルトの名無しさんNGNG
ひぃ?
0503デフォルトの名無しさんNGNG
いやん。
0504デフォルトの名無しさんNGNG
>>499
Win9xはプリエンティブなアプリとノンプリエンティブなアプリが
混在するから、不完全なプリエンティブマルチタスクと言われていたはず。
0505デフォルトの名無しさんNGNG
>>482
遅レスだが・・・

MsgWaitForMultipleObjectsとWSAEventSelect使えばメッセージ待ちながらソケット待てるよ。
Win32だとWSAEVENTは単なる手動リセットイベントだから。

Overlapped I/O使うならMsgWaitForMultipleObjectsExね。
0506名無しさんNGNG
>>494
つーか、Linuxなの?
だったらmain threadのpidにだけkillしてみれば?
0507名無しさんNGNG
>>504
あと、動的プライオリティ計算がせこいのも、
プリエンプティブスケジューラとしては貧弱でしたな。
ブーストと言われても…
0508デフォルトの名無しさんNGNG
>>506
Linuxデス
0509デフォルトの名無しさんNGNG
今まですっとWinなスレッドしか使ってなかったけど
linuxのpthreadってなんか使いにくくてしょうがない
0510デフォルトの名無しさんNGNG
>>509
自由にぼやいて貰って構わないんだけど、
「Winなスレッド」って生CThreadのこと?
0511デフォルトの名無しさんNGNG
>>509
http://pc.2ch.net/test/read.cgi/unix/1010933537/l50
0512デフォルトの名無しさんNGNG
>>511
キモイ関数が沢山ありそうだね
0513デフォルトの名無しさんNGNG
キモイの定義ができない人はム板にはいりません
0514デフォルトの名無しさんNGNG
あげ
0515純スレNGNG
>>505
おお そんなものがあるのですが、Win厨で失礼いたしましたぁ!_O_
しかし、ますますマルチスレッドプログラミングの必要性を見失いつつあり…。
最近はマルチスレッドプログラミングで苦悩している人を見ていると、とてもかわいそうなわけで…。
0516デフォルトの名無しさんNGNG
>>515
マルチスレッドプログラミングは、やればやるほど
スレッドを減らす方向に設計したくなるという面白い側面がありますね
0517デフォルトの名無しさんNGNG
_beginthreadex() が返すハンドルは CloseHandle() APIで閉じなければ
ならないという事なんですが、CloseHandle() を呼び出す位置は
_endthreadex() が (明示的もしくは暗黙的に) 呼ばれる前、呼ばれた後の
どちらでも構わないんでしょうか。
0518デフォルトの名無しさんNGNG
ハンドルは参照カウンタで管理されてるからどちらでもよい
不要だったら生成直後にcloseしてもよい
0519517NGNG
>>518
ありがとうございます、助かりました。
0520デフォルトの名無しさんNGNG
マルチスレッドのプログラムについて質問があります。
諸兄の知恵を貸してください。

現在、Solarisベースでpthreadを使用したプログラムを作成しています。
これはバックグランドで動作させ、デーモンとして使用するものです。

生成したスレッドの内部では、動的にメモリの獲得・解放を繰り返すのですが、
ps -el でSZの項目を監視すると、数値が増加しつづけてしまい、減少しません。
Purifyもかけてみましたが、リークはありませんでした。

原因を調べるためwebを検索したところ
ttp://www.ncad.co.jp/~komata/c-kouza28.htm
このようなサイトを見つけました。

>スレッド内で動的に多量のメモリを確保すると、プロセスサイズが大きくなり、戻らない
とあるのですが、これは「スレッド内部でメモリを確保しまくるとSZの値は減らない」と
解釈していいのでしょうか?

長文ですいません。
0521デフォルトの名無しさんNGNG
この前手伝ったプロジェクトは、Windowsのクライアントソフトに
がんがんスレッドを走らせていた。5つくらい。
あるひとりの優秀である(と言われている)人が設計したらしいんだけれど、
ソースコードにコメントが無いし、独自にCOMを実装してる(実装方法はCOMそっくり)
そのくせプラットフォームはWindows限定で、しかもSTLは使ってはいけなくて
……愚痴はやめておこう

さて本題ですが、個人的にはリソースが絡まないのにマルチスレッドにしないで欲しいんだけど、
一体何の理由があってマルチスレッドを利用したんだと思いますか?
部外者の俺が思うに、
・ある程度知識のあるプログラマが自分にしか理解出来ないコードを作ることで、支配基盤をはっきりさせたかった
・過去に作っていた自分のプログラムを再利用したかった(でもコードを見ると多分違う)
・クライアントマシンにマルチプロセッサの時代が来る事を見越していた(これもコードを見ていると多分違う)
・パズルが好きだった。

マルチスレッドをよく使う方々、他になんか理由があれば教えてください。
0522デフォルトの名無しさんNGNG
何をするクライアントか書いてないから判断しようがない

windowsということで、STLを使ってDLLとデータをやりとりすると、
ランタイムの関係でメモリ周りで問題が出る場合がある

あんたが差してるリソースの定義が曖昧だ、
CPUリソースもリソースであるという考え方も出来る

要するにお前は死ねって事だ。
0523デフォルトの名無しさんNGNG
相談室ということで、質問をさせてください。

今、Windowsで_beginthread()関数を利用して、経験のため無意味にスレッドを走らせています。
しかし、処理があまりにも遅くなるのでちょっと不可解に感じていました。
そこで、ループの先頭にSleep(1);を付け加えたところ、急にスムーズに動きました。
何が原因でこのような現象が起こるのでしょうか?
0524デフォルトの名無しさんNGNG
一つのプロセス内にあるスレッドがどれも必死で
CPUを使おうとしているから、
OSがその競合を解消しなければならなくなる。
↓
Windowsはそんなに賢くない。
↓
遅い。

Sleep(1);を加えると、OSはアイドルタイムをスレッドに割り振る処理しか
しなくてよいので、負担が減って早くなる。と、てきとうなことを言ってみるテスト。
0525デフォルトの名無しさんNGNG
>>521
我儘と傲慢が文中に溢れてるね。
久々に見たイターイ作文だな。

突っ込みどころ満載だけど、一部。
コメントが無いってのは、
 「自分じゃ理解出来ないから説明しる」
STL は使ってはいけなくてってのは
 「自分は STL バリバリだから使え」
スレッド使う意味があるのかってのは
 「私はスレッドについては無知なので
  是非使うのを止めて頂きたい」
って事か?

自分より出来る人を陥れる事に夢中になりやがって。
そいつのレベルを越える事に精進しな。
0526デフォルトの名無しさんNGNG
>>525
その通りかも。精進します。

しかしコメントが無いのはマジで困りました。本当に理解できないのです。
WaitForMultipleObjectsが、一体どのリソースを待っているのか確認するのは大変でした。

STL使っては行けない理由はサイズが大きくなるからだそうです。
MFCのCArrayとかを使いなさいと言われました。

スレッドを使う意味があるのかってのは、本当に解らなかったからです。
どんなクライアントかを簡単に言うと、ドロップされたjpeg画像を読み込んで、
それを横一列にサムネイルで表示するだけのプログラムでした(その当時は)。
その後、ネットから画像を読み込む様に対応させる方向にするのかもしれないですね。
その意味では予めマルチスレッドで実装させる必要があるのかもしれません。

ちょっと厨房な質問スマソでした>ALL
0527デフォルトの名無しさんNGNG
サムネイル作成は結構重い処理だから
bgで作成してないとアプリが固まったようになってしまう

って事じゃないの?
0528525NGNG
>>526
をっ、マジだったのね。きつぃ言動スマソ。

使う、使わないの理由聞いてんじゃん。
2ちゃんで聞くより、本人(SE)が暇そうな時に
もっと直接聞いたほうが間違いないと思うけどな。
まぁ、いろんな意見を集めた方がいいけど...
0529デフォルトの名無しさんNGNG
>>527
それだけでもないみたいです。というのも、別にサムネイルを作るところを
別スレッドにしているわけではなくて、ただサムネイルを表示する
GUIの部分の、独自メッセージのやりとりをしている部分がマルチスレッドでした。

例えば、何もないダイアログを作り、そこにボタン、スクロールバー、
エディットボックス、などなどを追加していきます(プログラムで)。
で、一斉にそれらがマルチスレッドで処理を始めるという具合です。
それぞれ普通にプロシージャを使ってWindows任せで処理すればいいと思うんですが…。

>>523
多分、他のスレッドと同期を取って計算しているんだと思うけれど、その同期の取り方が
適当なグローバル変数などを使ってやってるのではないでしょうか??
例えばスレッドAでflag=1にすると、スレッドBの処理がはじまる、というような場合、
スレッドBでは、while(flag!=1); みたいに待機しているんだと思います。
その時に、一度flag!=1を確認すれば、すぐに別スレッドに処理を移すべきなのだけれど、
もちろんOSではそんなことはわからず、ある一定の決められた期間スレッドBでは
ひたすらflag!=1を評価し続けます。この時間はまるまる無駄です。

そういうタイミングでSleep(0)を入れてやると、すぐに別スレッドに処理が移るので、
効率的にCPUを使うことが出来る、という現象だと思います。
(この場合、Sleepは1でなくて0で問題ないはずです)
どうでしょうか?
0530デフォルトの名無しさんNGNG
>>521
そいつはやる気のある天才だな。
自分よがりとはいえ、そこまでの技術を「たかが」仕事で使ってしまう辺り、
自分の仕事に自信があり、その会社でも正当な評価を受けてる証拠だろう。
そういうコードはめったに見れないから、素直に見習ったほうが良いぞ。
ここで聞かずに、その天才に聞けよ。(なんで本人に聞かない?)
0531デフォルトの名無しさんNGNG
>>529
> そういうタイミングでSleep(0)を入れてやると、すぐに別スレッドに処理が移るので、
> 効率的にCPUを使うことが出来る、という現象だと思います。
> (この場合、Sleepは1でなくて0で問題ないはずです)

「マルチスレッド 同期」あたりで、一回グクッてみることをお勧めする。
0532デフォルトの名無しさんNGNG
>>523
EventかFiberを覚えよう
0533デフォルトの名無しさんNGNG
>>531
間違ってないんじゃね?
Sleepせずにビジーループで変数待機してると
割り当てCPU時間全部使うまでCPU解放しないわけだし。
0534デフォルトの名無しさんNGNG
同期については
Windowsにはウィンドウメッセージという機構があるんだから
ぜひともそれを使っていただきたいものです

下手に俺様キューを作るよりよっぽどマシです...
0535デフォルトの名無しさんNGNG
>>533
> 間違ってないんじゃね?

別に間違っているとは言っていない。そもそも...

>> 例えばスレッドAでflag=1にすると、スレッドBの処理がはじまる、

に対して...

>> スレッドBでは、while(flag!=1); みたいに待機しているんだと思います。

なんてことは普通しない。素直に、Event ととか使えば、スレッド B は待ってる間全然 CPU を使わない。
0536デフォルトの名無しさんNGNG
>>534
該当スレッドにウインドウが無い可能性もあるだろ
あと、WindowsのメッセージはHWND指定がついてくるのが気持ち悪い。
素直にイベントに汁
0537デフォルトの名無しさんNGNG
>>536
ウィンドウがなくてもメッセージキューとして使えることを
知らないアフォが多すぎ
0538デフォルトの名無しさんNGNG
>>537
勿論知ってますが。
GetMessageでHWNDの指定を強制させるのが嫌すぎというだけです。
非同期ソケットとか、トレイアイコンにも言えることですが。
0539デフォルトの名無しさんNGNG
強制ってのは何か違うな、、、
MSGにhwndが入っているんだから、それで良いじゃないかってだけです。
0540デフォルトの名無しさんNGNG
GetMessageのHWNDにNULL指定できることを知らないのか?
ヘルプもロクに読めないとは・・・
0541デフォルトの名無しさんNGNG
送り側スレッドがPostThreadMessageで送って、
受け側スレッドがGetMessageで受けるんでしょ。

それでメッセージキューが実現できるという話だと思うんだが
何をゴネてるの?
0542デフォルトの名無しさんNGNG
>>540
勿論知ってるっつーの
GetMessageにHWNDがあるのが気に入らないだけ
0543デフォルトの名無しさんNGNG
( ´_ゝ`)フーン
0544ゲイチュNGNG
>>542
気に入らないならWindows使うな( ゚Д゚)ゴルァ
0545デフォルトの名無しさんNGNG
>>529
> それぞれ普通にプロシージャを使ってWindows任せで処理すればいいと思うんですが…。

何故いいと思うのか根拠書かないと。

GUIスレッドを自前で持つなんて、
Look&Feelのレスポンスが重要な局面ではよくやることだよ。
何も不思議なことはやってない。(少なくとも提示されている条件内では)

それよりも君の>>521の姿勢がずっと疑問。
AFCのスレッドモデルについてちゃんと理解してるの?
0546デフォルトの名無しさんNGNG
>>545

MainThread:
0547デフォルトの名無しさんNGNG
>>545

>>521
>さて本題ですが、個人的にはリソースが絡まないのにマルチスレッドにしないで欲しいんだけど、
これ見る限り素人だし相手にしても無駄だよぅ
0548デフォルトの名無しさんNGNG
送信ミス、スマソ

>>545
MainThread: ダイアログを作る -> サブスレッド起動
Sub1: ボタンのメッセージを処理
Sub2: スクロールバーのメッセージを処理
Sub3: エディットボックスのメッセージを処理

って事じゃないの?

>で、一斉にそれらがマルチスレッドで処理を始めるという具合です。
こう書いてあるし
0549デフォルトの名無しさんNGNG
>>548
読み間違いに一票。
単に521が仕事できないだけだろ。
0550デフォルトの名無しさんNGNG
>>529
>スレッドBでは、while(flag!=1); みたいに待機しているんだと思います。
こんな事考えてる様なやつだしね(w
0551デフォルトの名無しさんNGNG
>>550
それは523があまりにも初心者だから、そう推測したんじゃないのか?
と、擁護してみる。
0552デフォルトの名無しさんNGNG
>>520
> >スレッド内で動的に多量のメモリを確保すると、プロセスサイズが大きくなり、戻らない

ここの、

> とあるのですが、これは「スレッド内部でメモリを確保しまくると
> SZの値は減らない」と解釈していいのでしょうか?

「スレッド内で」はあってもなくても同じ。(古典的UNIXとC(++)では)
単純ヒープモデルのメモリ管理は一度でかくなったら元に戻らない。
brk(2)を小さくするために呼び出すことはない。
// 「スレッド内で」と書いてあるのは、プロセスからの類推で、
// スレッドが終了したら、利用していたメモリも
// 解放されると誤解する人がいるからでしょう。

理由は、malloc(3)したメモリオブジェクトの位置を変えられないので、
羽抜け状態になるからです。emacsでは可変長オブジェクト用ヒープの
コンパクションをして、巨大化を防いでいます。
(それでもいったん大きくなるとそのまま)

話せば非常に長くなるので、
http://www.saiensu.co.jp/books-htm/ISBN4-7819-0303-7.htm
の「動的な記憶割り付け」を。さらに進むには、
http://www.google.com/search?q=garbage%20collection%20site%3Aamazon.co.jp&sourceid=mozilla-search&start=0&start=0&ie=utf-8&oe=utf-8
でも読んでください。英語読めるなら、これも。
http://www.amazon.co.jp/exec/obidos/ASIN/0471941484/qid=1033055505/br=1-1/ref=br_lf_fb_1/249-2956017-1293960
"w3m"のweb pageとドキュメントも参考になるかも。

ちなみにthread関係ないから、
この話題続けるならUNIXプログラミングスレに。
0553デフォルトの名無しさんNGNG
マルチスレッドってどういう時に使うの?
0554デフォルトの名無しさんNGNG
>>553
エロゲーやりながらオナニーしたいときとかだね。君の場合。
0555デフォルトの名無しさんNGNG
>>554
マ板へどうぞ
0556デフォルトの名無しさんNGNG
>>542

 嗚呼、無能なヤシは困る…

 505をお読みになったか?
0557デフォルトの名無しさんNGNG
どうでもいいがWaitFor〜じゃメッセージ待機出来ても取得できないぞ
0558デフォルトの名無しさんNGNG
>>557
WaitFor〜じゃメッセージ待機できない。
できるのはMsgWaitFor〜だよ。

それでもメッセージの取得はできないが、メッセージが届いている事を
前提にできるから、GetMessageでブロックせずに取り出せる。
0559デフォルトの名無しさんNGNG
>>558
GetMessageが気に入らないんじゃなくてHWNDが嫌いなんだから、
PeekMessageも当然ダメだろ。
0560HWNDNGNG
すみません、僕のことで揉めるのは止めて貰えないでしょうか?
僕だって困ってるんです。隠居して、田舎暮ししたい…
0561デフォルトの名無しさんNGNG
NULL指定してても気に食わないとかいう理由で
だめとか言ってるんだから単なる言いがかりだろ
0562542 じゃねーけどNGNG
>>561
> NULL指定してても気に食わないとかいう理由で
> だめとか言ってるんだから単なる言いがかりだろ

言いがかりって...、Windows マンセー野郎様ですか ?

メッセージキューは本来もっと一般的なものだから、基本的には HWND なんてものがいらない素のバージョンの API があって、ウィンドに対するメッセージは、これをラップして使えばいいと思う。
でも、Windows では大多数がウィンドに対するメッセージだから、HWND 付きのメッセージ機構のをウィンド無しでも使えるようにしたという実装も理解できなくは無い。
俺はそう言う実装は嫌いだけど、それ以外の利点が大きいから Windows を使う。ただそれだけじゃないの ?
0563デフォルトの名無しさんNGNG
気に入る気に入らないの問題だったらどうでもいいです
0564デフォルトの名無しさんNGNG
>>562
使うもなにも、用意されてる選択肢がそれしかないんですけど。
0565デフォルトの名無しさんNGNG
ハァ?自前でメッセージキュー作れますが?
0566552NGNG
>>552
がーん、コピペ失敗した…

> さらに進むには、
> http://www.google.com/search?q=garbage%20collection%20site%3Aamazon.co.jp&sourceid=mozilla-search&start=0&start=0&ie=utf-8&oe=utf-8
> でも読んでください。

これです。
省メモリプログラミング―メモリ制限のあるシステムのためのソフトウェアパターン集
http://www.amazon.co.jp/exec/obidos/tg/detail/-/books/4894714086/glance/249-2956017-1293960
省メモリシステムに限らず、メモリ管理全般に有用です。
0567デフォルトの名無しさんNGNG
>>565
わざわざ気に入らないからって、スレッド対応のメッセージキュー作るの?
0568デフォルトの名無しさんNGNG
>同期については
>Windowsにはウィンドウメッセージという機構があるんだから
>ぜひともそれを使っていただきたいものです
>下手に俺様キューを作るよりよっぽどマシです...
そういう風に作ってしまった場合、
ログオンプロンプト(パスワード入力画面)のまま、
ATコマンドやRPCでプログラムを起動したらどうなるの?
これがWindowsのプログラムのヤナ部分。
0569デフォルトの名無しさんNGNG
なんの話?
0570デフォルトの名無しさんNGNG
>>568
GUIスレッドと
ATコマンドやRPC発行スレッドを
別にすりゃいいんでないの?
0571デフォルトの名無しさんNGNG
>>569
たとえばTVのタイマー録画のソフトを作った場合、
パスワードを入れた状態でユーザーが外出したり
することになるでしょ。
デスクトップを開いていない状態でウインドウハンドル
を操作するAPIを実行するとそこで停止するかエラーになるでしょ。
0572デフォルトの名無しさんNGNG
いまいちよくわからんのだが。
もしかして、関わらない方が良い?
0573デフォルトの名無しさんNGNG
571はエラーになることを確かめたの?
0574デフォルトの名無しさんNGNG
>>同期については
>>Windowsにはウィンドウメッセージという機構があるんだから
>>ぜひともそれを使っていただきたいものです
>>下手に俺様キューを作るよりよっぽどマシです...
>そういう風に作ってしまった場合、

>デスクトップを開いていない状態でウインドウハンドル
>を操作するAPIを実行するとそこで

HWNDにNULLを入れるからウィンドウハンドルは操作しませんよ?
0575デフォルトの名無しさんNGNG
ウインドウシステムと依存関係のあるモジュールを
使ったプログラムは、ログアウトした状態では
使えなくなる欠点があるだろ。
だから、夜間にログアウトした状態で
OLEを使ってエクセルのシートを集計したりできないわけ。
端末の上でしか動かないという制約のあるモジュールは
なんだかな。
0576デフォルトの名無しさんNGNG
>>571はエラーになることを確かめたの?
NT上で確かめたよ。
サービスの作り方で、停止するかエラーかが決まる。
0577デフォルトの名無しさんNGNG
>>575
ちょっと飛躍するけど、user32.dllを使ったAPIやつが駄目って事?
0578デフォルトの名無しさんNGNG
s/APIやつ/API/
0579デフォルトの名無しさんNGNG
575-576
それってMessageBoxとかを出すときの話では?

元はメッセージキューをWindowMessageで代用するという話だったのに、
いつのまにすり替わりましたか?

>>572
あんたするどい
0580デフォルトの名無しさんNGNG
>>565
> ハァ?自前でメッセージキュー作れますが?

普通作れるだろ ?
>>567 の言うように普通は、「作らない」けどな。

>>572
俺もそう思う。
0581デフォルトの名無しさんNGNG
つかサービス用にデスクトップが割り当てられるだろ。
使ったこともないくせに想像でモノを書いてるUNIXプログラマ様ですか?
とか>>572の警告を無視して釣られてみる。
0582デフォルトの名無しさんNGNG
>>562
HWNDにNULLを指定すればHWNDなんてものはいらないだろ。
お前はほんとにGetMessageの引数にNULLがあるせいで困ってるのかと
小一時間問い詰めたい
単にMSの設計はセンスが悪いって言いたいだけちゃうんかと。
0583間違えたNGNG
s/NULLがあるせいで/HWNDがあるせいで/;
0584デフォルトの名無しさんNGNG
>>582
> 単にMSの設計はセンスが悪いって言いたいだけちゃうんかと。

ただそれだけだけど ? (つーか、>>562 は普通そうとしか取れないと思うが。)

誰も困ってるなんて書いてない (除く >>560) んですが、妄想ですか ?
0585デフォルトの名無しさんNGNG
>>584=562=話の流れを理解してないやつ?
つーかね。きみ文章ヘタ。
0586デフォルトの名無しさんNGNG
>>585
で、あんたは何言いたいの ?
0587デフォルトの名無しさんNGNG
>つかサービス用にデスクトップが割り当てられるだろ。
システムからダイアログを唐突に出されたら止まるから却下。
0588デフォルトの名無しさんNGNG
デスクトップが唐突に出てきた背景の説明キボンヌ
0589デフォルトの名無しさんNGNG
依存関係を作るって事に対する疑問符だな。
0590デフォルトの名無しさんNGNG
>でも、Windows では大多数がウィンドに対するメッセージだから、
>HWND 付きのメッセージ機構のをウィンド無しでも使えるようにした
これのソースキボンヌ。
この挙動は保証されているのかな。
0591デフォルトの名無しさんNGNG
>>588-590
Win32APIスレに移動だな
もはやマルチスレッドとは関係ない
0592デフォルトの名無しさんNGNG
URL忘れスマソ
http://pc3.2ch.net/test/read.cgi/tech/1032548635/l50
0593デフォルトの名無しさんNGNG
すんません、話の流れとそれるかも知れませんが
WindowsでGetMessage等を呼ばずにシステム互換のメッセージキューを作る方法教えてくれませんか?
0594デフォルトの名無しさんNGNG
Windows限定だったらwin32apiスレで聞けば?
0595デフォルトの名無しさんNGNG
>>593
MUTEXをロック
受信側は共有メモリにFIFOバッファを作る。
ポーリング時だけ開放

送信側は送信時にMUTEXをロックしようとする
→相手がポーリグするまでブロックされる。

双方向にする場合は双方でFIFOを持ったうえで
さらにデッドロックしないようにプロトコルを明確化する。
0596デフォルトの名無しさんNGNG
>>595
> MUTEXをロック
> ポーリング時だけ開放
> 送信側は送信時にMUTEXをロックしようとする
> →相手がポーリグするまでブロックされる。

それって一個しかデータが入らないから、キューじゃねーじゃん。

普通は、ポーリングする瞬間だけロックして、キューが空だったら何らかの同期機構で待つ。
送信側も書き込む瞬間だけロックして、キューが満杯だったら待つ様に作る。

(普通のキューと同じだと思うが...。)
0597デフォルトの名無しさんNGNG
入門書にでも書いてありそうなことをここでやるの?
0598デフォルトの名無しさんNGNG
>それって一個しかデータが入らないから、キューじゃねーじゃん。
FIFOだからキューだろうが。普通はリングバッファにするわけだ。
>普通は、ポーリングする瞬間だけロックして、
>キューが空だったら何らかの同期機構で待つ。
つまり、開けて待機することがポーリングなわけだ。
双方向だとデッドロックとかめんどくせぇ問題が起きるから
なるべくサーバー・クライアント型にして、
サービス側リクエストがくるまでずーーと待機というデザインだな。
オレの場合。
0599デフォルトの名無しさんNGNG
>>597
つまらないと思うなら無視すればいいだろ
いちいち突っ込むなボケ
0600デフォルトの名無しさんNGNG
>>599
無知がほざくなボケ
0601デフォルトの名無しさんNGNG
>システム互換のメッセージキューを作る方法教えてくれませんか?
だれもこれを満たしてない
0602デフォルトの名無しさんNGNG
>>600
童貞が吠えるなハゲ
0603デフォルトの名無しさんNGNG
>>597-602
お前らまとめて逝ってよし
0604デフォルトの名無しさんNGNG
>>603
禿
・
同
0605デフォルトの名無しさんNGNG
>>602
低学歴はすっこんでろ
0606デフォルトの名無しさんNGNG
>>604
プッ
ずれてるよ
バーカ
0607929NGNG
>>598
> なるべくサーバー・クライアント型にして、
> サービス側リクエストがくるまでずーーと待機というデザインだな。

それは、キューとは言わん。
0608デフォルトの名無しさんNGNG
>>605
マジで言ってるのか?
氏ねよボケ
0609デフォルトの名無しさんNGNG
>>608
低学歴なお前が死ね
0610デフォルトの名無しさんNGNG
>>609
まずお前が死に方の見本を見せろ
0611デフォルトの名無しさんNGNG
まあまあ、落ち着け。お前等のおかけで、このスレが「哲学者の食卓」みたいになってるよ。
二人とも、ちょっと Sleep(100) ぐらいしてこいや。
0612デフォルトの名無しさんNGNG
>>611
まずお前が氏ね
0613デフォルトの名無しさんNGNG
すみなれたーわがやにー はなのかほりをそーえてー
 やさしくーそだったー じゅもくかほりもいーれてー
このまちでーいちばんー すてきでくらしたーいー
 りふぉーむーしようよー しんーにほんーはーうすー
0614デフォルトの名無しさんNGNG
環境はLinux + pthreadで、

/* pthread_createに渡す関数 */
void* thread_func(void* arg)
{
  int* sd = arg;  /* sd: ソケットディスクリプタ */
  char c;

  while (1) {
    int result = read(sd, &c, 1);

    if (result == 1) {
      fputc(c, stdout);
    } else if (result == 0) {
      usleep(WAIT_MSEC);
      continue;
    } else {
      perror("read on thread_func");
      pthread_exit(NULL);
    }
  }
}

…としています。ソケットにデータが流れてきた時にreadするように書きたいのですが、
usleepを使う以外の方法はありますか?
0615デフォルトの名無しさんNGNG
>>614なんでselect使わんの?
0616デフォルトの名無しさんNGNG
(´-`).。oO(select知らないんだろうなあ)
0617デフォルトの名無しさんNGNG
CreateThreadで作られたスレッドには、lpParameterで指定した情報しか
わたすことができないんですか?
初心者な質問でスマソ。
0618デフォルトの名無しさんNGNG
つーか自分でやってみりゃいいじゃん
0619617NGNG
自分でやってみてどうしようもなくなりました。
2つ以上のパラメータを渡したかったらどうするんですか?
0620デフォルトの名無しさんNGNG
>>619
パラメータのリストを渡す
0621デフォルトの名無しさんNGNG
>>617
パラメーター構造体を定義して、mallocして
そのポインタを渡すというのが常套手段ッス〜
0622デフォルトの名無しさんNGNG
そしてスレッドを使わないプログラムに回帰するのであった・・・
というネタが繰り返されるスレはここですか?
0623初心者NGNG
初心者が質問してごめんなさい。
今、エディタにプログラム書いて、コマンドプロンプトでコンパイルしてみたいな
ことしているんですが、マルチスレッドってこんな環境で使えるの?VCのような
開発環境でないとダメ?
0624デフォルトの名無しさんNGNG
>>623
開発環境は関係ない。
というか関係があるのかどうか自分で判断できるように努力しる。
0625デフォルトの名無しさんNGNG
>>624 ネタにマジレスすんなハゲ
0626デフォルトの名無しさんNGNG
>>614,615
select知りませんですた(´・ω・`)ショボーン。ありがとう。
0627デフォルトの名無しさんNGNG
プログラムは、理論を学習するのと、理論なくしてプログラミングを実践するのとどっちが重要ですか。
0628デフォルトの名無しさんNGNG
スレ違いに気づかないようなバカは何をやっても無駄
http://pc3.2ch.net/test/read.cgi/tech/1006617496/l50
0629デフォルトの名無しさんNGNG
>>628
ほざくな
0630デフォルトの名無しさんNGNG
>>627
マジレスするとどっちも重要。
実践して壁に当たってから理論せれ。
壁に当たらんと、理論のありがたさがわからん。
0631デフォルトの名無しさんNGNG
>>630
http://pc3.2ch.net/test/read.cgi/tech/1033317659/l50
0632デフォルトの名無しさんNGNG
質問。

スレッドをいくつか作成して、
メインスレッドが各スレッドにPostThreadMessage、
サブスレッドはGetMessageでそれを捌く。

これを数万〜数十万オーダー繰り返すとたま〜にGetMessageがデッドロック起こす現象に悩まされたことがあるんだけど、
他にそんな人いる?

すっごいシンプル(100行未満)なテストプログラムでも起こったんで、何か原因があるとは思うんだけど見当つかなかった。
0633デフォルトの名無しさんNGNG
>>632
再現するソースは?
0634デフォルトの名無しさんNGNG
>>617,619
構造体のポインタか、クラスのポインタわたせば?
0635デフォルトの名無しさんNGNG
>>634
s/構造体のポインタ/構造体のインスタンスのポインタ/
s/クラスのポインタ/クラスのインスタンスのポインタ/
0636デフォルトの名無しさんNGNG
>>632
while(GetMessage(&msg,NULL,0,0))
とかやってないよね
0637デフォルトの名無しさんNGNG
>>636
いけないの?
どこのサンプルでも-1をチェックしてないようだけど
0638636NGNG
>>637
確かに、大抵のサンプルはそうなってるけど、チェックした方がいいよ。
↓を見てね。
http://www.microsoft.com/japan/msdn/library/ja/jpwinui/html/_win32_getmessage.asp
0639632NGNG
ども。
数年前の話だったので久しぶりにソースおこして確認してみました。

その結果、PostThreadMessageで10001個目のメッセージをPostするとエラーが返っていたことが判明。
GetMessageはエラーを返さず、GetLastErrorも0を返していたけれど
単純にメッセージキューのオーバフローが原因だと思われます。

前回はエラーチェックが甘かったのかな。
結局自前でスレッド間メッセージキューを実装してしまいました。
まぁその経験がその後の仕事で活かされた(pthread使う仕事があった)ので
自分的には結果オーライでしたが。
0640636NGNG
>>639
原因は判明したみたいだから、参考までに・・・
http://www.microsoft.com/japan/msdn/library/ja/jpwinui/html/_win32_postthreadmessage.asp
0641デフォルトの名無しさんNGNG
-1が失敗であって、-2が成功とも言えるからチェックがめんどくさいな
0642デフォルトの名無しさんNGNG
>>640
かつてのSetMessageQueueSizeの説明には
ポストできるメッセージの数に上限はなくなったとか書いてたのに
なんかインチキくさいな
0643デフォルトの名無しさんNGNG
つか回数制限を知らないヴァカがいることが驚き。
0644デフォルトの名無しさんNGNG
>>642
×SetMessageQueueSize
○SetMessageQueue
上限がなくなったとは書いてない。
必要に応じて拡張されるようになったと書いてある。
Win2Kにおける既定の拡張限界が10,000ということ。
0645デフォルトの名無しさんNGNG
メッセージを取り出さないで10000個Postしたって事?
普通にアプリケーション組んでれば、10000個以上のメッセージの送受信普通だが。
0646デフォルトの名無しさんNGNG
10000個も滞留するのが普通なのか・・・
0647デフォルトの名無しさんNGNG
>>644
10,000個以上の必要には応じてくれないんですか?
やっぱ強引というかMSに好意的過ぎる解釈だと思う。
古いPostMessageのヘルプにはこんな制限書いてなかったし
0648デフォルトの名無しさんNGNG
>>647
>10,000個以上の必要には応じてくれないんですか?
ヴァカ発見(プ
0649デフォルトの名無しさんNGNG
>>647
何事にも制限はある。
どうしても、
10000個以上のメッセージを溜める糞ソフトを書きたければ、
レジストリを修正しろと書いてるだろ。
あと、この10,000という数はWin2kにおける数値だから、
Win2kが出る前の古いヘルプに書いてあるわけがないと思われ。
0650デフォルトの名無しさんNGNG
>>649
Win2000以前には制限がなかったのに
突然制限つけてドキュメントのほうまで変えるのが納得できない。
今まで95/98/NT4で動いていたプログラムが
動かなくなるってことでしょ。
0651デフォルトの名無しさんNGNG
>>650
試してみた?
手元にあったWin98マシンで試すと、
1000くらいが限度みたい。
95/NT4は手元にないので試せないけど。
0652デフォルトの名無しさんNGNG
>>647
おまえみたいなアフォがゴルァして来てウザいから追加されたんだろ。
0653デフォルトの名無しさんNGNG
ここは強引なAPIの変更、それによるソフトウェアの構造の変更を
強いられることをありがたがるオメデタイMS信者しか居ないようですね。

こういった変更が無いことが保証されている環境は存在しないのでしょうか。
もうこれ以上馬鹿を見るのはごめんです。
0654デフォルトの名無しさんNGNG
致命的なバグがあっても改善されない環境を
望んでいる変人がいるすれはここですか?
0655デフォルトは上限無しさんNGNG
WinのAPIが安定しないことは確かだが、
>>644,649はどうみても妥当。セマンティクスは厳密になり、
しかも上限は変更可能になっている、ということで言い掛かりだと思う。

と>>653に釣られてみる。
0656デフォルトの名無しさんNGNG
win界隈はドキュメントされてるだけマシっつう話もアルヨ・・・
0657デフォルトの名無しさんNGNG
LinuxやFreeBSDなら「ソースを使え、ルーク」なのだろうが
Appleとかどうするんだろ
0658デフォルトは上限無しさんNGNG
>>657
とりあえずDarwinのソースでまあなんとか。
え? Mac OS < 9ですか? およびでない? 失礼しました〜。
0659デフォルトの名無しさんNGNG
>>657
>「ソースを使え、ルーク」なのだろうが
ワラタ
0660653NGNG
windows上C言語でプログラミングしてて、マルチスレッドを使おうとしてます。

CreateThread()を使おうと思ってるのですが、作成したスレッドには一つしか引数を渡せないのでしょうか?
複数の引数を渡したいのですが・・・
0661660NGNG
653と名のってますが間違いですw
0662デフォルトの名無しさんNGNG
クイックソートをマルチスレッドで書いたら速いので教えてください。
0663デフォルトの名無しさんNGNG
>>660
>>617 >>619
バカばっか・・・
0664デフォルトの名無しさんNGNG
>>662
並列アルゴリズム ソート
でgoogleしてみよう!

つかCPU数が2以上じゃないと多分効果ないと思う
0665660NGNG
>>663
thanks
0666デフォルトの名無しさんNGNG
Windowsでプログラムしてマルチスレッドを使おうとしています。

BeginThreadを使おうと思っているのですが、作成したスレッドには1つしか引数を渡せないのでしょうか?
複数の引数を渡したいのですが・・・
0667デフォルトの名無しさんNGNG
これは何かの陰毛なのか?
0668デフォルトの名無しさんNGNG
>>666
お前、ちょっとは頭使え
0669660NGNG
>>668
お前、ちょっとは頭使え
0670デフォルトの名無しさんNGNG
構造体、、
0671デフォルトの名無しさんNGNG
ネタは放置
0672デフォルトの名無しさんNGNG
>>442
大昔の話をいまさらだけど、素朴な疑問。

それらのスレッドが動き出す前に1回init_Gを呼んでおく
(そして各スレッドでは呼ばない)
ってわけにはいかないんですか?
まあそういかないから質問してたんでしょうけど。
0673デフォルトの名無しさんNGNG
>>672
・init_G()が呼ばれるかどうかは事前には判らない
・init_G()の呼び出しは少なからず何らかの常駐リソースを食う
 (DLLのロードやメモリアロケート等)

という前提ならああしたくなるでしょうね。
0674デフォルトの名無しさんNGNG
なんとなく浮上
0675デフォルトの名無しさんNGNG
あるスレッドに文字配列を渡そうとして以下のようにやってみて、受け取り成功したのはいいのですが
このPostThreadMessageしたときに渡したローカル変数bufは、自動的に解放されますか?(受け取りで何かする必要あり?)

//送信側
char buf[]="ゴルァ";
PostThreadMessage(idThread, WM_USER+10000, (WPARAM)buf, 0);


//受信側
GetMessage(&msg, NULL, 0, 0);
0676デフォルトの名無しさんNGNG
自動変数なら、関数から抜けたときに開放される。
そういうう変数をPost〜で渡すのは、不確実性の元。
渡してはいけない。
0677675の上司NGNG
>>675
バカ野郎!そんなコード納品したらクビにするぞ!
二度とするなよ。いいな?

どうしてもやりたきゃ、こうしろ。
PostThreadMessage(idThread, WM_USER+10000, (WPARAM)"ゴルァ", (LPARAM)">>675の上司より");
0678デフォルトの名無しさんNGNG
Javaでタイムアウト付きのwait()した時に、notify()されたのか、
タイムアウトしたのかを判断する方法知ってる人いる?

つーか、何でタイムアウト付きwait()の戻り値がvoidなの?
0679C ◆dq2PerGLN. NGNG
CFileのMFCにあるファイルを開くダイアログはC#だとどのクラスでどのメソッドにあたるのですか?
0680デフォルトの名無しさんNGNG
>>679
誤爆?
0681デフォルトの名無しさんNGNG
>>678
区別する方法は知らない。

> 何で
区別する必要がないから、じゃない?
0682678NGNG
>>681
あ、やっぱ出来ないのね。つーか、何で区別する必要ないの?
notify()されたかタイムアウトしたかって完全に意味違うぞ。

pthread_cond_timedwait()はタイムアウトしたらETIMEDOUT返す。
WaitForSingleObject()もWAIT_TIMEOUT返す。
普通はこんなもんだと思うんだが。

やっぱJavaって変な仕様多いな・・・(^^;
0683681NGNG
そりゃ変だよ。最初はthread.stop()なんていう糞仕様があったぐらいだし。
複数オブジェクトに対しor条件でwaitできれば少しはマシだったのに。
ああでも最近のJavaがどうなってるかは知らないよ。
1.4なんてぜんぜん見てない。

> 完全に意味違うぞ。

意味は違うけど、その後の処理は
 *ほとんどの場合においてほとんど同じ*
という罠。

solarisのman pageのcond_timedwait()の使用例でも、抜けた後、
「やっぱり処理する必要があるかチェック」してたりする。

俺のトリアタマでは、複数のワーカースレッドが単一のリクエストキューを
待つ、という使い道しか思いつかないや。
0684名無しさん@XEmacsNGNG
pthread_cond_timedwait()がtimeoutを決めてから、
pthread_cond_signal()が発行された時、
timedwait()を行った側でsignal状態の後始末をする必要があるかどうか?

ある: 返り値で区別出来てもraceは残る。→何らかの方法で解決。
ない: しかしどちらかは知る必要はある: 返り値で教えろや、(゚Д゚)ゴルァ!
   どちらでもいい: (´-`).。oO(返り値何のためにあるのだろう)

最初の場合は、排他しながら調べるしかないね…
0685681NGNG
>>683
確かに普通の場合はほとんど同じことが多いかもしれない。

ちょっとWin32のEventみたいなの作ってて、wait()系のメソッドを
包んだ待機メソッド(タイムアウト付きも)実装するのに不便だな、と。
0686デフォルトの名無しさんNGNG
セマフォをOSでなくソフトで実現する方法ってありますか?
0687デフォルトの名無しさんNGNG
>>686
メッセージとか共有メモリを使って
代替の機能は作れると思うけど。

意味は、ないわな。
0688デフォルトは上限無しさんNGNG
>>686
セマフォは本来ソフトウェアだけで実装できるものだが、
タスク切り替えをしなければいけない/した方が効率がいい都合上、
カーネルスレッドなシステムではカーネルに実装されていること多い。

自分で実装する場合、タスク切り替えをどうするか考えないといけない。
M:Nスレッドが実装されているシステムだと、CPUを明け渡すAPIがあると思う。
Linux, *BSD, Solaris, NGPTのソースが参考になる。

UNIX System V IPCのセマフォのように、
processが死んだ時のundoを実装しているような高機能なものを作ろうとすると、
やはりカーネルの世話にならざるを得ない。


0689デフォルトの名無しさんNGNG
>>687-688
ありが�d。
0690デフォルトの名無しさんNGNG
Redhat8, gcc-3.2, glibc-2.2.93 でコード書いているんですが、acceptが妙な
戻りで帰ったとおもったら直後、突然SIGKILLされてしまいます。

[pid 8618] <... accept resumed> 0x4185fa6c, [0]) = ? ERESTARTSYS (To be restarted)
[pid 8617] <... select resumed> ) = ? ERESTARTNOHAND (To be restarted)
[pid 8618] +++ killed by SIGKILL +++
+++ killed by SIGKILL +++

これの原因、何かわかりませんか・・? tcpのポートをbindしてacceptしている
だけなんですが。。
0691デフォルトは上限無しさんNGNG
>>690
> 妙な戻り

signalによるsystem callの中断って分かりますか?
/usr/include/linux/sched.hのマクロなんかでは積極的に使ってますね。

pid 8617の方は、signalによるsystem callの中断があり、
system callをrestartしようとしたら、
指定されていたfile handleがなくなっていた、というエラーです。

glibcはpopen(3)以外ではSIGKILLを出さないみたいだけど…
状況がよく分からないので、こんなところですね。
0692デフォルトの名無しさんNGNG
WIN32ですが、クラス内でスレッド作るってどうやるんでしょう?
0693デフォルトの名無しさんNGNG
>>692
クラスの中で_beginthreadしてください
としか言えない

Javaみたいにクラスまるまるスレッド化とかは無理よ?
0694デフォルトの名無しさんNGNG
>>693
startメソッド呼んだらrunメソッドが新しいスレッドで
走るクラスくらい簡単に作れると思うけど
0695誤爆くさいので貼ってみるNGNG
446 名前:デフォルトの名無しさん 投稿日:02/10/24 11:12
//以下では駄目なのですがどのようにすれば良いのでしょうか?
//ThreadReceptionはクラス内で定義したいのですが・・

class ThreadClass {
public:
void ThreadHead();
void ThreadReception(void*);
private:

};
void ThreadClass ::ThreadHead (){

_beginthread(ThreadReception,0,0);

return;
}
void ThreadClass ::ThreadReception(void*){
return;
}
0696誤爆くさいので貼ってみるNGNG
>>695
_beginthreadex
0697デフォルトの名無しさんNGNG
あ、名前欄戻し忘れた
0698デフォルトの名無しさんNGNG
ごめん_beginthreadでもできた。
コンパイルして確認とってないから間違ってるかもしれないけど
そのへんは適宜脳内補完してくれ
class ThreadClass {
public:
void ThreadHead();
void ThreadReception(void);
private:
static void ThreadClass::RealThreadReception(void* tc);
};
void ThreadClass ::ThreadHead (){

_beginthread(RealThreadReception,0,(void *)this);

return;
}
void ThreadClass ::ThreadReception(void){
return;
}
static void ThreadClass::RealThreadReception(void* tc){
return ((ThreadClass *)tc)->ThreadReception();
}
0699デフォルトの名無しさんNGNG
度々すいません・・。
'_beginthread' : 1 番目の引数を 'void (void *)' から 'void (__cdecl *)(void *)' に変換できません
っていわれるんですが・・。
0700デフォルトの名無しさんNGNG
>>699
いわれたまんまだろ
そのぐらい自分でどうにかしろ
0701699NGNG
すいません、勘違いでした。
無事コンパイル通りました、ありがとうございました。m(__)m
0702デフォルトの名無しさんNGNG
Cの通信アプリで、
printfを削除すると挙動が変わってしまうのですが、
そんなときどうすればよいのでしょうか?
0703デフォルトの名無しさんNGNG
>>702
挙動が変わる原因がタイミングによるものでないなら、原因は 99% 以上君のプログラムのミスだから、ソースコードレビューを死ぬほどやりなさい。
0704デフォルトの名無しさんNGNG
printf入れると、スレッドのプライオリティが下がる
ような挙動なんです。
0705デフォルトの名無しさんNGNG
はぁ?
0706デフォルトの名無しさんNGNG
WaitForSingleObjectに渡すハンドルをもとに、
別スレッドからこのスレッドを破棄したいのですが、
可能でしょうか?
0707デフォルトの名無しさんNGNG
>706
Win32の話ね。
WaitForSingleObjectに渡すハンドルってスレッドハンドルのことなら
TerminateThreadに渡せばスレッド終了できるけど…。
独自プロトコル作ってイベントやメッセージで通信するのがお勧めだよ。
0708デフォルトの名無しさんNGNG
>>704
>>705 じゃないけど、確かに「ハァ ?」だよ。
単に、「スレッドのプライオリティが下がるような挙動」じゃわけわからんよ。
具体的に何がどうなるのか書いてみ。
0709デフォルトの名無しさんNGNG
アーカイブってどういう意味?
馬鹿ですいません 教えてくださひ
0710デフォルトの名無しさんNGNG
>>707

ありが�d。
私の考え方がマズかったです。
SetEventを使用した独自プロトコルでうまくいきました。
0711デフォルトの名無しさんNGNG
>>709
***すれ立てるまでもない質問はここで 第24刷***
http://pc3.2ch.net/test/read.cgi/tech/1035354069/l50
0712デフォルトの名無しさんNGNG
>>709
辞書ぐらい買うか、ググルぐらいしたら ?

http://www.yamagata.tao.go.jp/HTML/keyword.htm

つーか、激しくスレ違いだよ。
0713デフォルトの名無しさんNGNG
>711
サンキュ
>712
すまん
0714695NGNG
クラス内にスレッドを作成して、そのクラスを配列で複数定義して
処理を同時進行でするようなプログラムを作ったんですが、途中で処理速度が著しく落ちます。
クラスにしなかった場合とした場合とを比べるとクラスにしない場合の方が10倍ぐらい早いです。
何度もデバックしてみましたが原因不明です。
エラーもでないしなにがわるいんだろうか・・・・・
0715デフォルトの名無しさんNGNG
複数のスレッドが激しくCPUを奪い合うようになってたら、
シングルスレッドよりも遅くなるよ。
0716695NGNG
クラス化した理由はスレッドの関数を複数定義するのが面倒だし、スマートじゃない為でして、
#クラス化しなくてもいい方法があるかもしれませんが・・
スレッドの数はクラス化する前も、した後も同じなので恐らく速度が落ちる事は無いと思うんですが・・
0717デフォルトの名無しさんNGNG
そりゃアンタのプログラムがバグってるか
アンタがバグってるかのどっちかじゃろうね
0718デフォルトの名無しさんNGNG
子スレッド中でのfork-execは、安全ですか?
ターゲットはLinuxおよびCygwinです。
0719718NGNG
pthreadsでは、fork直後のexecは安全であるべきと
いうことになっていたので逝ってきます。
0720デフォルトの名無しさんNGNG
Cygwinでpthreadはもうまともに動いているの?
少し前に聞いた話だと、バグだらけで使い物にならないとか。
0721デフォルトの名無しさんNGNG
>>720
バグ取りは随時やってるようだけど、「まともに動いている」という話は
最近でも聞かないねぇ。まぁ動けばめっけもん、くらいに考えておいた
方がいいんじゃないかな。
0722デフォルトの名無しさんNGNG
cygwinのpthreadならwindowsのAPIラップするだけじゃないの?
自体はそんなに簡単じゃないのかな?
0723デフォルトの名無しさんNGNG
UNIXエミュレーションとの整合を取る部分で死ねるのだと思われ
0724デフォルトは上限無しさんNGNG
>>722
そんなに簡単じゃない。
pthreadはpthread単独で意味があるわけでなく、
signal, I/Oなどなどとセットではじめて意味がある。
それぞれとの相互作用においてPOSIXに合っていなければ、
わざわざ使う意味がない。(Win32 APIでいいじゃんという意味において)
0725デフォルトの名無しさんNGNG
「APIラップするだけじゃないの」と疑問を抱くレベルなら
確かにAPI直接使えばよさげだ
0726デフォルトの名無しさんNGNG
Cランタイムとの整合性なんかを考慮してねえとまずくないかな
0727デフォルトの名無しさんNGNG
そらまずいだろうね。
ただまぁ最悪自分で同期取ればいい話でもあるが。
0728デフォルトの名無しさんNGNG
APIで上げたスレッドからは一切Cygwinの機能を使わなければ
なんとかなりそうだ
0729デフォルトの名無しさんNGNG
pthread仕事で使ってる人います?
0730デフォルトの名無しさんNGNG
使うかもしれないから調査中
0731デフォルトの名無しさんNGNG
Cygwinのsocketは、未だthread safeではなさげ(DLLのソース読んで確認)
ひとつのfdに対して複数スレッドでaccept(2)して、ひどいめに遭った
0732デフォルトの名無しさんNGNG
cygwinってfork使えますか?
0733デフォルトの名無しさんNGNG
fork遅いよ
っていうかスレ違いだろ
0734デフォルトの名無しさんNGNG
cygwinってspoon使えますか?
0735デフォルトの名無しさんNGNG
>>734
knifeなら使えます
0736デフォルトの名無しさんNGNG
Windowsであるクラスに参照カウントを持たせ、InterlockedIncrement./InterlockedDecrementで
マルチスレッド対応にしようとしたのだが…

void ref() {
 InterlockedIncrement(&m_ref); 
}
void release() {
 if (InterlockedDecrement(&m_ref) == 0) {
  delete this;
 }
}

ところが、delete thisの直後にref()が呼ばれると、m_ref自体が解放された領域にあるため、
とんでもない値になってしまう。参照カウントをメンバー変数にするのが間違い?
どうしたらいんだろう?マルチスレッドのエキスパート様の降臨おながいします
0737デフォルトの名無しさんNGNG
> delete thisの直後にref()が呼ばれる

delete thisされたってことは、そのオブジェクトはもう参照されていない
と判断されたんだがら、その後にrefが呼ばれること自体がおかしい。
0738デフォルトの名無しさんNGNG
参照カウントを0から始めたに100スレッド
0739736NGNG
ある時点で、m_ref>0だったとします。
2つのスレッドが、それぞれ同時にref()とrelease()を呼び出すと…
0740デフォルトの名無しさんNGNG
ref() と release() が互いに排他してなきゃ動くわけないじゃん。
0741736NGNG
void ref() {
EnterCriticalSection(&m_cs);
 InterlockedIncrement(&m_ref); 
LeaveCriticalSection(&m_cs);
}
void release() {
EnterCriticalSection(&m_cs);
 if (InterlockedDecrement(&m_ref) == 0) {
  delete this;
 }
LeaveCriticalSection(&m_cs);
}
としても、ref()でInterlockedIncrement()にたどり着いたときには…
0742デフォルトの名無しさんNGNG
あるオブジェクトに触れるスレッドが一つふえたら
そのオブジェクトの参照カウントをageておく必要があることに
気づいてないに1000はらたいら
0743デフォルトの名無しさんNGNG
>739
それもなんだかおかしな動作だな。
refを発行する、というのは、どっかからobjectを貰ってきてるわけだろ。
で、releaseを発行するということは、所有権の一端を持っているわけだよな。
それで、deleteが実行されるというのは、
「refcount == 0かもしれないobjectが渡ってきた」
「release発行しすぎ」
ってなわけだろ。refするタイミングとか、考え直した方がいいんでないか?
0744736NGNG
refが参照カウントを増やす(objectを貰って来る)ためのものなのだが…
0745デフォルトの名無しさんNGNG
736はひょっとしてCOMを知らない?
0746736NGNG
いやCOMじゃなくて。
あるオブジェクトのインスタンスが作られるとm_ref=1となっていて、
そのオブジェクトを例えば別のスレッドが使うためにコピーを作るとm_ref=2
となる。
まさにその瞬間に、インスタンスの元のホルダーがオブジェクトを破棄しようとすると、
m_refのインクリメントとデクリメントが同時に起きる。
Interlocked...は同時じゃないが、ref()とrelease()が同時に呼ばれrelease()を
実行しているスレッドの方が早くCriticalSectionを獲得して解放したのち、
InterlockedIncrementが呼ばれると、解放されてしまうので値が不定になってしまう。
0747デフォルトの名無しさんNGNG
「別のスレッドが使うためにコピーを作る」ときに
「インスタンスの元のホルダーがオブジェクトを破棄」しちゃおかしいだろ。
「別スレッドに渡す」ときにコピーができるもんだろ、ふつー。
0748デフォルトは上限無しさんNGNG
>>746
Deleteされてしまうことがあるobject自身に、
objectの管理を「全て」任せようということ自体が無理。
Handler patternで行くか、refererにべたにcodeを書いてしまう。
0749デフォルトの名無しさんNGNG
つーかな。それはrefcountの問題と違うねん。たとえば、
method1() {delete str; str=0; }
method2() {func( *str );}

このメソッド2つが同時実行されるようなのとおなじ問題なわけよ。
あえて解決策を示すなら、

method1() {lock(); delete str; str = 0; unlcok(); }
method2() {lock() if( str ) func(str) unlock(); }

とかしないといけない。
0750デフォルトの名無しさんNGNG
ひょっとしてrefcountをさらにポインタや参照で管理しようとしてないか?
そんなのrefcountの意味が全くないぞ。根本的にrefcountについて誤解してるだろ。
0751デフォルトの名無しさんNGNG
>>750
俺もそんな気がして来た。グローバルなオブジェクトや静的なオブジェクトを
参照カウントでやろうとしてるような気もするし。
0752736NGNG
>746
やっぱり、そういう事になりますか。

>749
それは、ちっとも解決にならない。
method2がこの場合ref()なわけで、ref()から戻ったら、そのオブジェクト使おうと
するんだから。

>750
参照カウントは、扱われるインスタンス内に有りますが、
そのインスタンスを指すスマートポインターのようなクラスで持たなきゃならないって
事ですか?
そうでなくて、インスタンスと別にアロケートして参照カウント作ってもだめって事だけ?

>グローバルなオブジェクトや静的なオブジェクトを参照カウントでやろうとしてるような気もするし。
流石に、そんなこたぁない。
0753デフォルトの名無しさんNGNG
分からんヤツやな、、、
refする前にreleaseが発行されてrefcount==0になる
可能性があるなら、refする前に、oobjectが生きてて、
refできるか確かめないかんやろ。その結果、objectが
死んでるなら、refしてobject渡すのは諦めなアカン。
 で、そこでobjectが死んでるのが間違いなら、releaseか
refの発行の仕方がオカシイんや。
0754デフォルトの名無しさんNGNG
>>752
> >746
> やっぱり、そういう事になりますか。
ジサクジエーン?
0755デフォルトの名無しさんNGNG
>>752
> 参照カウントは、扱われるインスタンス内に有りますが、
> そのインスタンスを指すスマートポインターのようなクラスで持たなきゃならないって
> 事ですか?
> そうでなくて、インスタンスと別にアロケートして参照カウント作ってもだめって事だけ?

場所は関係ない。ただし、インスタンスとカウンタの対応を管理することを考
えれば、インスタンス内に置くか「スマートポインターのようなクラス」って
のが確実で手軽だし常套手段。

参照が増減するたびに必ずカウンタも同期しなきゃ行けないってこと、わかっ
てる? これは本来アトミックな処理なので、別スレッドに渡すってのも参照を
増やすことになるんだけど、それとカウンタの更新を別スレッドに分けちゃい
けない。

単一スレッド内でコピーする場合は複製によるカウント処理が終るより前にオ
リジナルが解放することはないので保護されるけれど、別スレッドにしてしまっ
たらその順序が保証されなくなってしまう。
0756デフォルトの名無しさんNGNG
>>754
多分 748 宛てだと思われ。
レス番号と間違えてコメント先頭のポインタを書いてしまう間違いは漏れも時々
やってしまう。
0757736NGNG
なんか昨日から粘着が居るが

>753
>分からんヤツやな、、、
あんたほどでは(W

>refする前に、oobjectが生きてて、refできるか確かめないかんやろ。
確かめた時生きてても、じゃあ参照しようとしたら死んでる罠
確かめるときに参照かうんと増やす何て言うなよ(W


>755
>参照が増減するたびに必ずカウンタも同期しなきゃ行けないってこと、わかってる?
それは当然ですね。

>これは本来アトミックな処理なので、別スレッドに渡すってのも
別のスレッドに渡すのではなく、
あるスレッドAが参照カウントを持つOのインスタンスをつくって、
別のスレッドBがそのオブジェクトをもらおうとしたらば、
Aはもう要らないとOを破棄しようとしている最中だったわけです。
0758デフォルトの名無しさんNGNG
>>753
736 にはもう何も言わなくていいよ。
十分答え出てるのに見ようとしないんだから。
0759デフォルトの名無しさんNGNG
>>757
> 別のスレッドに渡すのではなく、
「渡す」つってんのはインスタンス自体じゃなくて参照のことをいってんだけど。
ポインタといったほうがいい?

> あるスレッドAが参照カウントを持つOのインスタンスをつくって、
> 別のスレッドBがそのオブジェクトをもらおうとしたらば、
この「もらおうとした」ってどういう状態を考えてるわけよ。
スレッドBはOのインスタンスo1に対する参照を受け取ってないわけ?
もし受け取ってるんならその時点でカウントしないとだめぽ。
0760736NGNG
>「渡す」つってんのはインスタンス自体じゃなくて参照のことをいってんだけど。
>ポインタといったほうがいい?
「渡す」というのは、あるスレッドAがインスタンスOの参照(カウントが増えた状態)を、別のスレッドB
がアクセスできるようにするという意味で使いました。
そうではなくて、スレッドAの預かり知らぬところで、スレッドBがインスタンスOを
コピー(の過程で参照化運とは増える)して使おうとするということです。

参照を受け取った時には、当然参照カウントは増えていますが、Oの参照カウントを
(クリティカルセクション獲得後)増やそうとしたら、スレッドAが解放してしまっていた
わけです。

>758
そういうなら、参照カウント使ったクラスうpしてみそ。逃げますか?(W
0761758NGNG
>>760
逃げる。
そしておまいは困る。ザマーミロ。
0762デフォルトの名無しさんNGNG
>確かめた時生きてても、じゃあ参照しようとしたら死んでる罠
もう一度だけ言うぞ。

「確かめる」と「ref()呼ぶを」、一つのLock内でやれ。
もちろん、releaseの呼び出しにも、おなじLockをかけろ。
それでも、refcountが0になるなら、releaseを呼びすぎているだけ。
0763736NGNG
そんなに広い範囲でロックかけないで済む方法ってないの?
0764デフォルトの名無しさんNGNG
話してる前提が違うんじゃない?
>method1() {lock(); delete str; str = 0; unlcok(); }
が
method1() {lock(); delete this; /*this = 0;XXX*/ unlcok(); }
だから、method2()のifがそもそも出来ないという話

0765デフォルトの名無しさんNGNG
lock() str->release(); str = NULL; unlock();
0766デフォルトの名無しさんNGNG
>763
762のlockはそんなに広くないはずだが。
0767デフォルトの名無しさんNGNG
>>736
参照カウントが 1 のオブジェクトを複数のスレッドから参照してる時点で、
ref を呼び忘れてる。
参照回数0 のオブジェクトに到達することが正しい振る舞いだとしたら、
それは通常の参照じゃなく、弱い参照だ。
0768デフォルトの名無しさんNGNG
>>736
そもそも、スレッドが生きているかどうか分からないオブジェクトへの
ポインタを受け取ること自体に問題があるような。まさか、
スレッドA:
p = new クラス();
Bに渡す(p);
p->release();
スレッドB:
p = Aから受け取る();
p->ref();
というコードを書いていないだろうな?もしそうなら構造上の問題。
Bから見える場所にpを格納したなら、その分の参照カウントを数えなくては
ならない。それって本質的にはシングルスレッドでも同じことだけど。
0769デフォルトの名無しさんNGNG
> あるスレッドAが参照カウントを持つOのインスタンスをつくって、

COM知ってさえいれば・・・
0770デフォルトの名無しさんNGNG
つか、スレッドBに渡されたことをどうやってAは知るんだ?
0771デフォルトの名無しさんNGNG
>>770
普通Aがそれを知る必要は無いと思うが?
単にBが自分でディクリメントすればいいだけで。
0772デフォルトの名無しさんNGNG
なんか皆さん盛り上がってますが…
>>745 >>769に同意。
リファレンスカウントのサンプルを見たければCOMを勉強すればよい。
それと。日本語で一所懸命書かれてもどうにも伝わりにくいようですな。
C言語で(擬似コードでも可)書いた方が意図が伝わると思いますが。
0773デフォルトの名無しさんNGNG
>>760
> 参照を受け取った時には、当然参照カウントは増えていますが、Oの参照カウントを
> (クリティカルセクション獲得後)増やそうとしたら、スレッドAが解放してしまっていた
> わけです。
そりゃカウントミスってる。AがOを持ってるところでBがOの参照を受け取って
カウントも増やしたんなら、カウントは2以上のはずだ。その状態でAが解放し
てしまうというのはバグ。
0774デフォルトは上限無しさんNGNG
Guru of the Week!
Reference Counting - Part III (Multithreading!)
http://www.gotw.ca/gotw/045.htm

Reference Counting - Part I
http://www.gotw.ca/gotw/043.htm
Reference Counting - Part II
http://www.gotw.ca/gotw/044.htm
0775デフォルトの名無しさんNGNG
おまえらスレッド立てすぎです。
0776デフォルトの名無しさんNGNG
>>775
http://pc3.2ch.net/test/read.cgi/tech/997345868/515-516
0777775NGNG
>>776、禿同
マルチスレッド掲示板はやればやるほど
スレッドをsageる方向で書込みしたくなるという面白い側面がありますね。
0778デフォルトの名無しさんNGNG
この間ようやくプ逝1も sage を覚えたようですが
0779デフォルトの名無しさんNGNG
VC++の_beginthreadでプログラムを書いてるのですが
親スレッドから子スレッド(以後スレ)を10本同時進行で走らせていて、すべての処理が終った時
子スレの呼び出しの前に変数でフラグを立てておき、そのスレの最後でフラグをONにし、
親スレでそれを確認してからスレを終わるように処理を書いているのですが、
親スレで子スレのフラグを確認している最中に子スレが書き込みすると処理が停止してしまいます。
(デバックしてみるとその付近で停止したりしなかったりする)

このスレのどこかで参照は同時に行ってもかまわないようなレスをみたのですが(記憶が確かなら…)
同時書きこみでない場合(書き込み中を参照)でもだめなのでしょうか?
クリティカルセッション等やらねばダメなのでしょうか?

それともこのような設計が悪いのでしょうか・・
0780779NGNG
>>776
>マルチスレッドプログラミングは、やればやるほど
>スレッドを減らす方向に設計したくなるという面白い側面がありますね

私もスレッドにはうんざりですw
まぁ設計が悪いんでしょうが・・・
0781デフォルトの名無しさんNGNG
>>779
DQNは使うな
つーか、一冊でも参考書読め
0782779NGNG
よーくデバックすると原因が見つかりました。。^^;
長文書いたにもかかわらずすいません・・

後余談ですが、デバック中に子スレッドでconnect、closesocketを何度かやっていると
ある一定回数(かなりの回数)を超えた時、connectが出来ない状態になりました。
何らかのエラーが発生した場合そのエラーを表示するようにプログラムを
書いているのですが全く表示されません。
Socketの処理は居たってシンプルなもので、スレッドとは別で行っているのでバグは無いと思うのですが・・。
このような事は通常起こり得るのでしょうか?
0783736NGNG
どうして、参照カウントが増えた後の話にしたがるのか…
0784デフォルトの名無しさんNGNG
>765

>766
参照カウントを持つオブジェクトのリストがあって、追加・削除、参照(+そのための検索)
を行おうとすると、それぞれでリスト全部ロックしないと…
まあ、注目してるノードとその前後だけロックというのも有りうるけど面倒すぎる。
リスト自体が要素すうもってるし。

>767
参照できるようにする過程での話です。
参照カウントインクリメント不足は、お腹一杯。

>768
スレッドBのAから受け取る()は、どういう処理?
そのなかで、当然Mutexとかで排他制御して参照カウント増やすんでしょ?
その瞬間の話。

>769
実はCOMです。
COMのモジュール内で持ってる情報の管理でつまずいてる。
769はSTAだけつかってなさい。
0785デフォルトの名無しさんNGNG
>772
ちみもSTAだけつかってなさい。

> C言語で(擬似コードでも可)書いた方が意図が伝わると思いますが。
そいでは、>774の
Reference Counting - Part III (Multithreading!) http://www.gotw.ca/gotw/045.htm から

String::~String() {
  bool bDelete = false;
  data_->cs.Lock(); //---------------------------
  if( data_->refs == Unshareable || --data_->refs < 1 )
    bDelete = true;
  data_->cs.Unlock(); //-------------------------
  if( bDelete)
    delete data_;
}

String::String( const String& other ) {
  bool bSharedIt = false;
  other.data_->cs.Lock(); //---------------------
  if( other.data_->refs != Unshareable ) {
    bSharedIt = true;
    data_ = other.data_;
    ++data_->refs;
  }
  other.data_->cs.Unlock(); //-------------------
  if( !bSharedIt )
    data_ = new StringBuf( *other.data_ );
}
(つづく)
0786736=784=785NGNG
Sharable/Unsharableは置いといて、

Thread A             Thread B

delete O1呼び出し         O2 = O1 (otherがO1)

data_->cs.Lock();         other.data_->cs.Lock()
if (--data_->refs < 1)
  bDelete = true;
data_->cs.Unlock();
if (bDelete)             data = other.data;
  delte data;            ++data_->refs;
                     other.data_cs.Unlock()


例のコードではStringなので、ロック後解放済みだったら空の文字列
を返せばよいのですが、実際には目的のデータであることを確認後
Thread BはO1のコピーのO2を手に入れようとしているので困ってます。

目的のデータがあるかどうかの検索の最初から、コピーを手に入れるまで
と解放処理を呼び出すのもまるっきり排他制御すればできるのは明らかで
すが、極端にパフォーマンスが落ちてしまいます。
0787736NGNG
>>773
> そりゃカウントミスってる。AがOを持ってるところでBがOの参照を受け取って
> カウントも増やしたんなら、カウントは2以上のはずだ。その状態でAが解放し
> てしまうというのはバグ。

はぁー。
受け取る処理ってどうやるのさ?

>774
これからよく読んでみます。
ありがと。
0788デフォルトの名無しさんNGNG
>>786
> Thread A             Thread B

ここでBは既にO1への参照を持ってんだろ?

> delete O1呼び出し         O2 = O1 (otherがO1)
0789736NGNG
O1は、スレッド間で共有しているリスト中の要素としてある。

O2=O1は、そのリストから目的の物を検索して取り出す処理の中。
0790デフォルトの名無しさんNGNG
マルチスレッドのプログラムで
素朴リファレンスカウントGCをやるなら、
すさまじい細粒度ロックで効率が低下するのは
覚悟しなきゃ。

(普通のGCを使ったほうがずっと速いよ。)
0791デフォルトの名無しさんNGNG
>>789
やっぱりおかしいな。リストがStringを持ってるわけだろ?
それで、Thread Aがリストから要素を削除したら~String()が呼ばれる
わけだが、その前にThread Bがリストの要素への参照を持ってるなら
参照カウントは2になってなきゃおかしい。

こういうことするなら、当然文字列を指す可能性のあるオブジェクト
全部にリファレンスカウント付けて管理してるんだろ?
0792デフォルトの名無しさんNGNG
そうか。Stringというより
GarbageCollectedというスマートポインタを作って、
ヒープのオブジェクト全部GarbageCollectedを継承するように
するんだな。

そして、リストの検索とかやるときは、1つ1つの要素を
ロック・ref++・アンロック、ロック・ref--・アンロックすると。
0793デフォルトの名無しさんNGNG
>>789
もしかして
「排他制御せずにリストにアクセスしたら、変になるんですけど。」
って言ってる?

スレッドAがリスト中のO1を削除するには、

list.remove(index)

あるいは

list.remove(O1)

スレッドBがO1のコピーを作るには、

O2 = list.get(index)

だよな?
で、この get と remove はロックを使わずやりたいと。
そういうことか?
0794736NGNG
>791
>その前にThread Bがリストの要素への参照を持ってるなら
>参照カウントは2になってなきゃおかしい。

リストの要素への参照とは?
O1がそれだと言っているのか(W

>793
>で、この get と remove はロックを使わずやりたいと。
>そういうことか?
そう。
でも、
>「排他制御せずにリストにアクセスしたら、変になるんですけど。」
という事じゃない。
removeで要素中のO1は削除されるけど、Thread BがO2を手に入れていれば
O1-+
  +-->ref:2,data:"ABC"
O2-+

から
O2---->ref:1,data:"ABC"

となり、他のスレッドは、もはやこのデータにアクセスできないが、
Thread BはO2から使える。O2が不要になって破棄したら、データ本体も解放される。
0795デフォルトの名無しさんNGNG
リスト操作たるgetとremoveにlockかけんかったら、
そいつらが平行したらあぼーんちゃうの。

まあ、「いや、実は〜」とかいって
新状況が出てくるのかも知らんけど(ワラ
0796デフォルトの名無しさんNGNG
>>755で
> 参照が増減するたびに必ずカウンタも同期しなきゃ行けないってこと、わかっ
> てる? これは本来アトミックな処理なので、
と書いてある意味分かんないのか?

>>789
> O2=O1は、そのリストから目的の物を検索して取り出す処理の中。
てんなら、その処理中での参照の追加とカウントの増加は原理的に(そのオブ
ジェクトに対する)排他処理は必須ってことなんだが。
0797デフォルトの名無しさんNGNG
「getしてO1の参照先のref countが増える」までが
アトミックに行われないとまずいね。

getが返すべきO1を得た後で、かつO1のrefが増える前にrefがゼロに
なっちゃう。

やはり、
・リスト全体にmultiple-readers-single-writer lockをかける。
・リストの要素1つ1つに排他的ロックをかける。
のどちらかが必須。
0798デフォルトの名無しさんNGNG
>>796 禿同
getの中で「注目してるオブジェクト」を示すポインタが
あれば、そいつの参照も数えるべき。
あるオブジェクトを指す変数がある瞬間に3つあるなら
(たとえば「リストから」「Thread Aの局所変数から」
「Thread Bの局所変数から」)、参照カウントはその瞬間
3でないと間違い。
0799デフォルトの名無しさんNGNG
>>784 (=783?)
>実はCOMです。
>COMのモジュール内で持ってる情報の管理でつまずいてる。

COM扱っててこの有様は信じられない。
0800736NGNG
>796
未だに問題のポイントがわかってない言語障害者が居ますね。

>797
やっぱり、そうなっちゃいますかね。

>799
COMは関係なかろう、STAならInterlock何かする必要無いし、
そうでなければ、COMでも同じ。
0801デフォルトの名無しさんNGNG
ふつーのGC使えば、誤爆開放しちゃうdangling pointer問題からは
逃れられる。

でも、2人が同時にリストにあぷデートに行ったらどうやっても
ロック必須だけどナー
0802デフォルトの名無しさんNGNG
なんか禿しく釣られまくったような気がしてきた…。
0803デフォルトの名無しさんNGNG
ところでReadWriteLockでスタベーションフリーでLockのUpgrade/Downgradeも
できるようなの誰か知らんか?
0804デフォルトの名無しさんNGNG
>>736
考え方おかしいよ。
管理する側とされる側がごっちゃになってる。
そもそもdelete後に破棄されたインスタンスの排他制御
オブジェクトを参照しようとしてる事をおかしいと思わないの?
0805デフォルトの名無しさんNGNG
便乗で質問です。
スレッド間で、GC(インクリメンタルなマーク&スイープ)で管理された
共有領域のメモリオブジェクトを使いたいんですが、メモリオブジェクト
にはアクセスする度に排他制御しないといけませんよね?
参照するだけなら不要なのはわかるんですが、ポインタを繋ぎ変えたりも
したいので、結局双方でロックしてないと駄目ですよね。

素直に組むと、メモリオブジェクトの粒度が小さいので排他制御にかなり
の時間が割かれてしまいそうなんですが、良い方法はないでしょうか。
素人考えで思いついたのは、スレッド毎にローカルなメモリオブジェクト
領域を使って、処理が完了したら、その結果を共有メモリオブジェクト
領域に移すという方法で、排他制御は共有メモリにアクセスするとき
のみ掛けるというものですが、この方法だとスレッド毎にGCが必要な気が
します。
もっと一般的な方法があったらお願いします。
0806デフォルトの名無しさんNGNG
>>805
読むだけなら排他制御は不要だよ。
整数や文字を書き込むときも(共有変数以外は)不要。
ポインタを書いたときはライトバリアでGCに通知。
これも別に排他制御はいらない。たとえばスレッドごとにキューを作って、
ページ単位とかでまとめて渡せばよい。
0807805NGNG
>>806
ありがとうございます。
ライトバリアでマークする経路を保証するって事ですよね。
共有領域とローカルの区別をする手段が思いつかない(複数
ブロックにまたがってる)んで、改竄個所を全部保護する様に
書き直さないとまずいのかな。
ちょっと考えてみます。
0808デフォルトの名無しさんNGNG
ヒープに置くポインタはすべて
template Pointer<class T> ...
みたいなオブジェクトにして、コピーコンストラクタ
でライトバリアをかければよいんじゃないだろうか。
0809736NGNG
>804
頭おかしいよ。
こんなのどこにでもある。見たこと無いのか?
0810デフォルトの名無しさんNGNG
>>736
何人もの人間が否定してるんだから、おかしいのはお前だろ(笑
0811736NGNG
じゃあ、COMもおかしいのか?
0812デフォルトの名無しさんNGNG
>>809
「どこにでもある」 が 「おかしくない」 の理由には全然ならない事に気付け。
つーか、そんなのそうそう転がってないはずなんだが、あんたよっぽどクソな
サンプルに見舞われてるんだな。

>>811
おかしいのは COM を把握してないのにわかったつもりになってるあんたの頭。

つーか、教えを乞う立場だったら、もっと謙虚になれ。
主観を捨てろ。
答えへのポインタはもう不必要なほど出ているのに、あんたはそれを全部捨てている。
0813736NGNG
>812
>つーか、教えを乞う立場だったら、もっと謙虚になれ。

共有しているオブジェクトの集合に丸ごとロックかけずに、
各オブジェクトの参照カウントだけで済むかがポイントなのに、

参照カウントのインクリメント不足だとか、
COMを知ってればとか、
おんなじ事 おんなじ事 おんなじ事 おんなじ事 ばかーーーり。
しつこつ しつこく しつこーーーーく 同じこと繰り返す粘着が多くてウンザリ。

getはアトミックだとか…あのなあ、それ自体はアトミックでもremoveとgetを同時に呼ぶことは出来るんだよ。
参照を持っているならとか…あのなあ、その参照を受け取るのがgetだろ。共有オブジェクトのgetなんだよヴォケ。
じゃあ、参照を手に入れる処理を書いてみろというと、とたんに逃げ出す。
どうしてポイントがずれた香ばしい奴が多いのか。
0814736NGNG
>812
>「どこにでもある」 が 「おかしくない」 の理由には全然ならない事に気付け。
>つーか、そんなのそうそう転がってないはずなんだが、あんたよっぽどクソな
>サンプルに見舞われてるんだな。

これ見たこと無いか?
static ULONG WINAPI Increment(LPLONG p) {return InterlockedIncrement(p);}
static ULONG WINAPI Decrement(LPLONG p) {return InterlockedDecrement(p);}

ULONG InternalAddRef() {
 return _ThreadModel::Increment(&m_dwRef);
}

ULONG InternalRelease() {
 return _ThreadModel::Decrement(&m_dwRef);
}

STDMETHOD_(ULONG, AddRef)() {return InternalAddRef();}
STDMETHOD_(ULONG, Release)() {
 ULONG l = InternalRelease();
 if (l == 0)
  delete this;
 return l;
}
まあ、君のコードの中では、
static ULONG WINAPI Increment(LPLONG p) {return ++(*p);}
static ULONG WINAPI Decrement(LPLONG p) {return --(*p);}
しか使われないと思うが(W
0815デフォルトの名無しさんNGNG
736の、これまでの発言で推測できること。
1.listでCOM objectを束ねているらしい
2.list内のあるCOM objectに対して、
 releaseとrefが(release->refの順で)発生して死ぬようだ
3.list全体に対するlockはかけたくないらしい
 (listが持つCOM objectに対する個々のロックは可能みたい?)

736の発言だけで、この問題がわかるかってーの。
それを736の時点で言えば、まだ混乱は少なかっただろうに。
変に情報を出し惜しむから、おなじ事をしつこく何度も
言われる羽目になる。おまけに自分のことを棚に上げて
しつこいとか、ポイントがずれてるとか、香ばしいとか言うし。
0816736NGNG
それで?
0817デフォルトの名無しさんNGNG
で、815であげた推測は正しいのかい?
というか、コードだせ、コード。問題の起こる、
必要最小限の、736の書いたコードを。
0818736NGNG
738 :デフォルトの名無しさん :02/11/12 20:25
参照カウントを0から始めたに100スレッド

740 :デフォルトの名無しさん :02/11/12 21:24
ref() と release() が互いに排他してなきゃ動くわけないじゃん。

742 :デフォルトの名無しさん :02/11/12 21:57
あるオブジェクトに触れるスレッドが一つふえたら
そのオブジェクトの参照カウントをageておく必要があることに
気づいてないに1000はらたいら

743 :デフォルトの名無しさん :02/11/12 21:58
>739
それもなんだかおかしな動作だな。
refを発行する、というのは、どっかからobjectを貰ってきてるわけだろ。
で、releaseを発行するということは、所有権の一端を持っているわけだよな。
それで、deleteが実行されるというのは、
「refcount == 0かもしれないobjectが渡ってきた」
「release発行しすぎ」
ってなわけだろ。refするタイミングとか、考え直した方がいいんでないか?

745 :デフォルトの名無しさん :02/11/12 22:52
736はひょっとしてCOMを知らない?

747 :デフォルトの名無しさん :02/11/13 10:35
「別のスレッドが使うためにコピーを作る」ときに
「インスタンスの元のホルダーがオブジェクトを破棄」しちゃおかしいだろ。
「別スレッドに渡す」ときにコピーができるもんだろ、ふつー。
0819736NGNG
750 :デフォルトの名無しさん :02/11/13 11:21
ひょっとしてrefcountをさらにポインタや参照で管理しようとしてないか?
そんなのrefcountの意味が全くないぞ。根本的にrefcountについて誤解してるだろ。

751 :デフォルトの名無しさん :02/11/13 11:28
>>750
俺もそんな気がして来た。グローバルなオブジェクトや静的なオブジェクトを
参照カウントでやろうとしてるような気もするし。

753 :デフォルトの名無しさん :02/11/13 15:40
分からんヤツやな、、、
refする前にreleaseが発行されてrefcount==0になる
可能性があるなら、refする前に、oobjectが生きてて、
refできるか確かめないかんやろ。その結果、objectが
死んでるなら、refしてobject渡すのは諦めなアカン。
 で、そこでobjectが死んでるのが間違いなら、releaseか
refの発行の仕方がオカシイんや。
0820736NGNG
767 :デフォルトの名無しさん :02/11/13 21:20
>>736
参照カウントが 1 のオブジェクトを複数のスレッドから参照してる時点で、
ref を呼び忘れてる。
参照回数0 のオブジェクトに到達することが正しい振る舞いだとしたら、
それは通常の参照じゃなく、弱い参照だ。

769 :デフォルトの名無しさん :02/11/13 23:23
> あるスレッドAが参照カウントを持つOのインスタンスをつくって、

COM知ってさえいれば・・・

772 :デフォルトの名無しさん :02/11/13 23:58
なんか皆さん盛り上がってますが…
>>745 >>769に同意。
リファレンスカウントのサンプルを見たければCOMを勉強すればよい。
それと。日本語で一所懸命書かれてもどうにも伝わりにくいようですな。
C言語で(擬似コードでも可)書いた方が意図が伝わると思いますが。

773 :デフォルトの名無しさん :02/11/14 00:03
>>760
> 参照を受け取った時には、当然参照カウントは増えていますが、Oの参照カウントを
> (クリティカルセクション獲得後)増やそうとしたら、スレッドAが解放してしまっていた
> わけです。
そりゃカウントミスってる。AがOを持ってるところでBがOの参照を受け取って
カウントも増やしたんなら、カウントは2以上のはずだ。その状態でAが解放し
てしまうというのはバグ。
0821デフォルトの名無しさんNGNG
736 荒らしケテーイ
(いや、元々そうだったという説もあるが・・・)

という訳で出て逝ってくれ。
0822736NGNG
君らのしつこさを確認させてやっただけだよ
0823デフォルトの名無しさんNGNG
( ´,_ゝ`)プッ
0824736NGNG
結局誰も判らんのか。それならそう言えよ無能者ども。
0825デフォルトの名無しさんNGNG
>>822
あのさあ、
しつこいのは お ま え (w
消えろ
0826デフォルトの名無しさんNGNG
>>813
> 共有しているオブジェクトの集合に丸ごとロックかけずに、
> 各オブジェクトの参照カウントだけで済むかがポイントなのに、
参照カウントのインクリメントにはロックは*原理的に*必要不可欠。
してないのはシングルスレッドを前提にしてる場合だけ。
わかった?

> 参照カウントのインクリメント不足だとか、
> COMを知ってればとか、
> おんなじ事 おんなじ事 おんなじ事 おんなじ事 ばかーーーり。
> しつこつ しつこく しつこーーーーく 同じこと繰り返す粘着が多くてウンザリ。
なんでおんなじ事をこんなにしつこく説明してやらなきゃならんのか…。

> getはアトミックだとか…あのなあ、それ自体はアトミックでもremoveとgetを同時に呼ぶことは出来るんだよ。
> 参照を持っているならとか…あのなあ、その参照を受け取るのがgetだろ。共有オブジェクトのgetなんだよヴォケ。
そのアトミックなgetにカウントのインクリメントを含めてないからバグって
んだろが。
0827736NGNG
まだ言ってるのか。
>参照カウントのインクリメントにはロックは*原理的に*必要不可欠。
>してないのはシングルスレッドを前提にしてる場合だけ。
>わかった?

void ref() {
EnterCriticalSection(&m_mutex);
 InterlockedIncrement(&m_ref); 
LeaveCriticalSection(&m_mutex);
}
void release() {
EnterCriticalSection(&m_mutex);
 if (InterlockedDecrement(&m_ref) == 0) {
  delete this;
 }
LeaveCriticalSection(&m_mutex);
}
としたら満足か?(W
0828736NGNG
>826
おまえ、InterlockXXってなんのためにあるのか知らんだろ。
知らない奴に限って、無駄なレスを返しやがる。
0829デフォルトの名無しさんNGNG
としたら満足か、って・・・
一体何の為にここに質問に来たんだ?
0830デフォルトの名無しさんNGNG
736の無能っぷりをさらけ出すスレはここですか?

>>837
>EnterCriticalSection(&m_mutex);
> InterlockedIncrement(&m_ref); 
>LeaveCriticalSection(&m_mutex);

クリティカルセクション張ってるんだから、
インターロック不要なんだけど。


>EnterCriticalSection(&m_mutex);
> if (InterlockedDecrement(&m_ref) == 0) {
>  delete this;
> }
>LeaveCriticalSection(&m_mutex);

自分で書いてておかしいと思わないのかなあ・・
0831736NGNG
>>836

あのなあ、

>>参照カウントのインクリメントにはロックは*原理的に*必要不可欠。
>>してないのはシングルスレッドを前提にしてる場合だけ。
>>わかった?

というのは読めないのか。お前は、自然言語にたいする理解力は0だな。
ロックかけなきゃだめだと言ってるやつがいるから、ロックしたまで。
なーんの解決にもならんし、もともと、Interlockしてるから不要なんだがな。
0832736NGNG
>830
だわ
0833736NGNG
で?826も逃げたのか。全く都合が悪くなると逃げて…自分の発言に席にもてよ。
どうせ、別人のフリしてまた別の事言い出すんだろうが
0834736NGNG
ん?deleteまではロックしなきゃダメかな。
まあ、どのみちref()でロック獲得したときに、解放済みというのは避けられんが。
0835デフォルトの名無しさんNGNG
>>827
> としたら満足か?(W
で、バグは直ったのか? 漏れが満足したからってバグが消えるわけじゃないぞ。

void Item::ref() {
 InterlockedIncrement(&m_ref); 
}
Item* List::get() {
EnterCriticalSection(&m_mutex);
Item* p = ...;
p->ref();
LeaveCriticalSection(&m_mutex);
return p;
}
この例で行くとListのget()とremove()で競合が起きるんだろ?
ならListのほうで排他処理をするのが自明の理。
0836736NGNG
やっぱり、List::get()でリストの検索処理が丸ごとロックするしかないのか。
0837デフォルトの名無しさんNGNG
(´-`).。oO(100レスかけてようやく染み込んだのか)
0838736NGNG
それ以外に無いのか聞いてんだが。
ここのいる連中じゃ無理のようだ(W
0839736NGNG
>812
>「どこにでもある」 が 「おかしくない」 の理由には全然ならない事に気付け。
>つーか、そんなのそうそう転がってないはずなんだが、あんたよっぽどクソな
>サンプルに見舞われてるんだな。

812も逃げたようだな。逃げ足の速い連中だ。
0840デフォルトの名無しさんNGNG
>>838
> それ以外に無いのか聞いてんだが。
散々いわれてんのに。>>762とか>>785とか。
大体間接的に渡すって話自体>>789くらいでいきなりだし。

>>839
> 812も逃げたようだな。逃げ足の速い連中だ。
いつまでも君の相手してらんないしね。
漏れもそろそろ出かけなきゃならないんでバイバイ。
0841デフォルトの名無しさんNGNG
winでのTerminateThreadと同じような
関数はunixにありますか?
0842デフォルトの名無しさんNGNG
pthreadならpthread_cancel()かな。TerminateThreadと違って必ずしも即座に
終了するわけじゃないけど。
0843デフォルトの名無しさんNGNG
教えて下さい。
pthread_cancel()を実行すると
実行されたスレッドの終了はいつになるのですか?
0844デフォルトの名無しさんNGNG
実行してみればわかる
0845736NGNG
>840
またバカが湧いてきた。

>散々いわれてんのに。>>762とか>>785とか。
>762は、各オブジェクト毎にロック掛けるって意味ならロックが多量に必要だし、リストにはロック掛けないのか?
リストにロックかけるんだったら、各オブジェクト毎に掛ける必要なし。
君のような厨には理解で菌だろうがな。

>大体間接的に渡すって話自体>>789くらいでいきなりだし。
間接的?ハァ?頭大丈夫?

785は俺だ。
たくっ。ろくに読まないでレスするアホウは書くなっつの。

>いつまでも君の相手してらんないしね。
>漏れもそろそろ出かけなきゃならないんでバイバイ。

いや、君みたいなアホウに相手してくれとは言ってないから(W
お呼びでないの(Wつか出てくんなっての

大体、レスして何か言われたら自分が誰かわかるように名前に番号入れるもんだろ。
言いっぱなしで自己満足してる厨が多すぎ。
0846736NGNG
740 :デフォルトの名無しさん :02/11/12 21:24
ref() と release() が互いに排他してなきゃ動くわけないじゃん。

826 :デフォルトの名無しさん :02/11/15 13:03
>>813
> 共有しているオブジェクトの集合に丸ごとロックかけずに、
> 各オブジェクトの参照カウントだけで済むかがポイントなのに、
参照カウントのインクリメントにはロックは*原理的に*必要不可欠。
してないのはシングルスレッドを前提にしてる場合だけ。
わかった?

こういう連中は、
void ref() {
 EnterCriticalSection(&m_cs);
 ++m_ref;
 LeaveCriticalSection(&m_cs);
}
void release() {
 EnterCriticalSection(&m_cs);
 if (--m_ref) == 0) {
  delete this;
 }
 LeaveCriticalSection(&m_cs);
}

って書いてるのかな。馬鹿だなー。
こんな事言ってる奴が多いのは オ ド ロ キ。
もはや都市伝説だな。
0847736NGNG
おっ!
830が、慌ててネットで調べ始めた。まあ、自分の馬鹿さ加減を思い知れ。
0848736NGNG
おっ!
他にもInterlockだけじゃダメだと思ってる奴も多いな。
まあ、release()のLeaveCriticalSectionがdelete以降なのは論外だが、
void ref() {
 InterlockedIncrement(&m_ref); 
}
void release() {
 if (InterlockedDecrement(&m_ref) == 0) {
  delete this;
 }
}
じゃだめだと思ってるやつは何か言ってみろ。
どうせ逃げんだろうけどな。
0849デフォルトの名無しさんNGNG
void ref() {
 InterlockedIncrement(&m_ref); // A
}
void release() {
 if (InterlockedDecrement(&m_ref) == 0) {
  // B
  delete this;
 }
}
B のタイミングで A が呼ばれた場合。
0850デフォルトの名無しさんNGNG
void ref() {
 InterlockedIncrement(&m_ref); // A
}
void release() {
 if (InterlockedDecrement(&m_ref) == 0) {
  delete this;
  // C
 }
}
C のタイミングで A が呼ばれた場合。

しかし、危険性において 846 のコードは結局 848 と変わらないな。
0851736NGNG
おいおい、本当にのこのこ出てきたよ。恥ずかしい奴だ。
0852736NGNG
>しかし、危険性において 846 のコードは結局 848 と変わらないな。
説明してみろよ。わくわく。
Bのところに行くのは、どういう場合さ?
0853デフォルトの名無しさんNGNG
>849
馬鹿です。
0854デフォルトの名無しさんNGNG
晒しage
0855デフォルトの名無しさんNGNG
>>762は、各オブジェクト毎にロック掛けるって意味ならロックが多量に必要だし、リストにはロック掛けないのか?
>リストにロックかけるんだったら、各オブジェクト毎に掛ける必要なし。
>君のような厨には理解で菌だろうがな。

つか、762の時点では、そもそもリストが使われていることが
説明されていないわけで、762の時点で「リストにもロックかけろよ」
と言えるなら、そいつは神
0856736NGNG
あげてねーじゃん
0857736NGNG
>855
リストである必要なし。
グローバル変数など共有してれば同じ。
この場合動的じゃなきゃ意味無いが。
0858デフォルトの名無しさんNGNG
何がおなじなんだか、、、
0859デフォルトの名無しさんNGNG
思うんだが、ref() を bool 型にして、呼び出し側で false を受け取ったら取得を諦める
ようにはできないのか?

bool m_sw1st; // コンストラクタで true に
bool ref() {
 bool ret = true;
 EnterCriticalSection(&m_cs);
 if(!m_ref)
 {
  if(m_sw1st)
   m_sw1st = false;
  else
   ret = false;
 }
 if(ret)
  ++m_ref;
 LeaveCriticalSection(&m_cs);
 return ret;
}
void release() {
 EnterCriticalSection(&m_cs);
 if (--m_ref) == 0) {
  delete this;
 }
 LeaveCriticalSection(&m_cs);
}

参照カウンタが 1 始まりなら m_sw1st は要らないけど。
0860859NGNG
ごめん、無かった事にして。
0861736NGNG
m_csってメンバー変数じゃないのか?
ref()のEnterCriticalSectionでブロックされてるときに
deleteされるのは大丈夫か?
首尾よく、ref()でCriticalSectionに入れてもm_refは不定だぞ。
0862736NGNG
で?849はやっぱり逃げたのか。
0863デフォルトの名無しさんNGNG
ここはすごいITパワーですね。
0864デフォルトの名無しさんNGNG
>838
だから、無いんだって。intのlistを考えてみろよ。
lockしないで、検索処理と、削除処理を併走できるかっつーの。
0865デフォルトの名無しさんNGNG
>864
リストなら丸ごとロックしなくてもできる。
0866736NGNG
>865
と言うと?

>864
おい!あるってぞ。言い返せよ。
0867デフォルトの名無しさんNGNG
別に言い返さないさ。
自身の不明を恥じて、詳細を拝聴するだけサ。
0868865NGNG
例えば、リストの3番目を削除しようとしている時には、検索処理が4番目以降の要素を
見ているなら同時に動いて問題ない。検索処理が、ちょうど3番目の要素を見ようとしているか
3番目から4番目に移ろうとしている時だけが同時に動けないだけ。
どのみち、要素数とか持っているリストだと同時に複数が書き込めないから、
たかだか一つの要素だけ排他制御できさえすればよい。
0869デフォルトの名無しさんNGNG
リストの項目が増えた時、リスト丸ごとのロックと、項目ごとのロックでは、
どっちが速いんだろうか。
0870 NGNG
>>869

そういうものの定石を適用すると、リストを示すポインタ値を適当にハッシュして16個くらいの
ロックに分散させる、てな感じにするんだと思うよ。一要素毎にロックを持つのはリソースを食
うし、あまりぶつからない程度に分散させれば十分だから。
0871デフォルトの名無しさんNGNG
>869>870
865が言っているのは、要素毎にロック作らなくても、
同時書き込み無しなら、一つロックがあればいいということだろ。
丸ごとロックしなくても、ロック一つでWriterはReaderと共存(Readerがいなく
なるまでまたなくても)できると。
0872デフォルトの名無しさんNGNG
>871
ロックが一つしかないなら、どうやって、
「今削除しようしている所を読んでるreaderがいない&
readerは削除しようとしている所へ進入しない」って
保証できるん?
0873736NGNG
それは、16スレッドが同時に書き込めるのか?
各スレッドが別の要素にアクセスするとして。

リストが要素数なんか持ってても大丈夫?
単純なリストならまだしも、空リストとか管理されてると結局その中の
一つのスレッドしか書き込みできない(というか排他制御が必要な)気がするが。
0874871NGNG
>872

writerは要素の変更じゃ無くて、要素の追加・削除を行うとして。
writerが削除しようとしている要素とかその次の要素の場所を書いとけば、
readerはそれみて何とかできる気がするが。
writerが削除しようとしている要素はすっ飛ばすとか。

追加は先頭でも最後でも問題起きないと思うが。
どっちにしろ、readerはwriterがする事を知っているのが前提で、
汎用ではなく。
0875872NGNG
ひょっとして、readerの数だけの、index/pointerを指している
配列と、その配列全体に対するロックがあれば解決できる話
なのか?
0876デフォルトの名無しさんNGNG
>874
それだと、「削除されるべき場所にいるreader」が、
「『リストの次の要素へ』を発行すること」をどう保証するか、
writerはどう検出するかって問題になるとおもうけど、、
0877デフォルトの名無しさんNGNG
50年前の並列処理問題を一から学び直す
ドキュソPGのスレはここですか?
0878デフォルトの名無しさんNGNG
>877
( ´д)ヒソ(´д`)ヒソ(д` )
0879デフォルトの名無しさんNGNG
lock free linked list
なんつって
0880768だけどさあNGNG
分からん奴だなあ。
リストの排他制御と、参照カウントの問題と、参照カウントの
排他が全部ごっちゃになっている時点でもう駄目。
まず、リストに複数スレッドからアクセスするなら、そのリストの
どこかに排他入れなきゃ駄目なの。次に、問題の共有オブジェクト
はリストからの参照の分があるから、リストに繋がっている間は
参照カウントは常に1以上でなきゃ駄目なの。「見付けた」時点では
「リストの方が」排他されているから、この間に参照カウントを増やそうね。
リストの排他が終わった時点で、参照カウントは2以上だから、この後
リストからremoveされても平気だよね。(ここが768の「Bから見える場所に
云々」ということの意味。)第三に、参照カウントも複数のスレッドから
参照されるから、これも排他しなくちゃならないよね。これはさすがに
分かってるみたいだけど。
0881736NGNG
お前ら無能すぎ。そんな程度で2ちゃん来てんじゃねーよ。
0882デフォルトの名無しさんNGNG
ところで、881は何人目の736ですか?
0883870NGNG
>>873

何への質問だかわからないけど、16っていうマジックナンバーがあるから
870 だと仮定して答える。

「リストから remove 」等の処理に排他制御をかけるとして、ごく素朴な
リスト全体にたいしてロックが1つ、という状態では競合が起きた場合に
素直にパフォーマンスが悪化する。並列性が高くなればなるほど競合の可
能性は増し、結局並列動作できない場面が出てくる。

その辺をチューニングする場合の定石として、適当にロックの数を増やす
ってのがある。コンテキストスイッチングに比べて排他の対象となる操作
の方が十分重い場合には、寝てるスレッドのことはほぼ無視しても良いの
で、CPU の数+αに分散させれば十分。そうじゃないときは多めにする。
0884870NGNG
>>849-850

そのタイミングで当該オブジェクトへのアクセスが発生するって思うのは、
参照カウントというものが何であるのかをわかっていないと思う。

そらまあそーいうこともあるだろうケド、その場合呼び出し側がバグって
るわけで。
0885736NGNG
>>881
とうとう偽者まで出てきたか。
0886736NGNG
適当ほざいてんじゃねーよ
帰って寝てろ
ワラワラ
0887736NGNG
881=882だろ。

>880
> 第三に、参照カウントも複数のスレッドから
> 参照されるから、これも排他しなくちゃならないよね。
どういう風に?(W
0888736NGNG
>886
おまえも881だろ。

>884=870

もうちょっと、説明してくれや。
0889736NGNG
騙ってまで何がやりたいんだか

>880
教科書のコピペはやめようね
0890元祖736NGNG
736増殖中
0891736本人NGNG
やめろっての。馬鹿がうつる。
0892元祖736NGNG
>>880
だぁから、そんなのあたりまえだろ。おまえはしらなかったかもしらんが。
そこを参照カウントに技使って、リストのロックに工夫できないかという話だったのが、
しつこく しつこく しつこーーく 参照カウントのインクリメント不足だと
おんなじ事繰り返す厨の集団攻撃が始まっちまったんだよ。
しまいには、ref()とrelease()に排他制御が無いからだと言い出すドアホまで
何人も出てきやがるし。お前達は、お呼びじゃないんだよ。
0893870NGNG
reference counting ってのは、そのオブジェクトへの「参照」の数を
数えておいて、ゼロになったら誰も見てないから開放〜てなアイデア。

だからカウントがゼロになった後は誰から参照されておらず、どんな
メソッド…メンバ関数も呼ばれないわけです。呼んだとしたらそれは
呼び出し側のバグ。
0894デフォルトの名無しさんNGNG
>そこを参照カウントに技使って、リストのロックに工夫できないかという話だったのが、
736ではそんな話には読めない。最初からそう書けよ。

>おんなじ事繰り返す厨の集団攻撃が始まっちまったんだよ。
自業自得
0895デフォルトの名無しさんNGNG
>そこを参照カウントに技使って、リストのロックに工夫できないかという話だったのが、
どんどん話が変わっているような。しかも参照カウントとオブジェクトを
参照しているリストなんて、参照カウントを増やすこと以外に全然関係
無いから、工夫なんてまず無理だろう。
0896デフォルトの名無しさんNGNG
誰か本物の736を連れ戻してくれよ
0897デフォルトの名無しさんNGNG
>881=882だろ。
違いますよ。
0898デフォルトの名無しさんNGNG
だから参照カウントなんて腐った手法使うなって。
0899736NGNG
>898
ギブアップしたの?(W
0900デフォルトの名無しさんNGNG
だから最初から言ってるだろ?
参照カウントなんて使わずにまともなGC使えや。
0901デフォルトの名無しさんNGNG
参照カウントか、昔よくやってた。懐かしいな。マルチスレッドでうまく解けるか
自信ないけど…。

スレッド 1 がクリティカルセクションに入って参照カウントを 0 にしようとした
瞬間、別のスレッド 2 がカウントアップしようとクリティカルセクションで
ブロックに突入するからまずいんだろうな。同期ブロックに入っている数もカウント
しておいて、参照カウントと同期ブロックスレッド数が 0 になったところで初めて
開放すれば良いんじゃなかろうか。

…でも別スレッドからカウントアップ可能ということはそのスレッドから参照が残っ
てるってことだからやっぱり無理なのか? CPU 負荷などの影響でカウントアップ側の
処理が遅れたらアウトだもんな。んでもスレッド間での参照の「コピー」時にしっかり
カウントアップしてれば問題無いような。

参照カウントと循環参照について IBM に話が載ってるけどこれはガイシュツかいな。

http://www-6.ibm.com/jp/developerworks/java/000721/j_garbage-collection.html
0902デフォルトの名無しさんNGNG
参照を獲得する処理そのものがアトミックでなければいけない。
つまり、ref や release に到達する時点でそのオブジェクトに対する排他制御が
かかってなきゃいけない。それらのメソッドに入ってからでは遅い。

Object* List::get(int index){
 criticalSections_[index % 4].enter();
 Object* o = items_[index];
 if(o != NULL){
  o->ref();
 }
 criticalSections_[index % 4].leave();
 return o;
}

void List::remove(index){
 criticalSections_[index % 4].enter();
 Object* o = items_[index];
 if(o != NULL){
  o->release();
  items_[index] = NULL;
 }
 criticalSections_[index % 4].leave();
 return o;
}

こんな感じか?
0903デフォルトの名無しさんNGNG
レスがたくさんついていると思ったら、、、
0904入門者だけどNGNG
本質的には参照カウントのことは関係なくて、参照が複数スレッドで
共有されていれば、その参照自体にも排他をかけなければならない
というだけの話だ、という理解で合ってる?
0905デフォルトの名無しさんNGNG
そもそもスレッド間で参照を代入するときにちゃんと 参照数 +1 してれば
ゼロにはならないのでは?
0906デフォルトの名無しさんNGNG
>>905
>>742

あれから100以上もひっぱった736の連中、氏ね。
0907デフォルトの名無しさんNGNG
>>906
みんな同期問題の方に目がいっちゃってたね。
0908デフォルトの名無しさんNGNG
>>902
getって削除された要素を飛ばして次の要素を返すんじゃないか?
あと、removeが値を返してるよ。

>>905
その参照を増やす手段がgetなんだけど…
0909デフォルトの名無しさんNGNG
スレッドだけに限らず、とにかく「何ヶ所から指されてるか」
をちゃんと保持しないと。変数に代入したらちゃんと参照カウント
増やせ。
0910デフォルトの名無しさんNGNG
だから、参照カウント法はマルチスレッドにむちゃくちゃ不向き
なんだから、まともなGC使えってば...
0911デフォルトの名無しさんNGNG
>>908
スレッド A からスレッド B に参照を代入しようとしている。同時にスレッド C が
参照を開放しようとしている。

最初の時点で参照を持っているのは A と C だから参照数は 2、C がカウントダウン
したところで参照数は 1、そのあと B に代入されてカウントは 2 になる。

これのどこに参照数 0 になる要素があるか答えよ (同期化は当然行っている
とする)。

# と断言して俺が間違ってたら恥ずかしいわけだが…
0912デフォルトの名無しさんNGNG
単なる論理バグで 100 以上引っ張った悪寒
0913デフォルトの名無しさんNGNG
論理バグというより、勉強不足でしょ。
0914デフォルトの名無しさんNGNG
>>911
スレッドの数だけ数えりゃ良いわけじゃないって言うとるに。
ヒープ上のデータ(たとえばリスト)から参照されてて、
そのリストを指しているのはスレッドDだけだったとする。
あんたの数え方だと、スレッドAとBが参照を離したら、
リストから指されてるのに解放されちゃうよ。

また、同じスレッドの中でメソッド呼び出しに参照を渡した
とする。この時にも参照を増やさないと。呼び出された先で
参照が不要になったからって勝手にカウントダウンしたら
呼び出し元が困るだろ。
0915デフォルトの名無しさんNGNG
>>910
でも、C++みたいな言語でGCも怖い気がする。
GCのバグ云々じゃなく、相当気をつけて使わないと、GCと
例外機構やデストラクタが衝突してあぼーん、になりそうで
不安。Cの方がまだしも、処理系の動きが見えやすいだけ、
楽な気がする。
0916デフォルトの名無しさんNGNG
>>914
後半は普通につかってりゃありえんだろ
0917デフォルトの名無しさんNGNG
>>914
>あんたの数え方だと、スレッドAとBが参照を離したら、
>リストから指されてるのに解放されちゃうよ。
914をどう読むとそういう数え方になるんだ?
>また、同じスレッドの中でメソッド呼び出しに参照を渡した
>とする。この時にも参照を増やさないと。呼び出された先で
>参照が不要になったからって勝手にカウントダウンしたら
>呼び出し元が困るだろ。
それは弱い参照にするかどうかだよね。呼び出された先が、
どこにもその参照を突っ込まないで、カウントを変えないまま
リターンすれば問題ないわけで。
参照カウントの有難味は無くなるけど。
0918デフォルトの名無しさんNGNG
>>908
いや、index が識別子なのか単なる順序値なのかわからんし、
一応こうしといた。

remove は中途半端になっちまった。引数の型も抜けてるし。
中で release する場合と、オブジェクトを返して外で release する
場合と考えてた。
0919デフォルトの名無しさんNGNG
いくつの「スレッドが」参照してるかなんていう
数え方をするから間違える。

シングルスレッドでも参照カウントはちゃんと増減させるだろ?

とにかく「何ヶ所から指されているか」を正しく参照カウント
に反映させておかないと。

メソッド呼び出しではたしかに人間が推論して最適化すること
はあるね。間違いのもとだけど。
0920デフォルトの名無しさんNGNG
>>914
スレッド D が持つリストからも参照されてるなら初期状態での参照数は 3 だろ。
逝っておくがいくつのスレッドで共有されているかをカウントしているという意味
ではないぞ。

ただ循環参照になってるとどこからも使われてないのに参照数が残ってしまう
だろうな。単純な参照カウントの弱いところだ。
0921767=793=902NGNG
で、736 はどうした。問題は解決したか?
とりあえずリスト全体ロックは回避できたんだから、これくらい(複数のロックを使う)で
手を打つのがよいと思うのだが。

あとは、refcount が 0 になってもその場では削除せず、後で回収するくらいしか
無いと思う。もちろん回収の時は、全スレッドを安全な場所で停止させる必要があるが。

っつーかもっといい手があるのかどうか俺も知りたい。
0922デフォルトの名無しさんNGNG
OK 埋め立て成功。
            ∧_∧
     ∧_∧  (´<_`  )
     ( ´_ゝ`) /   ⌒i   さすがだな兄者。
    /   \     | |
    /    / ̄ ̄ ̄ ̄/ |
  __(__ニつ/  FIVA / .| .|____
      \/____/ (u ⊃
0923772NGNG
#うわあ。見ないでいたらこんな事態に…
#なんか終息しかけてますけど、まあ話題としては面白いのでいいけど。
ええと、>>788が重要な指摘だと思いますよ。

>>786の「実際には目的のデータであることを確認後」
この確認はどういうコードで行っているのですか?
ぱっと思いつくコードは例えばこうなんですけど。

//目的のデータであることを確認
O3 = O1 ; //ここで既に参照カウントが上がってる!
if (! IsWanted(O3)) {
//O3生成の瞬間にO1が破棄されているとO3に新規データが入っている
//エラー処理
}

O2 = O1 ; //既にO3があるのでO2は要らないけど安全にコピーできる。

なんか私大間違いしてます?
0924デフォルトの名無しさんNGNG
しかし良く考えてみると、リスト全体にロックしないと
removeはやっぱり出来ないんじゃないかなー。
単方向リストでも、双方向リストでも、配列+ホールでも…

少なくとも「n番目getする」という操作は正しく動かないだろう。
「キーkを持つ要素をgetする」ときも、一部だけロックで出来る?
0925デフォルトの名無しさんNGNG
素直にJava使え。
0926デフォルトの名無しさんNGNG
なんでこんなくだらん事で話を引っ張ってるの? > >>736
0927デフォルトの名無しさんNGNG
http://www15.big.or.jp/~kaini/image/img-box/img20021111111348.jpg
まぁこれでも見てマターリしる
0928デフォルトの名無しさんNGNG
Javaでもコレクションクラスのthread safetyについて考慮してるのは
jdk1.2以降ですな。

0929デフォルトの名無しさんNGNG
>>928
thread safety についてというか、1.1 までのコレクションは莫迦でも使えるように
何でもかんでも同期化してただけ。
0930デフォルトの名無しさんNGNG
1.4の日本語ヘルプ
>ConcurrentModificationException
>...
>たとえば、あるスレッドが Collection で繰り返し処理を行なっている間に、
>別のスレッドがその Collection を変更することは通常許可されません。

通常ダメなんだとさ。
0931デフォルトの名無しさんNGNG
この争いに参加しなかった俺は自制心の持ち主
0932デフォルトの名無しさんNGNG
レベル低いだけだろ?(W
0933デフォルトの名無しさんNGNG
>>929
じゃあ、いまでもVectorとか使ってるばかには使わせといた方がいいんですか?
0934デフォルトの名無しさんNGNG
Javaなら少なくともreference countで悩む必要はないね。
0935デフォルトの名無しさんNGNG
>>934
でも、たま〜に使いたくなることあるなぁ。。。
0936デフォルトの名無しさんNGNG
参照カウンタの使い方程度も分からないバカはJavaがお似合いだね
0937デフォルトの名無しさんNGNG
736 はどうしたのよ?
散々人を見下した発言を繰り返した割には、反論できずにだんまりかよ
ヘタレやの、おまえ
0938デフォルトの名無しさんNGNG
>>937
もういいよ・・・
0939デフォルトの名無しさんNGNG
真理を見通す目を使ってこのスレを覗いてみた。そこに見えたものは・・・

938 名前:736 投稿日:02/11/16 22:31
>>937
もういいよ・・・

0940デフォルトの名無しさんNGNG
736マジ死亡!?
もっと踊ってくれよ
0941772NGNG
>>923
あ、違った。O1がBスレッドにあるという時点で
既に参照カウントがアガってなきゃいかんのか。
鬱だ…。

DataType O1;
hr = pDataList->GetItem(index, &O1) ;
if (FAILED(hr)) { /* エラー*/ }
if (IsWanted(O1)

とか。ふむ。確かにリスト側で排他したくなるし、
同時に他スレッドで削除されてると面倒。やっと分かった。
0942767=793=902=918=921NGNG
>>941
参照を得る/切るタイミングでアトミックにカウントが上がる/下がる必要が
あるからなぁ。
そうでないと、無効なオブジェクトを参照してしまう。

ならば、参照カウントが 0 でも有効な(というより、無効かどうか判別できる)
ものを作るのも一つの手だな。

bool Object::ref(){
 bool valid = false;
 cs_.enter();
 if(refCount_ > 0){
  refCount_++;
  valid = true;
 }
 cs_.leave();
 return result;
}

void Object::release(){
 cs_.enter();
 if(refCount_ > 0){
  refCount_--;
  if(refCount_ == 0){
   garbages__.add(this);
  }
 }
 cs_leave();
}

で、安全なタイミングで(ってそれが一番むずい気も)garbages__(グローバル変数)
の要素を delete してやると。
0943942NGNG
# 続き。改行が多すぎるって言われちまった。

あるいは、Object ではなく、SharedPtr みたいな入れ物でこれをやっても良い。
SharedPtr のフィールドは Object* を格納する ptr_ と refCount_。refCount_ が
0 になったときに delete ptr_ するけど、 SharedPtr 自体は無効な状態で
残り、garbages__ に入る。

コメントくれ 736。もしくは偉い人。
0944942NGNG
>>942
ああ。result 返してるよ。ref の最後は return valid; ね。
コンパイルくらいは通すか...
0945デフォルトの名無しさんNGNG
もまいら別スレ立ててそっち逝け
0946デフォルトの名無しさんNGNG
>>943
736でも偉い人でもないが…

ref()がfalseを返したら、いったい何をすればよいんだ?

そもそも、release()で参照が0になるということは、release()を呼んだスレッド
以外からの参照はないはずなのに、他からref()が呼ばれるのがおかしいってば。

リストのgetとremoveが排他制御をちゃんとやれば、そういうことは起きないだろ?
getがロックを離す前にはrefが済んでいる。あるいは、removeが先なら、
参照が他のスレッドに渡ることはない。
0947デフォルトの名無しさんNGNG
やっぱり、どう考えてもリスト全体をロックするより無いなー。
0948デフォルトの名無しさんNGNG
Javaを使えば簡単に解決する低次元な問題に
一生悩みつづけるC++プログラマのスレはここですか?
0949デフォルトの名無しさんNGNG
二日留守にしてたからとっくに終ってるかと思えば、まだ続いてたのかよ。こ
の736祭は。
0950デフォルトの名無しさんNGNG
>>948
>>930
0951デフォルトの名無しさんNGNG
>>948
うん
だからオマエには関係ないんよ
どっか逝け、二度と来んな
0952942NGNG
>>946
いやだから。
List で排他制御をかけずに安全な方法があるかを探してる。

ってあまりやると今度は俺が煽られるかな。
0953デフォルトの名無しさんNGNG
>>952
特殊な場合はあるかもしれんが、一般的なリストのセマンティクスを
ロックなしで一貫性を持って実現するのは無理だろう。

たとえば
「n番目を取り出す」→他のスレッドが先頭を削除したら、戻ったときには正しくない値を返してしまう。
「データxを含む最初の要素を取り出す」→探索中に他のスレッドが先頭にxを
付け加えたら…
0954942NGNG
>>953
その特殊な場合が知りたい。
そのために、902 の List::remove では、items_[index] = NULL をもって
要素削除としてる。

いや、現実問題、こんなことしてたら、List も Object も、使う側に
知識を要求する、やっかいなクラスになるとは思う。

ただ、そうすることによってパフォーマンスが得られるなら、
それが有効な選択肢になる場合もある。
ってことで、無理問答みたいなことを続けてるわけだ。

っていうか 736 が続けてくれよこれ。
0955デフォルトの名無しさんNGNG
あのさぁ、参照カウントの時に出てきた↓を見てみたんだけど、
http://www.gotw.ca/gotw/045.htm

void String::AboutToModify(size_t n, bool bMarkUnshareable /* = false */)
 int refs = IntAtomicGet( data_->refs );
 if( refs > 1 && refs != Unshareable ) {
  StringBuf* newdata = new StringBuf( *data_, n );
  if( IntAtomicDecrement( data_->refs ) < 1 ) {
   delete newdata; // just in case two threads
  } // are trying this at once
  else { // now all the real work is
   data_ = newdata; // done, so take ownership
  }
 } else {
  data_->Reserve( n );
 }
 data_->refs = bMarkUnshareable ? Unshareable : 1;
}

の、delete newdataって間違いじゃない?
0956955NGNG
複数のスレッド(それぞれが参照を持つ)が同時にAboutToModifyを呼び出すと、
それぞれが共有を解除して、独自にデータを持つわけだが、その内の一つは
data_->refs が0になるから、元の共有していたdata_の指す先か、newdataの
一方を開放する必要がある。

というのは判るんだけど、AbountToModifyは共有解除と共にsize_t nに
データ領域のサイズを拡張しなきゃならんのに、delete newdataでは
data_の指す先の領域のサイズはsize_t nだけあるとは限らなくない?

ここは、単純に
if( IntAtomicDecrement( data_->refs ) < 1 ) {
 delete data_; // just in case two threads
}
data_ = newdata; // done, so take ownership
じゃないかと思うんだが…
0957名無しさん@カラアゲうまうまNGNG
あるいはこうか?

  if( IntAtomicDecrement( data_->refs ) < 1 ) {
   delete newdata; // just in case two threads
  data_->Reserve( n );
  } // are trying this at once
0958955NGNG
ですな。
でも、既にnewdataはサイズn以上で領域確保しているので、
data_を破棄する方が良いかと。

誰も、反論が無いところを見ると、やっぱり間違いと言う事でよろしいか?
0959デフォルトの名無しさんNGNG
パフォーマンスを得るためならreference count法なんて
使っちゃいかんと思うが...
0960名無しさん@カラアゲうまうまNGNG
>>958
いいんじゃん。

ところで、次スレって立てんの?
0961デフォルトの名無しさんNGNG
>959

別にリファレンスカウントでアロケーション回数を少なくしてパフォーマンスを稼ごう
という事ではなくて、そもそも大域的なデータをマルチスレッドで使う時には意味無いかな?
0962デフォルトの名無しさんNGNG
>>960
マルチスレッドプログラミングの苦労はすべて、
C++を使う事が原因だと結論が出たので、
次スレは不要でしょう。
0963デフォルトの名無しさんNGNG
たてますよー
0964963NGNG
載せるようなリンク先がねえよ...
0965デフォルトの名無しさんNGNG
>>962
どっちかというと、不要なのはオマエだな
0966次スレの逝ってよしの1NGNG
次スレ立てました
http://pc3.2ch.net/test/read.cgi/tech/1037636153/

間違えて3つも立ててしまった・・・
決してマルチスレッドとかけたわけではありませぬ・・・
0967デフォルトの名無しさんNGNG
じゃあ1000取りでもはじめるか
0968デフォルトの名無しさんNGNG
どれが本スレなんだ・・・。
次スレには全部重複ごめん、次スレはこちら、と書いてあり
リンクをたどると無限ループするんだが・・・。
0969デフォルトの名無しさんNGNG
>>968
削除依頼板に書いてあるとおりです
0970デフォルトの名無しさんNGNG
スレ立てもマルチスレッドでやって、排他制御に失敗したのはこのスレですか?
0971デフォルトの名無しさんNGNG
ここの奴らの話は信用ならねーな
0972デフォルトの名無しさんNGNG
つーか「間違えて」3つも立てられるはずないだろ。
明らかに故意に串を差し替えるとか回線を繋ぎ替えるかして
立てたはずだ。
市ねよ。
0973デフォルトの名無しさんNGNG
>>968
素朴な参照カウントモデルは循環参照があると
役に立たないのです
0974次スレの逝ってよしの1 NGNG
>>972
いえ、それが同じアドレスから3連発したのです
一度目はコネクションタイムアウト
二度目は30秒ぐらいでこちらから停止
三度目で成功
で、気づいたら3つ立ってました(;_;)
一回目の段階で、しばらく待って、スレ一覧をチェックすればよかったんですね。

しばらくスレ立てはやめときます・・・
0975デフォルトの名無しさんNGNG
2ch の調子が悪くてスレ立ての重複が頻発しているらしいよ。
0976デフォルトの名無しさんNGNG
>973
> 素朴な参照カウントモデルは循環参照があると

うん、それで?
参照カウントを使って、どんな場合にも使えるクラスを設計しようとしてるならともかく、
循環参照が発生しないデータモデルで使用する場合には、何の意味も無いな。

>972
スレが3つ立ったからって、そんなに迷惑被ったのかヨ?
引きこもりは、攻撃性が強くて困るな。
0977デフォルトの名無しさんNGNG
>>976
「リンクをたどると無限ループ」に引っ掛けたネタに
マジレスされても困るのだが
0978デフォルトの名無しさんNGNG
>>973
ネタニマジレスカコワルイ
>>976
ネタノカイセツカコワルイ
0979デフォルトの名無しさんNGNG
>>978
>>976 -> >>977
ネタノテイセイカコワルイ
イッテキマス...
0980デフォルトの名無しさんNGNG
誰も居ない・・・
????するならイマノウチ
0981デフォルトの名無しさんNGNG
????
0982デフォルトの名無しさんNGNG
????
0983デフォルトの名無しさんNGNG
????
0984デフォルトの名無しさんNGNG
????
0985デフォルトの名無しさんNGNG
ぬるぽー!!
ぬるぽぬるぽぬるぽぬるぽぬるぽ


      ぬ る ぽ ー っ ! ! !

0986デフォルトの名無しさんNGNG
????
レス数が950を超えています。1000を超えると書き込みができなくなります。