マルチスレッドプログラミング相談室 その3
レス数が950を超えています。1000を超えると書き込みができなくなります。
0001デフォルトの名無しさん
NGNGOS・言語・環境は問わないが、それゆえ明記すべし。
その1 http://pc3.2ch.net/test/read.cgi/tech/997345868/
その2 http://pc5.2ch.net/test/read.cgi/tech/1037636153/
0002デフォルトの名無しさん
NGNGpthread地獄
http://pc5.2ch.net/test/read.cgi/unix/1010933537/l50
Pthread -- POSIX Thread Mailing List
http://www.media.osaka-cu.ac.jp/mailman/listinfo/pthread
0003デフォルトの名無しさん
NGNGThe Single UNIX Specification, Version 2 Threads Extensions
http://www.unix.org/version2/whatsnew/login_threads.html
Multithreading in the Solaris Operating Environment
http://wwws.sun.com/software/whitepapers/solaris9/multithread.pdf
Building an open-source Solaris-compatible threads library
http://www.opensource.hp.com/the_source/linux_papers/scl_solaris.htm
Pthread Support in Microsoft Windows Services for UNIX Version 3.5
http://www.microsoft.com/technet/itsolutions/interop/sfu/pthreads0.mspx
Programming with POSIX Threads
http://www.awprofessional.com/title/0201633922
0004デフォルトの名無しさん
NGNG並列オブジェクト指向プログラミングの設計原理」
http://www.amazon.co.jp/exec/obidos/ASIN/4881359185/
0005デフォルトの名無しさん
NGNG誌ね
0006デフォルトの名無しさん
NGNG糞スレ乙
0007デフォルトの名無しさん
NGNGネタ щ(゚▽゚щ) カモーン
0008デフォルトの名無しさん
NGNG0009デフォルトの名無しさん
NGNGロックせずに交互に描画なんかしたりしたらまずいよね?
なんかWeb上にそういうサンプル使って説明してる馬鹿がいたからびっくりした
0010デフォルトの名無しさん
NGNG...
0011デフォルトの名無しさん
NGNGどこのページ?
0012デフォルトの名無しさん
NGNG0013デフォルトの名無しさん
NGNGなかなか難しいね。頭痛いわ。
0014デフォルトの名無しさん
NGNGスローダウンってなんですか?
0015デフォルトの名無しさん
NGNG0016デフォルトの名無しさん
NGNG早く直せよ
0017デフォルトの名無しさん
NGNGこの辺か?
ttp://wisdom.sakura.ne.jp/system/winapi/win32/win144.html
0018デフォルトの名無しさん
NGNG0019デフォルトの名無しさん
NGNGスローダウンぐらいぐぐれよ(((;-д- )
ttp://msugai.fc2web.com/java/thread/deadLock.html
システムプログラミングの本には大抵症状を起こすプログラム例がのっている。
0020デフォルトの名無しさん
NGNG0021デフォルトの名無しさん
NGNGべつにyahooでいいじゃん
0022デフォルトの名無しさん
NGNG全然違う。内部でミニデッドロックが多発して、本来走っているべき
スレッドの数が大幅に少なくなっているのがスローダウン。止まらず
に動いているので一見正常に見えるが、処理速度が遅くなるので、
あちこちに不都合が出る。最終的に完全なデッドロックに移行してしまう
事もある。
設計ミスが原因。
0023デフォルトの名無しさん
NGNGジャインアントロックすると簡単に起きるよね。
0024デフォルトの名無しさん
NGNG0025デフォルトの名無しさん
NGNG0026デフォルトの名無しさん
NGNG0027デフォルトの名無しさん
NGNG管理に手間かかってメモリ余計に食うだけだろ
普通に処理したほうが百倍早い
0028デフォルトの名無しさん
NGNGレベルの低い方はお引き取りください
0029デフォルトの名無しさん
NGNGたいていそうだよね (百倍速いってことはないけど)。
できるだけ避けるほうがいいと思うよ、マルチスレッド。
0030デフォルトの名無しさん
NGNGなおしたのか?
0031デフォルトの名無しさん
NGNGHT
0032名無しさん@お腹いっぱい。
NGNG0033デフォルトの名無しさん
NGNG>>19のリンク先との説明と全然ちがうのですが、どっちが正しいの?
0034デフォルトの名無しさん
NGNGまだです
0035デフォルトの名無しさん
NGNG>>19のリンク先の説明は舌足らず。ちゃんとした本を買って勉強した方がいい。
0036デフォルトの名無しさん
NGNG>内部でミニデッドロックが多発して
それは普通にデッドロックって言わない?
0037デフォルトの名無しさん
NGNGさっさと直せよ
0038デフォルトの名無しさん
NGNG0039デフォルトの名無しさん
NGNG0040デフォルトの名無しさん
NGNG0041デフォルトの名無しさん
NGNG0042デフォルトの名無しさん
NGNGそれに相当すると思う。またレース状態ってのもある。
ttp://www.microsoft.com/japan/msdn/vs/general/vbtchusingthreads.asp
0043デフォルトの名無しさん
NGNGリソースを割り当てられないエンエィティがあること。
レース状態というのは、
単にリソースを奪い合う関係にある状態のこと。
0044デフォルトの名無しさん
NGNG0045デフォルトの名無しさん
NGNG誰かが言うと思ってた。本当にバカなんだから。
0046デフォルトの名無しさん
NGNG0047デフォルトの名無しさん
NGNG0048デフォルトの名無しさん
NGNG以下のようなプログラムを作ってる。
懸賞サイトをよく利用するので住所などの入力を自動にするプログラム。
配布されてるのはあるが、なんか使いにくく機能がいまいち。
サイトごとに指定できないので、入力がおかしくなる懸賞サイトがある。
0049デフォルトの名無しさん
NGNGスレ違い。
0050デフォルトの名無しさん
NGNG「現在動いている」とは?
0051デフォルトの名無しさん
NGNG0052デフォルトの名無しさん
NGNG使えるようにするだけなら、MPIの実装をinstallしろ。それだけだ。
0053デフォルトの名無しさん
NGNG0054デフォルトの名無しさん
NGNG0055デフォルトの名無しさん
NGNG0056デフォルトの名無しさん
NGNGそれ未満のOS(マルチCPUやHyperThreadingなども含めて)ではスレッドの切り替え時には、
同期制御をして書き換えた部分も切り替え後に値が途中までしか変わっていない
ということが有り得るのでしょうか?
通常、小さい変数などはvolatileをつけるべきだってのは知っているのですが、
const_castでvolatileを変える仕様はMS VC7.1には入っていないし、
同期をかけるクラスはすべてvolatile版も作れということですかねぇ。
0057デフォルトの名無しさん
NGNG前スレ読め。
0058デフォルトの名無しさん
NGNGその1にもありますかね?その1読み中。
0059デフォルトの名無しさん
NGNG006056
NGNGその1をよんだところ、マルチスレッドな環境で同期処理用の関数で
制御を行うときにはキャッシュはクリアしていなければ、まともに動作しねぇ。
マルチプロセスじゃ弱いメモリモデルというのになってるらしい。
本でもあさってみますわ
0061デフォルトの名無しさん
NGNG微妙に誤認がある。やはりその2嫁
0062デフォルトの名無しさん
NGNGgoogleのキャッシュとか、archive.orgとか。
006356
NGNGVC++な俺は_ReadWriteBarrierでreorderされないようにバリアしろ。
Intrinsicな_Interlocked*をつかって、reorderも抑制しろ。
ソース書き直す前に、手持ちの本も読んでみます。
0064デフォルトの名無しさん
NGNG0065デフォルトの名無しさん
NGNG君には無理です。氏になさい。
0066デフォルトの名無しさん
NGNGここでスレイプの練習するの止めてくれる?
自作自演で煽り煽られの状態に持ち込むのがテクニックの一つだよね?
0067デフォルトの名無しさん
NGNGなんか参考になるサイト教えてくださいおながいします。
006867
NGNG0069デフォルトの名無しさん
NGNGpthreadが無難だと思う
0070デフォルトの名無しさん
NGNG気持ち悪いです。
0071デフォルトの名無しさん
NGNG0072デフォルトの名無しさん
NGNG得意げになってクソスレ立てまくるんだよな
これ、マジでシャレにならんよ
0073デフォルトの名無しさん
NGNGkernelのversionは新しくしてね。
古いlinuxthreadは糞だから。pthread互換じゃないから。
0074デフォルトの名無しさん
NGNG0075デフォルトの名無しさん
NGNG何かありましたらお教えください。お願い致します。
0076デフォルトの名無しさん
NGNG0077デフォルトの名無しさん
NGNGJavaの範囲(モニタ)に特化してるかも。とするとpthreadだと使いにくそうな気がする。
組み込み系の本に載ってるかも…でもスレッドじゃなくて全体が並列に動くからなあ。
0078デフォルトの名無しさん
NGNGUML
昔はペトリネット
0079デフォルトの名無しさん
NGNGメモリにアクセスする時にクリティカルセクションで同期をとっています。
クリティカルセクションEnter状態の時に、子関数を呼んだ場合
子関数が動作中も安全なのでしょうか。
Thread()
{
EnterCriticalSection();
Func();
LeaveCriticalSection();
}
Func()
{
共有するメモリの編集処理
}
0080デフォルトの名無しさん
NGNG安全なのです
0082デフォルトの名無しさん
NGNG0083デフォルトの名無しさん
NGNG0084デフォルトの名無しさん
NGNG他スレッドはEnterCriticalSection()から返ってこない。
動作を見れば簡単にわかるだろうに・・・。
0085デフォルトの名無しさん
NGNG0086デフォルトの名無しさん
NGNGpthread_setschedparam()
0087デフォルトの名無しさん
NGNG0088デフォルトの名無しさん
NGNGpthread_cond_wait関数を用いて待機させ、
pthread_cond_signalやpthread_cond_broadcast関数を用いて
待機スレッドを起こしています。
ここで質問ですが、
ある時点において、待機中のスレッドがあるかどうか、
できればいくつあるのか、を拾う術はあるのでしょうか。
ある待機中のスレッドをpthread_cond_signal関数で起こした際に、
他に待機中のスレッドがあるかどうかで処理を変えたいと思っています。
以上、よろしくお願いします。
0089デフォルトの名無しさん
NGNG0090デフォルトの名無しさん
NGNGpthread_*にはないので、その辺のロジックは自分で書く。
0091デフォルトの名無しさん
NGNG0092デフォルトの名無しさん
NGNG0093デフォルトの名無しさん
NGNG0094デフォルトの名無しさん
NGNGhttp://www.amazon.co.jp/exec/obidos/ASIN/4756116825/qid=1102708104/sr=1-3/ref=sr_1_10_3/249-8517280-2920313
下のは持ってるが、ソラリスマンセーでいかにソラリスが素晴らしいか
嫌というほど延々と語っている本だ。訳文は悲惨だし、カナーリ古い内容なので
お勧めはしないけど。どこに住んでるんだ?
都内なら、神保町の三省堂本店に二冊ともあったよ。
0095デフォルトの名無しさん
NGNG前の本は古いSolairs独自のスレッドAPI。しかし解説が良い。
初心者向けのスレッド概念、マルチスレッド技法から説き明かしてある。
Solarisは8辺りからスレッド内部が結構変っているから、
細かい制御をしたい人は、>>3のSunのPDFを。
0096デフォルトの名無しさん
NGNG009769式フリーPG ◆hND3Lufios
NGNG0098デフォルトの名無しさん
NGNGありが�d
あちこち調べまわった結果、95以外は一応大丈夫みたいですのう。
でもfiber関連はドキュメント見ると
> Windows NT: 3.51 SP3 以降を使います。
> Windows: サポートされていません。
と書いてあるのが激しく不安
0099デフォルトの名無しさん
NGNGMicrosoft Platform SDK February 2003から
Client: Included in Windows XP, Windows 2000 Professional, Windows NT Workstation 3.51 SP3 and later, Windows Me, and Windows 98.
0101デフォルトの名無しさん
NGNG診断(デバッグ)目的なら、必要な状況は理解できるが
それ以外だとちょっと用途が浮かばない。
だいたい、調べた次の瞬間、待機中のスレッドが待機中かどうかわからんし。
sem_getvalue( )なんかも同じだけどね。
セマフォ値を得たところで、その値を使うころに
値がどうなっているのかわからん。
0102デフォルトの名無しさん
NGNGMPICHを入れようね。
SSHかRSHを使えるようにしてね。
複数のコンピュータ上にNFSで同じディレクトリを用意しておいてね。
mpicc hoge.c
mpirun a.out
で実行できるよ。
0103デフォルトの名無しさん
NGNGわかりました。
がんがります。
>>101
まさにその通りで、デバッグ用に使おうと思ってました。
printkでどう表示するか、を分けようと・・・。
仰っている懸念は、設計上回避しているつもりではいます。
一旦あるスレッドがpthread_cond_signalで起こされると、
起こされたスレッドでの処理が終わるまではpthread_cond_signalは
呼ばれないようにはしています。
逆に待機スレッドが増えるという可能性はありますが、待機スレッドが
0か0以外かさえわかればいいので無問題です。
というわけでセマフォを使うことにします。
ありがとうございました。
0104デフォルトの名無しさん
NGNG表示だけならどうと言うことは無いけど...。
> 一旦あるスレッドがpthread_cond_signalで起こされると、
> 起こされたスレッドでの処理が終わるまではpthread_cond_signalは
> 呼ばれないようにはしています。
スレッドの処理の終了と pthread_cond_signal を呼び出す処理の競合のあたりちと心配。
0105デフォルトの名無しさん
NGNGpthread_createで得られるptherad_tを使って判定する関数がありそうなのですが、
調べたところ見つかりませんでした。
0106デフォルトの名無しさん
NGNGのではだめなの?何も複雑にすることないじゃん。
0107105
NGNG1.動いているかどうか判定する変数を用意する。
2.pthread_create()の直前にtrueにする。
3.pthread_create()で設定したデストラクタでfalseにする。
0108デフォルトの名無しさん
NGNGテストした瞬間、どうなっているかわからんがな。
0109デフォルトの名無しさん
NGNG質問の意味がさっぱりわからん。
pthread_tがあるってことは、それすなわちthreadじゃないのか?
「スレッドが動いている」って何?
0110デフォルトの名無しさん
NGNGhttp://lists.debian.org/debian-devel/2003/04/msg02112.html
0111デフォルトの名無しさん
NGNGざっと読んだところ。
主張
・正式な意味でのi386サポートをやめたい
理由
・gcc3.2以降はi386をサポートしていない(i386では動作しない)
・i486以降に限定すれば、速度の面でかなり有利。カーネルも、ユーザアプリも。
・i386とi486以降を個別にサポートするのは時間の無駄だ。
提案(3案)
・i386とi486以降に分けて、それぞれサポートする
・i386アーキを捨てる。i486という名前のアーキを新たに作成する
・i386の名前のまま、実際はi486以降必須にする
てなところか。酔ってるので間違い勘弁。
0112105
NGNGまずメインスレッドがありますよね?これをスレッドAとします。
そしてpthread_createで新しいスレッドを作って動かします。これをスレッドBとします。
Bで何か作業をやらせておいて、AではBが終わった瞬間、Bの計算結果を使った処理をします。
ところがBが終わったという判定をする方法がわからないのです。
それからpthread_joinはAの作業が止まってしまうので使えません。
以下のプログラムで、isfinished()という関数がありますが、
このようにスレッド識別子pthread_tを使ってスレッドの終了を判定したいのです。
0113デフォルトの名無しさん
NGNG/*スレッドB*/
void thfunc(void *dat)
{
/*ここでスレッドBの計算を行う
最終的にglobal_valueに計算結果の値が入る*/
}
/*メイン(スレッドA)*/
int main()
{
pthread_t th;
pthread_create(&th, NULL, thfunc, NULL);
while(1){
/*あるループを伴う作業*/
/*Bで計算が終わったか?*/
if( isfinished(th) ){
/*global_valueを使う*/
}
}
return 0;
}
0114デフォルトの名無しさん
NGNGpthreadのリファレンスには載っていませんでした。
もしjavaが分かるようでしたら、スレッドクラスのisAlive()と同じものと思ってください。
あるいはjavaの場合はjoin()する際タイムアウト時間が設定できるので、
もしCでもそのような方法があるようでしたら、教えてください。
0115デフォルトの名無しさん
NGNG「GUI アプリケーションの場合は、プロセスの主スレッドで呼び出さないようにしてください」
と書いてあったのですが、
これはスレッドを作ってそこでやればいいということですか?
0116デフォルトの名無しさん
NGNG単一スレッド上でブロッキングソケットを使っても構わないよ。
0117デフォルトの名無しさん
NGNG0120115
NGNGサーバーとして待機するときにacceptを使った瞬間、
アクセスがあるまで次に進まないので、
ウィンドウプロシージャに送られてくるメッセージなんかも
たまる一方で処理できないということですね?
0121117
NGNG0122105
NGNG(´・ω・`)ショボーン
0123デフォルトの名無しさん
NGNGその処理なら condition variable を使えばいいんじゃないの?
なんでわざわざ thread の生存で判断したいのかわからん。
0124デフォルトの名無しさん
NGNG「別のスレッドが終了したこと」ではなく、
「別のスレッドで行っている処理が終了したこと」なんでしょ?
だったら、自分で書いたようなフラグを使っての判定で良いと思うんだけど。
0125デフォルトの名無しさん
NGNGダセエな
0126デフォルトの名無しさん
NGNG0127デフォルトの名無しさん
NGNGAn absolute time measure was chosen
for specifying the timeout parameter for two reasons.
First, a relative time measure can be easily implemented
on top of a function that specifies absolute time,
but there is a race condition associated with specifying an absolute timeout
on top of a function that specifies relative timeouts.
0128デフォルトの名無しさん
NGNGthe thread blocks for too long.
Blocking, however, is irrelevant if an absolute timeout is used.
An absolute timeout also need not be recomputed if it is used multiple times in a loop,
such as that enclosing a condition wait.
0129デフォルトの名無しさん
NGNG「マニュアル読め」
0130デフォルトの名無しさん
NGNG0131デフォルトの名無しさん
NGNGどうもしっくりこない。
マヌケ野郎ならなおさら。
なんでだろ
0132デフォルトの名無しさん
NGNG0133デフォルトの名無しさん
NGNG0134デフォルトの名無しさん
NGNGwhileの無限ループが入ったスレッドを二つ立ち上げるだけで一気にCPU使用率が100%いく。
一つ目ならまだなんとか20%台なんだが。
スレッドってこんなものなのか?
0135デフォルトの名無しさん
NGNG0137デフォルトの名無しさん
NGNG一つで20%しか食わないって方がOSのスケジューラに問題ありそうな。
0138デフォルトの名無しさん
NGNG0139134
NGNGどうも。
それから、
同じスレッドを複数呼び出したりしたら、そのスレッド内のローカル変数はどうなりますか?
例えば、 a という数値型変数をローカル変数として宣言してあって、
そのスレッド内で一定時間おきに a の値を一つずつ増やしていく・・・
ということをした場合、このスレッドを2つ3つと走らせた場合に
a の値は・・・?
2倍、3倍になりますか?
それとも各々のスレッド内で独立した変数として通常通り一つずつ増えていきますか?
0140デフォルトの名無しさん
NGNGauto変数は全関数呼び出しインスタンスで別個。
0142デフォルトの名無しさん
NGNGビジーループには0.1秒、または0.05秒Sleepを置くのが常套手段
0143デフォルトの名無しさん
NGNGもっともスマートあるいはエレガントで
標準的な方法は?
0144デフォルトの名無しさん
NGNG0145デフォルトの名無しさん
NGNG0146デフォルトの名無しさん
NGNG0147デフォルトの名無しさん
NGNG0148デフォルトの名無しさん
NGNG失敗終了させればいいのか。
終了フラグ立ててダミーパケットを送ってみたりしてたんだが、
何か随分無駄っぽい気がしてたんだよな。
「パケットとりこぼしたらやだな」ってのもあったし。
最初、終了フラグに揮発性を設定し忘れてたし。
0149デフォルトの名無しさん
NGNG0150デフォルトの名無しさん
NGNG>例えば、 a という数値型変数をローカル変数として宣言してあって、
>そのスレッド内で一定時間おきに a の値を一つずつ増やしていく・・・
>ということをした場合、このスレッドを2つ3つと走らせた場合に
>a の値は・・・?
すいません、139じゃないんですけど、ちょうど悩んでたんで便乗でおしえてください。
上記の139さんの質問、Cの場合は答えて頂いてますが、Delphiだとどうなるでしょうか?
さらに上の例で言うと、aがローカルではなく、スレッドのpublicなメンバーだったらどうなるでしょうか?
0151デフォルトの名無しさん
NGNG0152デフォルトの名無しさん
NGNGTThreadから派生させて作ったクラスのpublicメンバ変数ってことです。
こんな感じ。
type
TMyThread = class(TThread)
private
{ Private 宣言 }
public
a: integer;
protected
procedure Execute; override;
end;
0153デフォルトの名無しさん
NGNG0154150
NGNG0155デフォルトの名無しさん
NGNGmake-engineがそれにあたるのでしょうか…
0156デフォルトの名無しさん
NGNGグローバル変数と一緒。
0157デフォルトの名無しさん
NGNG回答ありがとう。
しかし...グローバルと一緒ですか...
Priveteならたぶんスレッド内で独立した変数になるんだろうけど、メインのフォーム
から操作する必要あるんですよねえ。
publicな手続きつくってその中でaを操作すればいいのかな。
0158デフォルトの名無しさん
NGNG御免、言っている意味がよくわからない。
スレッドローカルな変数で、グローバル変数とローカルな変数の中間。
生存期間: そのスレッドが終了すると(TThreadが消えると)なくなります。
アクセス: パブリックなので、アドレス分かればどこからでもアクセス可能。
0159デフォルトの名無しさん
NGNGそのスレッドから見ればグローバル変数と一緒。
0160157
NGNG僕も最初そうかと思ったんですけど、実際に動かして見るとどうも動きがちがうのよねえ。
152であげた例でいうと、メインフォームのほうでこいつのインスタンスを二つ作って
Thread1:=TMyThread.Create(False);
Thread2:=TMyThread.Create(False);
でaを操作する。
Thread1.a:=1;
TMyThreadのExecuteでaを監視してるんですが、これやると、なぜかThread2も
反応してしまうんですよ...
どこが間違ってるんでしょうか。ご指導お願い致します
0161デフォルトの名無しさん
NGNG0162デフォルトの名無しさん
NGNG0163デフォルトの名無しさん
NGNGスレッドローカルだからでは?
もう自分でも何をしたいのか、よくわかっていないでしょ?
0164157
NGNG163さん言うとおり、相当煮詰まってあれこれ試しているうちに
何がなんだか混乱していたのも事実です。
aをpriveteに移して、aをメインスレッド側からいじらないように改造
したら誤動作なくなりました。
正直言うとまだ明確にはわかっていません。
あまりプログラミングの知識ないのですが、最初ごく単純なツール
の予定だったので私でもできるかなと引き受けたのですが、あれよ
あれよと機能追加要求が来て大変です。
でもまあ、あれこれ迷いながら楽しんで仕事できてます。
とりあえず変数の種類とスコープを復習しなおすことにします。
ありがとう。
0165デフォルトの名無しさん
NGNG「無効なアンワインド対象がアンワインド操作で検出されました。。」
ってなんやねんわけわかめ!わけわか!
0166デフォルトの名無しさん
NGNG0167デフォルトの名無しさん
NGNG「アンワインド」の意味は分かっているの?
スタック上のアンワインド用のメタデータが壊れているんでしょう。
それが餡ワイン度している時に見つかったと。
0168デフォルトの名無しさん
NGNG0169デフォルトの名無しさん
05/01/19 13:16:21どこもロックしてないのにLockSemaphoreだけロックされててわけわかめ。なんじゃこれ
もう疲れた
0170デフォルトの名無しさん
05/01/23 22:50:00#POSIX, Win32両方使ってます。
0171デフォルトの名無しさん
05/01/24 13:58:45コードで示せ。
0172170
05/01/24 14:58:01↓
メインスレッドがスレッドTを生成する
↓
TがgFooの値を排他制御なしで読む
の順で処理が発生したとき、Tが観測するgFooの値が1であることが保証されているかが知りたいです。
メインスレッドは1を書いた後、当面gFooにアクセスしないと仮定してOKです。
よろしくおながいします。
0173デフォルトの名無しさん
05/01/24 16:33:36環境によっては保証されない。
何故ならば、大域変数へのアクセス完了を待ってスレッド生成する保証がないから。
0174170
05/01/24 18:28:24> 環境によっては保証されない。
> 何故ならば、大域変数へのアクセス完了を待ってスレッド生成する保証がないから。
gFoo = 1;
// ここ
pthread_create();
というコードで、「ここ」と書いたところはsequence pointで、かつ「ここ」ではまだシングルスレッド
状態なわけですが、それでも「大域変数へのアクセス完了を待つ」が保証されないのでしょうか?
>> スレッドの生成や消滅って、implicitなmemory barrierになると考えて良いのでしょうか?
という質問に戻ってしまうわけですが・・。
0175デフォルトの名無しさん
05/01/24 18:52:291の代入が完了しなければスレッドが作られないんだから。
1の代入とスレッド作成は同一スレッドで行われるわけだからね。
0176デフォルトの名無しさん
05/01/24 18:56:38前スレの最後の方とか http://www.nwcpp.org/Downloads/2004/DCLP_notes.pdf を見た上でもそう思う?
0177デフォルトの名無しさん
05/01/24 19:09:38する場合でも、movが完了する前にpthread_createされることって有り得るの?
そういう話ではないよね?コンパイラのオプティマイザによって変わってくるということかね?
0178デフォルトの名無しさん
05/01/24 19:11:430179デフォルトの名無しさん
05/01/24 19:13:19・コンパイラがreorderしなくても、CPU(H/W)が命令をreorderするかもしれない
・あるCPUでmovが完了したからといって、その値が別のCPUから観測可能かはわからない
ということでは?
0180デフォルトの名無しさん
05/01/24 19:20:28前スレッドを見たいが見られない。困った。
0181デフォルトの名無しさん
05/01/24 19:23:32memory barrierでググればそれ関係の論議は大抵見つけられると思う。
0182170
05/01/24 19:33:12ているのか、挿入するよう規格が要請しているかが知りたいです。
#またはfenceなどなくても大丈夫というならその理由を
0183デフォルトの名無しさん
05/01/24 20:19:010184デフォルトの名無しさん
05/01/24 20:22:170185デフォルトの名無しさん
05/01/24 21:19:140186デフォルトの名無しさん
05/01/24 21:22:380187デフォルトの名無しさん
05/01/24 21:24:35詳しく
>>186
ポカーン
0188デフォルトの名無しさん
05/01/24 21:24:420189デフォルトの名無しさん
05/01/24 21:25:480190170
05/01/24 21:39:43> total store order
すみません、memory modeに疎く、TSOだけだとちょっと意図が汲めません。結局>>172の例は
safe/unsafeどちらだとお考えでしょうか?
0191170
05/01/24 21:40:280192デフォルトの名無しさん
05/01/24 21:54:32volatile とか VC/VC++ の _ReadWriteBarrier とかその辺の問題はともかく、
MSのサンプルでも、Win32のThreadProcで、渡されたデータ、実体はポインタ、
が挿すメモリアクセスするような場合にMemoryBarrier()呼び出しをしている例は
一度も見たことなく、逆の例は沢山あるので、
Win32のCreateThreadはメモリバリアになってるような気がします。
具体的なドキュメント等の記述は見つからないけど。
0193デフォルトの名無しさん
05/01/24 21:55:20編集していたらなんか「、」が多くて変な文になってしまった。
0194デフォルトの名無しさん
05/01/24 22:04:250195デフォルトの名無しさん
05/01/25 00:30:21POSIXではpthread_create()もpthread_join()もMemory Synchronizationが
要請されてますな。
ttp://www.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap04.html#tag_04_10
0197デフォルトの名無しさん
05/01/25 22:20:490199デフォルトの名無しさん
05/01/25 23:09:070200デフォルトの名無しさん
05/01/25 23:34:260201デフォルトの名無しさん
05/01/26 00:34:16ISO C/C++的にはシグナルハンドラからアトミックに更新したい変数に用いる型、だね。
volatile sig_atomic_t。この使い方以外でvolatileって語は出てこないし。
あーあと、POSIXにはまったく登場しないね。
0202デフォルトの名無しさん
05/01/26 00:36:5956はリア厨だったりする罠。
>通常、小さい変数などはvolatileをつけるべきだってのは知っているのですが、
必要ありません。
>const_castでvolatileを変える仕様はMS VC7.1には入っていないし、
>同期をかけるクラスはすべてvolatile版も作れということですかねぇ。
CRITICAL_SECTION使え
0203デフォルトの名無しさん
05/01/26 14:01:570204デフォルトの名無しさん
05/01/26 15:27:420205デフォルトの名無しさん
05/01/26 17:22:230206デフォルトの名無しさん
05/01/26 19:04:350207デフォルトの名無しさん
05/01/26 19:13:180208デフォルトの名無しさん
05/01/26 19:14:250209デフォルトの名無しさん
05/01/26 19:58:210210デフォルトの名無しさん
05/01/26 20:36:310211デフォルトの名無しさん
05/01/27 00:31:200212デフォルトの名無しさん
05/01/28 00:28:170213デフォルトの名無しさん
05/01/28 02:46:28どんな時ですか? 長い時間掛かる処理を待ってる時は、条件変数使った方が良いみたいですが。
ググったら見つかったとこ。
ttp://www.imou.to/~AoiMoe/column/pthread/pthread_cancel.html
これは、絶対に mutex で待っちゃダメって事じゃないですよね。
0214デフォルトの名無しさん
05/01/28 03:08:46condition variableで待つ場合ロックしているmutexを一時的に
解放してくれて、かつ、signalやbroadcastで条件が調った時に
一時的に解放していたmutexを自動的にロックしてくれる。
なので、時間とかの問題ではなく、デッドロックを避けつつ、
必要な排他処理を過不足無く行なうために必要であれば、
condition variableを使うか、自前で同等の処理を行なうことに
なる。
mutexをロックしたまま別のmutex待ちをして良いのなら、
condition variableを使う必要は無い。
0215デフォルトの名無しさん
05/01/28 03:38:10どうもありがとうございます。
自分が考えていたのは、mutex が一時的に解放されてもそれほど嬉しく無さそうな
処理だったので、まずは mutex のみで実装してみようと思います。
0216デフォルトの名無しさん
05/01/30 17:49:59volavolavolavolavolavolavolavolavolavolaァァァァーー!
0217デフォルトの名無しさん
05/01/30 18:28:51マルチスレッドのときにも排他は不要ですよね?
0218デフォルトの名無しさん
05/01/30 18:31:210219デフォルトの名無しさん
05/01/30 18:35:10へ?
0220デフォルトの名無しさん
05/01/30 18:57:200221定期的にこの話題出てくるな。つりだろうか ?
05/01/30 21:11:48不要だと思うなら、そうすればいい。
後で泣きを見ても知らんけどな。
0222デフォルトの名無しさん
05/01/30 21:18:59100%煽りでしょ。
せっかくの「またvolatile厨か・・・」への前振りを無駄にするな。
0223デフォルトの名無しさん
05/01/31 11:01:300224デフォルトの名無しさん
05/01/31 19:34:430225デフォルトの名無しさん
05/01/31 23:11:21下記のページみたいな感じでmutexやクリティカルセクションを使ってロックするしかないの?
なんか重そうだけど。
http://www.athomejp.com/goldfish/mfc/cobject/thread.asp
0226デフォルトの名無しさん
05/01/31 23:41:26stringstreamの場合は工夫した方がいいと思うが。
0227デフォルトの名無しさん
05/02/02 23:23:58から重くないと思われ。
0228デフォルトの名無しさん
05/02/03 01:12:21応答性やパフォーマンスを気にするならcoutなんかやめて
非ブロッキングI/Oを使えばいい。
0229デフォルトの名無しさん
05/02/03 10:36:44>επιστημηです。
>
>で、関連事項なんすけど、スレッド間で共有する変数の類は
>Mutexなんかでガードしてないならvolatileつけとくのが無難
>なんでしょかしらやっぱ?
えぴすさんでもひっかかっちゃうのね。
0230デフォルトの名無しさん
05/02/03 12:09:18「でも」とはなんだ「でも」とは!
奴だからこそ、だろう。
0231デフォルトの名無しさん
05/02/03 12:17:260232デフォルトの名無しさん
05/02/03 12:50:58排他のためにやるわけじゃなくて、
最適化の抑止の事だけを話しているのかも知れないから。
十分って言っているわけじゃなくて、無難だしね。まあ、
>で、関連事項なんすけど、
何に関連していたかにも依るわけですが…
0233デフォルトの名無しさん
05/02/03 13:01:080234デフォルトの名無しさん
05/02/03 21:34:24> 排他のためにやるわけじゃなくて、
> 最適化の抑止の事だけを話しているのかも知れないから。
排他が関係しないスレッド間の共有って、全スレッドがreadしかしないとかそういうこと?
確かにそれなら定数読むのとかわらんから、volatileもメモリバリアもいらないけど、そういう文脈なのかなぁ。
0235デフォルトの名無しさん
05/02/04 01:21:32国内でだれかvolatileを布教してる人でもいるんですか?
0236デフォルトの名無しさん
05/02/04 05:57:040237デフォルトの名無しさん
05/02/04 06:10:36下記のページみたいな感じでmutexやクリティカルセクションを使ってロックするしかないの?
なんか重そうだけど。
http://www.athomejp.com/goldfish/mfc/cobject/thread.asp
0238デフォルトの名無しさん
05/02/04 08:26:34思い込みはどうでもいいからベンチマークとれよ
0239デフォルトの名無しさん
05/02/04 09:00:25volatileはマルチスレッド対応ですか?教えてください。
0240デフォルトの名無しさん
05/02/04 09:10:22coutをvolatileにしろ
0241デフォルトの名無しさん
05/02/04 09:23:38(スレッドが2つ以上になった時点では読込しか行わない場合)
排他処理したり、volatile修飾する必要は無いの?
0242デフォルトの名無しさん
05/02/04 09:42:47またvola (ry
えーとね、排他は必要ない。169-170の質問と実は同じ内容だから、
回答は >>192 >>195 を参照のこと。
あと、volatileはいい加減やめい。スレッドとvolatileは無関係。
0243デフォルトの名無しさん
05/02/04 20:15:080244デフォルトの名無しさん
05/02/04 22:16:440245デフォルトの名無しさん
05/02/04 22:22:00ウザい
0246デフォルトの名無しさん
05/02/04 22:26:20trueに変えたはずなのにまだfalseと読み出されたりするくらいで、
いきなりスレッドが死んだりする事は無いよね?
0247デフォルトの名無しさん
05/02/04 22:39:07お前がな。
そもそもこのスレでのvolatile発言はすべて煽り。ほいほい釣られるのはやめてくれ。
0248デフォルトの名無しさん
05/02/04 23:12:27お前がな。
そもそもこのスレでのvolatile発言はすべて煽り。ほいほい釣られるのはやめてくれ。
0249デフォルトの名無しさん
05/02/05 01:22:510250デフォルトの名無しさん
05/02/05 02:14:05volatileと宣言すれば完璧です。
0251デフォルトの名無しさん
05/02/05 02:43:570252デフォルトの名無しさん
05/02/05 15:08:47java/c#のvolatileは意味合いが違うという理解でいいのでしょうか?
普通のブラウザからなので過去スレッドに既出ならすまそ。
0253デフォルトの名無しさん
05/02/05 16:13:110254デフォルトの名無しさん
05/02/05 16:53:32c/c++の言語仕様にはマルチスレッドとvolatileとの関係なんて定義されていない。
きちんと定義されているものと未定義のものとを比較して、
意味合いが違うとかどうとか言うのは意味がない。
0255デフォルトの名無しさん
05/02/05 17:00:36while (f)
{
;
}
は最適化で
if (f)
{
for(;;) {}
}
になったりはしないの?
0256デフォルトの名無しさん
05/02/05 17:10:580257デフォルトの名無しさん
05/02/05 17:15:29ノ
コンパイル時の最適化についての話でしょう。
前者の記法は後者の記法のように変換されて解釈されるのではないか、
という質問だと思います。
0258デフォルトの名無しさん
05/02/05 17:59:55>c/c++の言語仕様にはマルチスレッドとvolatileとの関係なんて定義されていない。
ありがとう。なんかすごく腑に落ちました。
現実には独自仕様などでそれなりの関係で動いちゃう処理系が多々あるってことで
しょうね。混乱するほうが自然なような気もしてきました。
0259デフォルトの名無しさん
05/02/05 18:12:37今でも最適化でこんな間違いが生じる恐れあるのか?
0260デフォルトの名無しさん
05/02/05 18:34:22while (f) {
/* ループ中でfは参照されない */
}
こういうコードなら、それに近い最適化される
可能性もあるんじゃない?
0261デフォルトの名無しさん
05/02/05 20:40:40void f(const char *str) {
int i;
for (i = 0; i < strlen(str); ++i) {
...
}
}
なんてコードは、
慣れてる人が見れば「毎回長さを判定している糞コード」なわけだけど
VCとかだと、このstrlenをループの外に出しちゃうわけよ。
こういう最適化をするコンパイラが
ループ内で変更していない変数の値を、ループ時に毎回評価するなんてありえないわけで。
0262デフォルトの名無しさん
05/02/05 20:51:20はつみみです
0263デフォルトの名無しさん
05/02/05 21:44:43http://www.microsoft.com/japan/msdn/library/default.asp?url=/japan/msdn/library/ja/jpdncode/htm/secure10102002.asp?frame=true&hidetoc=true
0264デフォルトの名無しさん
05/02/05 23:29:58VCについては知らんが、gccだとpureアトリビュートってのを
関数に宣言してやると、そういう動作をするな。
以下、Infoより引用。
---
`pure'
Many functions have no effects except the return value and their
return value depends only on the parameters and/or global
variables. Such a function can be subject to common subexpression
elimination and loop optimization just as an arithmetic operator
would be. These functions should be declared with the attribute
`pure'.
0265デフォルトの名無しさん
05/02/05 23:43:07pureって意味わかりにくね?
C++の純粋仮想関数を想像しちまう。
Oracle PL/SQLのdeterministicの方がいいな。
0266デフォルトの名無しさん
05/02/06 00:05:45http://h18009.www1.hp.com/fortran/docs/vf-html/azsumm/rfpure.htm
http://publib.boulder.ibm.com/infocenter/macxhelp/index.jsp?topic=/com.ibm.vacpp6m.doc/language/ref/clrc07fn_attrib_pure.htm
http://documents.wolfram.com/v5/TheMathematicaBook/PrinciplesOfMathematica/FunctionalOperations/2.2.5.html
0267デフォルトの名無しさん
05/02/06 04:49:580268デフォルトの名無しさん
05/02/06 09:14:470269デフォルトの名無しさん
05/02/06 10:48:370270デフォルトの名無しさん
05/02/07 09:07:400271デフォルトの名無しさん
05/02/08 01:04:080272デフォルトの名無しさん
05/02/08 03:51:12そのことと、マルチスレッドプログラミングがどう絡むのかというと、
最適化を抑制することが、
マルチスレッドプログラミングにおいて発生する問題を解決したり、
未然に防いだりするのに有効な場合があるのです。
もちろん、volatileの使用は、起こりうる問題の全てを解決したり、
予防したりするものではありません。そとのきは、
mutexを使うなりして別の手段を用いる必要があるでしょう。
0273272
05/02/08 03:58:21そのときは の誤りです。スレを汚してごめんなさい。
0274デフォルトの名無しさん
05/02/08 04:09:370275デフォルトの名無しさん
05/02/08 04:17:120276272
05/02/08 04:46:42誤)そとのとき
正)そのとき
ではなくて、
誤)そとのき
正)そのとき
だと指摘してるのかな?
2重にスレを汚してごめんなさい。
0277デフォルトの名無しさん
05/02/08 09:24:29「場合がある」程度で使われちゃ迷惑なんだよ
つか仕組を理解していない証拠だ
0278デフォルトの名無しさん
05/02/08 09:46:400279デフォルトの名無しさん
05/02/08 10:35:50i = i++; 並みの珍説だな
0280デフォルトの名無しさん
05/02/08 11:03:11に,
One use of the volatile qualifier is to provide access to memory locations used by
asynchronous processes such as interrupt handlers.
って書いてあるんだけど...
さらには,
http://www.microsoft.com/japan/msdn/library/default.asp?url=/japan/msdn/library/ja/vclang/html/_pluslang_const_and_volatile_pointers.asp?frame=true&hidetoc=true
では,
When a name is declared as volatile, the compiler reloads the value from memory
each time it is accessed by the program.
This dramatically reduces the possible optimizations.
However, when the state of an object can change unexpectedly,
t is the only way to ensure predictable program performance.
とあります.
少なくともVC++の場合は(気をつければ)volatile使うのもありなのでは?
もちろん,C++の規格上は,マルチスレッドとvolatileの関係なんか何も定められていないと思うけど.
親の敵がごとくvolatileを嫌っている理由を知りたいです.
0281デフォルトの名無しさん
05/02/08 11:31:05volatileは何の解決にもならないんだよ。
volatileで解決したように見えるものを別のところに持っていって正しく
動く保証は全くない。
自説に固執する前にちっとは勉強したらどうよ。
0282デフォルトの名無しさん
05/02/08 11:43:37他の環境でも正常に動作するとは限らないというのは全く同意です.
正直にいうと,マルチスレッドプログラミングはWindows上でしか
経験がありません.それで,
>> 自説に固執する前にちっとは勉強したらどうよ。
自説に固執しているつもりもありませんが,
勉強する意欲はありますので,よろしければ,
>> volatileは何の解決にもならないんだよ。
ということを学習できる書籍,URLなどをご紹介ください.
英語でもかまいません.
0283デフォルトの名無しさん
05/02/08 12:04:03Atomic じゃない処理でアクセスしてるなら、気休めにもならんぞ。
0284デフォルトの名無しさん
05/02/08 12:26:35> Memory Mapped I/O 以外に volatile を使う必然性が解らん…
> Atomic じゃない処理でアクセスしてるなら、気休めにもならんぞ。
cppllの受け売り?mmapでもvolatileはまずい。
0285デフォルトの名無しさん
05/02/08 12:27:18例えば,
bool 型の変数(初期値false)があって,ある一つのスレッドが,
その値をtrueに変更し,他のスレッドは,その変数の値が
trueになるのを待ち構えている...的な状況に使っています.
同期オブジェクト使えばいいじゃん.と思われるかもしれませんが,
例えば,上のbool型の変数がグローバル変数であった場合,
単純に同期オブジェクトに置き換えることも出来ません.
初期化の問題もあるし,それをクリアしてもリソースをいつ
OSに返せばいいかという問題もあります.
より具体的には,
http://www-6.ibm.com/jp/developerworks/java/040416/j_j-jtp02244.html
の後半にある,
「リスト1. volatileフィールドを「見張り」変数として使う」
的な利用の仕方をしています.
上記サイトは言語がjavaですし,古いjavaのメモリ・モデルでは,
最適化のリオーダの定義が甘く,うまく動かないと結論づけらているので,
あんまり適切なソースではありませんが,私が提示できるのはこれくらいです.
0286デフォルトの名無しさん
05/02/08 12:27:56such as interrupt handlers.
でしょ?MSもスレッドとの相互作用は言及していないやん。
0287デフォルトの名無しさん
05/02/08 12:28:370288デフォルトの名無しさん
05/02/08 12:29:36>bool 型の変数(初期値false)があって,ある一つのスレッドが,
>その値をtrueに変更し,他のスレッドは,その変数の値が
>trueになるのを待ち構えている...的な状況に使っています.
残念ながらダメな使用例の典型です。
http://www.aristeia.com/Papers/DDJ_Jul_Aug_2004_revised.pdf
0289デフォルトの名無しさん
05/02/08 12:36:01>>285
変数の操作前後に同期オブジェクト使用。
0290デフォルトの名無しさん
05/02/08 12:42:43> 例えば,
> bool 型の変数(初期値false)があって,ある一つのスレッドが,
> その値をtrueに変更し,他のスレッドは,その変数の値が
> trueになるのを待ち構えている...的な状況に使っています.
バカの典型例。
> 同期オブジェクト使えばいいじゃん.と思われるかもしれませんが,
いいじゃん、じゃなくてそれが正しい解。
> 例えば,上のbool型の変数がグローバル変数であった場合,
> 単純に同期オブジェクトに置き換えることも出来ません.
> 初期化の問題もあるし,それをクリアしてもリソースをいつ
> OSに返せばいいかという問題もあります.
単なる言い訳。
0291デフォルトの名無しさん
05/02/08 12:51:18cppll ってのが何か知らんが、Mapped Memory の話なぞしていない。
メモリ空間に配置された I/O ポートの話。
>>285
うむ。最悪な用途だな。
>同期オブジェクト使えばいいじゃん.と思われるかもしれませんが,
使えばいいじゃん。
0292285
05/02/08 12:54:04ソースの提示ありがとうございます.
早速読んでみます.
> 残念ながらダメな使用例の典型です。
でも,ちょっとショックです.
285の使用例を許すOS自体が存在しないということなら,さらにショック.
0293デフォルトの名無しさん
05/02/08 13:02:24> でも,ちょっとショックです.
> 285の使用例を許すOS自体が存在しないということなら,さらにショック.
OSっつーかハードウェアとコンパイラね。
(1)シングルコアのシングルCPUの上でしか動かさないプログラムか、
マルチプロセッサだけど強いmemory consistencyを持つハードウェア上でしか動かさないプログラムで、
かつ、
(2)コンパイラの最適化の特徴を完璧に把握している
場合のみboolをロックなしで使用してよし。実質的に常人には判断不可能とおもうが。
特に(2)はコンパイラの作者でもなければわからない悪寒。
0294285
05/02/08 13:21:24解説ありがとうございます.
pdf,まだ読んでませんが,困難さが伝わってきました.
285のような場合は,Windowsの場合ですと,
boolをlongにして,InterlockedExchangeみたいな
API を使っても無駄なあがきでしょうか?
0295デフォルトの名無しさん
05/02/08 13:30:570296デフォルトの名無しさん
05/02/08 13:40:08ビジーループだったりすると、volatile 以前の問題だったり。
0297デフォルトの名無しさん
05/02/08 13:47:42http://msdn.microsoft.com/library/en-us/dllproc/base/interlockedexchange.asp
などをみると、This function generates a full memory barrier (or fence) and performs ... とかなんとか
説明がある。この意味が分からないなら手を出さない方がいい。
0298デフォルトの名無しさん
05/02/08 13:51:53InterlockedXXXはもちろんOKでそ。
基本的にはマルチプロセッサを考えない場合にはスレッド間でのメモリ内容の
同期化は考えなくても良いので、volatile とか _ReadWriteBarriar (VCね)とかで
テキトーに済ませてしまっても問題ない。
でも今時「マルチプロセッサではデッドロック起こします」なんてプログラムは
書かないことが多いんでは?なので他のスレッドが書いたデータを読むとき
には、適当にメモリバリアになる処理を入れておくべき(ドライバ書いているとき
には、リングバッファ - メモリモデルの問題さえなければ、writerとreaderは
並行して動作しうる - とかではまることがある)。
あとJava VMの場合は新し目のJSR-000133 に準拠したものだと、
同じvolatile変数へアクセスするコンテキスト間ではアクセス時点で同期化が
成されるみたいだけど、これはまだ一般的じゃないと思う。
0299デフォルトの名無しさん
05/02/08 13:56:34コンパイラの最適化によるトラブル@シングルプロセッサは無視ですか?
0300デフォルトの名無しさん
05/02/08 15:44:470301デフォルトの名無しさん
05/02/08 15:54:06お前が意味不明。
0302デフォルトの名無しさん
05/02/08 16:26:36そのためのvolatileでしょうが。
#って書くとまたvolatile厨云々書く香具師が沸くのかな?
0303デフォルトの名無しさん
05/02/08 16:28:15既出の、
Javaの場合普通JSR-133を仮定しないで同期化でメモリバリアするから問題起きない。
サーバ側などVM限定で良くて高速処理が必要なら、JSR-133を仮定して高速な実装を使うこともアリ。
C/C++ならvolatile とかVCの_ReadWriteBarrier(>>298ではスペルミスしてました)みたいなものでテキトーに。
(インラインでアセンブラ書ける処理系なら、大抵はメモリへの配置と値のストアを強制できると思う)
参考:http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclang/html/vclrf_ReadWriteBarrier.asp
ってようなことの他に何か最適化によるトラブルがあったら教えてください。
0304デフォルトの名無しさん
05/02/08 16:53:58外から参照できるような変数がレジスタに割り付けられるような
間抜けなコンパイラが存在するんですか?そりゃすげぇや。
0305デフォルトの名無しさん
05/02/08 16:56:01ごく普通にある。例:GCC
0306デフォルトの名無しさん
05/02/08 17:01:12C/C++ではvolatileでメモリへの割付は強制できるけど、Javaとは違って当該のメモリ位置に
何時データを書き出すかまでは指定できない(読み出しは字面上の位置でメモリから読むこと、
と規定されてるけど)。
んだからさんざ既出の様に「VCの_ReadWriteBarrierみたいなもの」を併用する必要があるわけ。
gccでもvolatile変数に代入した後インラインアセンブラでちょいと参照しておけばOKなんじゃない?
(でもgccってgasにした後で最適化入るんだったような記憶が・・・それだとダメか?)
0307294
05/02/08 18:15:35実は,Javaにおけるクラスレベルのロック機能みたいなのを実現したいと思っているのです(とりあえずはWindowsで,言語はC++).
クラスレベルのロックをするための同期オブジェクトは,初期化と後始末の問題があるため単純に静的な変数に出来ません.
また,クラスレベルのロックをするための同期オブジェクトの生成過程もロックしないといけませんし,
それをするのにmutexなどの同期オブジェクトを作っていたのでは,またそのオブジェクトの生成過程をロックしなければいけなくなってきりがないのです.
そこで,volatileと,Interlock系のAPIを使用してクラスレベルのロックをするための同期オブジェクトの生成過程をロックすればよいんでは?
と思いプログラミングしてみたところ,見た目は動いてるっぽいです.
ただ,動作確認をしているマシンが1CPUですので,まだまだ,勉強が必要です.
とりあえずは,今回提示されたpdfを読んでみようと思います.
勉強になりました.ありがとうございました.
0308デフォルトの名無しさん
05/02/08 18:17:32いや、だからね、
> 同期化は考えなくても良いので、volatile とか _ReadWriteBarriar (VCね)とかで
> テキトーに済ませてしまっても問題ない。
「volatileとか」は余計だろ?
メモリバリアを正しく使ったなら無問題だよ。
0309デフォルトの名無しさん
05/02/08 18:20:05> gccでもvolatile変数に代入した後インラインアセンブラでちょいと参照しておけばOKなんじゃない?
参照っていうか、fence命令を挿入だな。Linuxカーネルなんかに_ReadWriteBarriar相当の
マクロなんかがあるから参考にすればいい。
0310デフォルトの名無しさん
05/02/08 18:23:28> そのためのvolatileでしょうが。
全然違う。
volatileによって、
変数の領域が最適化によってレジスタに作られた場合、*自スレッドが* これを参照することの影響を排除すること
はできるが。
0311デフォルトの名無しさん
05/02/08 18:26:53> Atomic じゃない処理でアクセスしてるなら、気休めにもならんぞ。
アトミックかどうかは関係ないでしょう
0312294
05/02/08 18:33:50http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclang/html/_langref_volatile.asp
に,
The volatile keyword is a type qualifier used to declare that an object can be modified in the program by something such as the operating system, the hardware, or a concurrently executing thread.
ってありました.
0313デフォルトの名無しさん
05/02/08 18:38:00308で言ってることは正しい指摘だと思うんだけど、それはともかくとして
>>298
>コンパイラの最適化によるトラブル@シングルプロセッサは無視ですか?
これの例を聞いてみたわけだけど。エイリアス関係ならvolatile指定でOKだし・・・
0314デフォルトの名無しさん
05/02/08 18:42:26IA32の強めの一貫性を仮定しているんだろうね
0316デフォルトの名無しさん
05/02/08 18:46:13俺に聞かれても困るんだけど・・
volatileはvolatileで修飾した変数Vをレジスタに置かないことは保証するが、V
にアクセスする順序(Vにアクセスしたことが他CPUからみえるようになるタイミ
ング)までは制限しない
ということじゃないの?それ以上はEffectiveC++の作者様にでも聞いてくれろ
0317デフォルトの名無しさん
05/02/08 19:33:10これまた微妙な表現・・・
0318デフォルトの名無しさん
05/02/08 19:46:18参照する場合には、ってことだよね・・・
あと他人の質問に一旦返事しといて、再度聞かれると
「俺に聞かれても困るんだけど・・ 」は反則じゃねーの。
0319デフォルトの名無しさん
05/02/08 20:05:39「このスレッドの人はJSR-133も知らないのか」と思っていたが、みんな
知ってて遊んでたのね。人が悪い。
0320デフォルトの名無しさん
05/02/08 20:24:59全員Cの話をしているものだとばっかり。
0322デフォルトの名無しさん
05/02/08 20:58:06WindowsにゃPTHREAD_MUTEX_INITIALIZERみたいなのがないからなぁ。
苦労するのはよくわかる。まぁ、、現実にはみなテキトーにやってるわけだがw
0323デフォルトの名無しさん
05/02/08 21:13:21漏れはヘルパクラスを作って静的変数(classのstaticメンバにすることが多い)の
コンストラクタとデストラクタでやってます。
複数のスレッドから、DLL等ダイナミックにローディングされるような状況(COM等)ではそれだと
上手くないので、DLL_PROCESS_ATTACH のタイミングでCRITICAL_SECTIONを初期化し、
開放はしないという方針(DLL_PROCESS_DETACHでDeleteCriticalSectionはGPF出ることがある)。
Mutex使えば簡単なんだけど、重いからなぁ・・・
0324デフォルトの名無しさん
05/02/08 21:20:20初期化順の問題がおきそうですね。
あと、Windowsってmain関数が走る前にマルチスレッド状態ってことはあるんですか?
0325デフォルトの名無しさん
05/02/08 21:29:56初期化順の問題が出てくるようなコードの場合には、DllMainで処理するより他ないでしょうね。
>あと、Windowsってmain関数が走る前にマルチスレッド状態ってことはあるんですか?
そういうプログラムを作るか、他プロセスからフック等で介入するかすれば。
0326デフォルトの名無しさん
05/02/08 22:11:010327デフォルトの名無しさん
05/02/08 22:37:220328デフォルトの名無しさん
05/02/08 22:54:02ば、ばかな。
0329デフォルトの名無しさん
05/02/09 00:05:46されたアプリを動かしたとき、そのアプリ内でたてるスレッドって
それぞれ別CPUが処理してくれるのでしょうか?
いや、単純にスレッドをCPU分作れば複数枚のCPUパワーを
フルに使えるのか、それともシングルスレッドのアプリを複数
プロセス立ち上げた方がいいのかってところなんですが。
もちろん完全並列処理が可能だという前提で。
0330デフォルトの名無しさん
05/02/09 00:12:360331デフォルトの名無しさん
05/02/09 00:20:29SunのJREとSolaris/Linux/Windowsなら基本的にはその通り。
並列度がどれくらい効くかはOS自身の成熟度にもよるけど。
あとはプロセスを別個に作るとかなりメモリが無駄に重複して
消費されるだろうとかGC的には逆に並列でスレッドが沢山走って
でかいプロセスだと負担がどうだろうとかその他のリソースの
制約はどうだろうとかあるけど。
0332PHP
05/02/09 01:46:55どうしたらいいんでしょうか?
真剣にだれか教えてください
0333デフォルトの名無しさん
05/02/09 01:51:03WebProg板でやれよ
0334329
05/02/09 02:02:18なんスレッドくらいがよいのか試してみます。
0335デフォルトの名無しさん
05/02/09 10:11:01こっちだろ
http://www.divakk.co.jp/blog/aoyagi/archive/2004/07/16/546.aspx
0336307
05/02/09 10:34:15内容をちょっとだけ紹介します.
Singletonクラスのインターフェースが次のように定義されていたとします.
class Singleton {
public:
static Singleton* instance();
...
private:
static Singleton* pInstance;
};
本当はいろいろな場合わけがなされているのですが,ここでは,
Double-Checked Locking Pattern(DCLP)としてのinstanceメソッドの(まずい)実装例を取り上げてみます.
Singleton* Singleton::instance() {
if (pInstance == 0) { // 1st test
Lock lock;
if (pInstance == 0) { // 2nd test
pInstance = new Singleton;
}
}
return pInstance;
}
これが何故まずいのかというと,
pInstance = new Singleton;
この一文がアトミックに行えないことにその原因があります.
【次へつづく】
0337307
05/02/09 10:35:37Singleton* Singleton::instance() {
if (pInstance == 0) {
Lock lock;
if (pInstance == 0) {
pInstance = // Step 3
operator new(sizeof(Singleton)); // Step 1
new (pInstance) Singleton; // Step 2
}
}
return pInstance;
}
で,どんな問題が起きるかというと,
1.Step2のコンストラクタが例外を投げた場合,pInstanceにはoperator newでアロケートした領域のアドレスが代入されたままになります.
さらに,コンストラクタが例外を投げたときは,operator deleteが呼ばれてしまうので,pInstanceにはフリーストアに戻ってしまった記憶領域のアドレスが保持されていることになります.
2.Thread Aがinstanceの中に入ってif文を通過しロックを取得し,Step3とStep1 を実行したとします.そしてThread Aがサスペンドしたとします.
pInstanceにはnullではないポインターが保持されていますが,コンストラクタはコールされていません.
この状態でThread Bがinstanceの中に入ってきた場合,pInstanceはnon-nullですから,そのまま,pInstanceの値をリターンしてしまいます.
何度もいうようですがコンストラクタはコールされていません.
正直,ここまで考えるか!と感心してしまいます.しかもこんなのが連続します.
Singletonクラスを設計するときにはとても役立ちそうです.
ありがとうございました.
0338307(いまさらだけど)
05/02/09 10:52:18で 285 的なvolatileの使用例があります.上記urlでは,最初に問題のあるコーディング例として,
class Gadget
{
public:
void Wait()
{
while (!flag_)
{
Sleep(1000); // sleeps for 1000 milliseconds
}
}
void Wakeup()
{
flag_ = true;
}
...
private:
bool flag_;
};
というコードが記述されています.そして,
So all you have to do to make Gadget's Wait/Wakeup combo work is to qualify flag_ appropriately:
class Gadget
{
public:
... as above ...
private:
volatile bool flag_;
};
と,問題点が修正されます.でも,CPUが複数個の場合は,環境依存ということになりそうですね.
0339デフォルトの名無しさん
05/02/09 11:14:00フラグをヒントにするくらいなら問題ないんじゃね?
終われそうなら終わってくれって程度で。
0340デフォルトの名無しさん
05/02/09 11:59:08仮にメモリの内容の同期が遅れてループが多少何回か多めに回転しても,この場合は無問題ですね.
0341デフォルトの名無しさん
05/02/09 14:32:29いいかもね。
俺のチームからはクビにするけど。
0342デフォルトの名無しさん
05/02/09 14:37:16お前のチームで一緒にやりたくねーよwwww
0343デフォルトの名無しさん
05/02/09 14:40:03>>250さんが言っているように
volatileにしとけば完璧ですか?
0344デフォルトの名無しさん
05/02/09 14:45:03そうだ。その通りだ。わかったらクソして寝てろ。
0345デフォルトの名無しさん
05/02/09 15:04:29温めるの
0346デフォルトの名無しさん
05/02/09 15:09:08そうだ。その通りだ。わかったらクソして寝てろ。
0347デフォルトの名無しさん
05/02/09 19:09:540348デフォルトの名無しさん
05/02/09 19:22:33そうだ。その通りだ。わ(ry
0349デフォルトの名無しさん
05/02/09 21:15:19wの多さは知能の低さ
>343
スレッドが死んだりすることはない。volatileで他スレッドの変更を
いつの日か読めるかどうかは環境依存。何度もいうが規格で規定され
ていない(C++)か未定義とされている(POSIX)ことに結論を求めては
いけない。ロック汁。
まぁ釣りなんだろうけどクマー
0350デフォルトの名無しさん
05/02/09 21:35:52Javaは?
0351339
05/02/09 21:57:17規格厨ですか?
Sleep()で寝てもいるのにvolatileなフラグの変更を
いつまで経っても読み取れない処理系挙げてみろよ。
なんでヒントって書いたかわかってないだろ?
0352デフォルトの名無しさん
05/02/09 21:58:140353デフォルトの名無しさん
05/02/09 22:08:34> なんでヒントって書いたかわかってないだろ?
なんで条件変数とかEventオブジェクト使わないの?
0354デフォルトの名無しさん
05/02/09 22:09:25JSR厨の光臨を待て!
0355デフォルトの名無しさん
05/02/09 22:10:22己の無知を棚に上げて人を規格厨呼ばわりするのはやめておけ。
0357デフォルトの名無しさん
05/02/09 22:23:530358351
05/02/09 22:28:14想定したのはProducer/ConsumerのConsumer側スレッドプールの
スレッド数を縮小させる場合などで、ターゲットのスレッドに対して
適当なタイミングで終了させるフラグを実装するような場合。
キューから引っ張ってきたタスクを実行中に止められるはずもなく、
その次のループで確実に終了する必要もない。
この条件でもフラグ見るのに絶対に同期する必要がある?
0359デフォルトの名無しさん
05/02/09 22:28:49池沼が根拠の無い嘘を書き散らす場所でないことだけは確か
0360デフォルトの名無しさん
05/02/09 22:37:30誰かに問題ない!と言ってもらいたいんだろうな。
OSとCPUとコンパイラくらい書けばいいのに。
0361デフォルトの名無しさん
05/02/09 22:54:050362351
05/02/09 22:59:12同期しときゃ済む話だし、省いたところでパフォーマンスが特に
上がるわけでもないからどうでもいい。
だけど、更新のある変数を扱う時は*絶*対*に*同期しなきゃ
いけないような論調になってるのが気に食わなかっただけ。
普通はフラグだけで完結するようなものはなくて、厳密な整合性を
必要とする操作のところで同期取ってるはずだから、結局はそこが
Memory Synchronizationになってるから問題ないでしょ?ってことさ。
だから問題がある処理系があるなら、それを挙げろ、と。
0363デフォルトの名無しさん
05/02/09 23:09:31お前がコード貼って、みんなの環境でコンパイルして逆汗して、それをメモリモデルを考慮しながら検証するしかないだろうな。
俺は嫌だけど。
0364デフォルトの名無しさん
05/02/10 00:37:25> volatileで他スレッドの変更を
> いつの日か読めるかどうかは環境依存。
1 thread内なら、sequence pointは越えないんだけどね。
http://www.redhat.com/docs/manuals/enterprise/RHEL-3-Manual/gcc/volatiles.html
0365デフォルトの名無しさん
05/02/10 00:37:57C/C++なら、プログラミング言語の処理系レベルの問題ではなく、
アーキテクチャレベルの問題なんだが、それがわかってないようだな。
0366デフォルトの名無しさん
05/02/10 00:42:17バカはこれだから困る。
0367デフォルトの名無しさん
05/02/10 00:53:34変数が扱えなくてリンゴとミカンでしか考えられない小学生みたいですね。
0368デフォルトの名無しさん
05/02/10 00:56:24おまいさんの質問に対して、もう二度も例が挙がってる。
それに気付いてない時点で、無知を曝け出しているのだよ。
0369デフォルトの名無しさん
05/02/10 01:54:59// 初期値はともに0とする。
volatile int a = 0;
volatile int b = 0;
int threadA() {
int x;
a = 1;
x = b;
return x;
}
int threadB() {
int x;
b = 1;
x = a;
return x;
}
0370369
05/02/10 01:55:31SMP構成のPentium4マシン(HT機能はoff)上で
threadA(), threadB()をそれぞれ別スレッドから同時に呼び出したとする。
このとき「threadA()とthreadB()がともに0を返す」ようなことが起こり得るか?
起こり得る(起こり得ない)なら、その理由は?
次に、同じプログラムをUP構成だがHT機能を有効にしたPentium4マシンで
動かした場合はどうなるか?
# とりあえず、C/C++コンパイラはgcc 3.xとする。
# (VCでも同じ答えになるはずだが。)
0371デフォルトの名無しさん
05/02/10 02:03:470372デフォルトの名無しさん
05/02/10 02:08:20>>369はvolatileかどうかに関わらず、どちらが先に実行されるかって問題だけな気がする。
volatileがマルチスレッドに使えるとしている人たちの論拠は、緩やかな同期を取る話であって、
>369みたいなクリティカルな実行順序まで期待しての話じゃないと思うのだけど。
#わーい、自分でも何が言いたいのか判らんぞ
0373デフォルトの名無しさん
05/02/10 02:20:37ハァ?バカか?
んなもん存在しねーよ。
これだからバカは困る。
0374デフォルトの名無しさん
05/02/10 02:32:310375デフォルトの名無しさん
05/02/10 02:35:01消えろ。
0376デフォルトの名無しさん
05/02/10 06:34:07ものだと思ってるってことになっちゃってない?
0377デフォルトの名無しさん
05/02/10 07:59:02そういうレベルの話はとっくに片付いてる。
雑音も多いけど珍しくまともな議論になっていると思うよ。
0378デフォルトの名無しさん
05/02/10 09:17:320379デフォルトの名無しさん
05/02/10 09:22:31volatileで修飾されいるとき、
変数の宣言とreturn文の間の2文の実行順序って気まぐれに変化するんだっけ?
何気に回答になっていなくてすまん。
0380デフォルトの名無しさん
05/02/10 10:58:560381デフォルトの名無しさん
05/02/10 11:22:15ここはコンパイラももってないリア工房のスレだったのか。
0382デフォルトの名無しさん
05/02/10 11:25:020383デフォルトの名無しさん
05/02/10 11:28:54誰もが皆、一瞬つけてみたくなる発想のレスです♪
しかし、賢明な人はその自らの短絡的思考を野放しにする事を嫌がり、
こういうレスは控えます♪しかし、この人はしてしまったのです(^^;
「誰もが思い付くような事」を堂々と♪
この人にとってこのレスは何なのでしょうか♪
このレスをしている間にも時間は刻々と 過ぎ去っているのです♪
正にこの人のした事は「無意味」「無駄」でしかありません♪ああ・・・何ていう事でしょう(^^;ワラ
図星で泣いちゃうかも(^^;ワラ
0384351
05/02/10 11:31:51今のところ、Singletonで確実に一度しか実行されないことを保証するのに
volatileでは解決にならない、ってことは結論出てるけど、決定的な一貫性を
必要としない、falseがtrueに変化するだけのフラグに使用することに関しては
まだ話題に上がってないと思うんだけど。
0385デフォルトの名無しさん
05/02/10 11:36:25threadの書き方もしらねーじゃねーの( ´,_ゝ`)
VBかDelphiでスレッドかいてるのがバレバレ
0386デフォルトの名無しさん
05/02/10 12:11:59実行される順序は保証されないんじゃないかなー。
Pen4のOoOの仕様についての質問なら多少スレ違いじゃないか?
0387デフォルトの名無しさん
05/02/10 12:15:23漏れ手元に環境ないからわからないんだけど、IA64でスレッド/CPUの対応を
固定にして実行させると、単に参照している側は永遠にキャッシュから幸せに
falseを読み出し続けるような気がする。
もちろんSleep(100)の間に、他スレッド・プロセスの実行によってキャッシュが
無効になる可能性は十分あるけど。
0388デフォルトの名無しさん
05/02/10 12:16:360389デフォルトの名無しさん
05/02/10 12:31:28こういう負け惜しみ言うやつって
仕事じゃ使えないんだよな
0390デフォルトの名無しさん
05/02/10 13:36:17キャッシュの影響でスレッド間で同期が取れない状況というのは
Pentium4のHTでも起きるのでしょうか?物理的には1CPUだから無理なのでしょうか?
0391351
05/02/10 19:49:51Coherent Cacheだから無問題。
一貫性が崩れるのは他のCPUに伝わるまでのわずかな時間だけ。
さすがにそうじゃないアーキテクチャの場合(あるのか知らないけど)は
重要な前提が崩れるわけで、他でも悲惨なことになるんだろうね。
>もちろんSleep(100)の間に、他スレッド・プロセスの実行によってキャッシュが
>無効になる可能性は十分あるけど。
これは十分というより確実にあるでしょ。CPUがスレッド数より多く、さらに
その場合はOS側でコンテキストスイッチを行わないような実装になって
いればありえるかもしれないけど、そんなの現実的じゃないし。
で、SingletonのDCLの場合は、ひらたく言えば、ある変数の読み取りと
書き込み(+比較)を、必ずしも同期なしでAtomicに行うことができるか?
という命題と捉えていいと思う。
今のフラグの話題に戻ると、DCL問題ほど制約は厳しくなくて、読み取る
タイミングは必ずしも正確である必要はなく、書き込み側では読み取りは
一切無く、1ビット(Cだと1ビットでも立ってればtrue扱い)の書き込みのみ。
Reorderされようが、最終的に1ビット立ってりゃいいだけってこと。
volatileがなければ、ループ前に最適化でレジスタにキャッシュされて、
そのまま永遠に回し続けられる可能性も否定できなくなる。
これでも*絶*対*に*同期しなきゃいけないんだろうか?
0392デフォルトの名無しさん
05/02/10 21:56:550393デフォルトの名無しさん
05/02/10 23:37:130394デフォルトの名無しさん
05/02/10 23:52:48>>392 はそこいらじゅう同期オブジェクトだらけのプログラムでも作ってるのでしょうか?
0395デフォルトの名無しさん
05/02/11 09:05:15出るような場面だけマルチスレッドにすればいいんだよな?
0396デフォルトの名無しさん
05/02/11 09:59:350397デフォルトの名無しさん
05/02/11 11:14:01同期できてないんじゃないか?なんか出力がおかしいぞ。
0398デフォルトの名無しさん
05/02/11 11:21:480399デフォルトの名無しさん
05/02/11 11:26:59おもしろい。というのはさておき、
>>391
Windowsしかも1CPUの環境でしか、マルチスレッドプログラミングしたことないヘタレだけど、
>>338 的なことはフツーにやってんだけど、やっちゃいけないことってされてたの?
危ない橋を渡ってたんだろうか?
オレは単純だから>>338 みたいなコードが無限ループみたいになるんだったら、volatileの存在意義なんてないって思ってたんだけど...
間違い?(とされてたのか?)
だれかホントのことを教えてくれ。むちゃくちゃ気になる。
0400デフォルトの名無しさん
05/02/11 11:34:51もっぺんスレを最初から読め
0401デフォルトの名無しさん
05/02/11 11:54:39ところで,338>>で既出の
http://www.cuj.com/documents/s=7998/cujcexp1902alexandr/
ってC/C++ Users Journalなのな。しかも書いてる人がAndrei Alexandrescu !
ヘタレなおれには心強い
とにかく最初から読んでみるよ
0402369
05/02/11 12:22:17「OoOだから保証されない」じゃちょっと不十分かな。
「どういうメモリ操作が」OoOで実行されるかってことまで突っ込んで欲しかった。
>369のコードで「threadA()とthreadB()がともに0を返すことが起こり得ない」ためには
どういうmemory orderingが要求されるか、ってのは重要。
あるアーキテクチャでは、Double-Checked Lockingは正しく動作するが
Dekker's Algorithmは動かない、それは何故か。なんて話にも繋がる。
少なくともこの程度は意識できていないと、規格厨には対抗できんぞ。
0403デフォルトの名無しさん
05/02/11 12:34:30ググってみたが関係しそうなのが見つからなかったっす。
0404ジャムおじさん
05/02/11 12:38:410405デフォルトの名無しさん
05/02/11 12:41:21クイズに当たると最高100万円等が正解者全員に当たる!
1問コース 小物、アクセサリー 2問 鞄、雑貨、
3問 指輪、アウトドア 5問 商品券、家電、食品
6問、ゲームボーイアドバンス、折りたたみ自転車等
10問 PS2、2万円、サイバーショット、GQ、ブランド物等
15問 10万円、VAIO U、ビデオカメラ
20問 30万円、VAIO QR、VAIO W 25問 100万円
0407デフォルトの名無しさん
05/02/11 12:46:44雑音はおいといて、Out of Orderの略。
0408デフォルトの名無しさん
05/02/11 13:16:190409デフォルトの名無しさん
05/02/11 13:25:520410デフォルトの名無しさん
05/02/11 13:41:08当初は、>>338のようなコードはダメの典型(必ず同期を取る必要がある)とされてきたけど、
今は、>>339, >>340のいうような緩やかな同期というか成り行き任せの同期が
許される状況では >>338 のようなコードも選択肢のうちに入れてよいのでは?
ってことになってるってことでOK?
そして、C/C++ Users Journalの記事に反論できる猛者の出現を待っていると...
0411デフォルトの名無しさん
05/02/11 13:41:58write → readがout of order実行されるとダメってことですかね。
例えばIA32だとこういう操作がout of order実行される、とかってどこかに書いてあるの?
0412デフォルトの名無しさん
05/02/11 13:45:25> 今は、>>339, >>340のいうような緩やかな同期というか成り行き任せの同期が
> 許される状況では >>338 のようなコードも選択肢のうちに入れてよいのでは?
同期というより、なおかつ変更があった直後に気付くという保証が不要で、
そのうち気がつけばいいやという程度なら、ですね。
0413デフォルトの名無しさん
05/02/11 13:46:13○変更があった後の最初のチェックで気付く
0415410
05/02/11 14:23:00「何で同期しないんだ!」ってことになってたからおかしくなってたんだ...
0416410
05/02/11 14:26:51もちろん、同期を必要としない状況下で同期しても害はないね。
0417デフォルトの名無しさん
05/02/11 14:41:03チラシの裏にでも書いてろ
0418デフォルトの名無しさん
05/02/11 15:15:09いまここに必要とされている人は、C/C++ Users Journalの記事に対して反論できるほどの識者であり、
もはや,あなたのようにノイズを撒き散らすだけがとりえの人間の居場所はありません。
より正確には、あなたの存在自体がノイズです。
ノイズはノイズらしく消えてください。
0419デフォルトの名無しさん
05/02/11 15:35:120420デフォルトの名無しさん
05/02/11 15:46:400421デフォルトの名無しさん
05/02/11 16:07:52もう更けるのかよ!
北極圏にお住まいなのかよ!
0422デフォルトの名無しさん
05/02/11 16:24:042ちゃんねるの議論の無限ループ化は防げません。
ってことでOK?
0423デフォルトの名無しさん
05/02/11 17:20:450424デフォルトの名無しさん
05/02/11 17:28:380425デフォルトの名無しさん
05/02/11 23:59:130426デフォルトの名無しさん
05/02/12 00:50:39でも立てるか
0427デフォルトの名無しさん
05/02/12 03:55:280428デフォルトの名無しさん
05/02/12 07:09:050429デフォルトの名無しさん
05/02/12 11:26:060430デフォルトの名無しさん
05/02/12 11:28:590431デフォルトの名無しさん
05/02/12 14:31:29セマフォの記述として、適切なものはどれか。
ア P操作待ちのタスクはキューで管理される。
イ V操作待ちのタスクはキューで管理される。
ウ デッドロックの心配がない排他制御の手段である。
エ 排他制御の目的以外には使用できない。
(平成10年度 ES 午後 問32)
正解がアかイかでちょっとだけ揉めています。どちらが正しいと思いますか?
0432デフォルトの名無しさん
05/02/12 15:43:04調べりゃ分かるが、確保するのがPで返却がV
queue使うのはP操作待ちの方だな
0433デフォルトの名無しさん
05/02/12 17:30:11それにしてもあまり出来のいい問題じゃないと思うなあ。
0434デフォルトの名無しさん
05/02/12 18:33:520435デフォルトの名無しさん
05/02/12 18:48:350436デフォルトの名無しさん
05/02/12 19:13:250437デフォルトの名無しさん
05/02/12 20:28:19||ヽn/|, --- 、
|i/^r ヘ、
く, '/彡 (ノノ))))i| 待ちタスク管理したいな
|N ミ| | ┃ ┃ | |
| lヽ| | ''' ヮ''ノi | ______
| | ⊂}|i † i|{つロ / ロ ロ ロ /
Vy と.l_/_|_j_〉 / ロ ロ ロ /
 ̄ ̄ ̄ ̄ ̄ ̄
0438デフォルトの名無しさん
05/02/12 21:53:490439369
05/02/13 02:28:27> 例えばIA32だとこういう操作がout of order実行される、とかってどこかに書いてあるの?
そりゃ、"IA-32 Intel Architecture Software Developer's Manual"で決まりでしょ。
ttp://www.intel.com/design/pentium4/manuals/index_new.htm
とりあえず、Volume 3の"7.2. MEMORY ORDERING"以降は必読。
0440411
05/02/13 03:06:40見たはずなのに気づいてなかった。
とりあえず読んでみます。
0441デフォルトの名無しさん
05/02/13 09:00:34お前は知識は申し分ないが、日本語の能力に問題がある。
0442デフォルトの名無しさん
05/02/13 14:58:10Singleton* Singleton::instance() {
if (pInstance == 0) {
Lock lock1;
if (pInstance == 0) {
Singletom* volatile temp;
{
Lock lock2;
temp = new Singleton;
}
pInstance = temp;
}
}
return pInstance;
}
上のコードは、Lockの確保/解放をまたいでコードが移動しないことを前提としています。
Lockの用途を考えるとLockの外側にコードが移動することはないと思いますが、
Lockの内側にコードが移動することがあるのかどうかが不明です。
0444デフォルトの名無しさん
05/02/13 23:48:02> 上のコードは、Lockの確保/解放をまたいでコードが移動しないことを前提としています。
> Lockの用途を考えるとLockの外側にコードが移動することはないと思いますが、
それって言えるの? 少なくともセマンティクス上はロックだなんてコンパイラは
関知しないから普通にありえるんじゃないの?
> Lockの内側にコードが移動することがあるのかどうかが不明です。
lockだと認識してもありえるんじゃないの?
Javaのsynchronizedもこれはありえたと思う。
0445442
05/02/14 01:23:47> それって言えるの? 少なくともセマンティクス上はロックだなんてコンパイラは
> 関知しないから普通にありえるんじゃないの?
確かにそうなんですが、これが保証されてないとロックは使い物になりません。
コンパイラを限定するか、普通のコンパイラであれば問題ないように
実装されているのだと想像しますが、ライブラリのスペックとして
どのように決まっているのかを知りたかったのです。
> Javaのsynchronizedもこれはありえたと思う。
おっしゃるとおり、Javaではありです。
C/C++(あるいはC上でのライブラリ)ではどうなのか、ということです。
0446デフォルトの名無しさん
05/02/14 06:21:32そのコードはともかくとして、
http://www.nwcpp.org/Downloads/2004/DCLP_notes.pdf
により、アドバンストなDCLPの実装があるよ。
でも、マルチCPUの場合は適切にメモリバリアを挿入してない、
DCLPはダメ(あらゆるマルチCPUな環境でダメというわけではないと思うが)
ってことになってるよ。
0447442
05/02/14 23:36:55読みました。
>>442のコードは2つほど問題があるようです。
1つ目。
new SingletonがpInstance = tempよりも前に実行される必要があるが、
これは必ずしも保証されません。
ロックが完全同期をとるメモリバリアの場合や、
メモリモデルがTSOのようにwrite→writeの順序が逆転しなければ
問題なさそうです。
しかし、acquire/release型のメモリバリア(release consistencyというのかな?)の場合
release後の読み書きは同期されないため、write順が逆転すると意図通りになりません。
2つ目。
Singleton::instance()で取得したオブジェクトを読み書きするときの例として以下のコードを考えます。
SIngleton* p = Singleton::instance();
p->x;
もしメモリモデルが(Pentium4のように)read→read順序が保証されないものだったとすると、
p->xがpの代入より前に行われる可能性があります。
(ただp->xはpに依存しますので、実際には順序が入れ替わることはないような気もします)
特定の環境では動きそうですが、確かにポータブルな書き方はなさそうですね。
どうもありがとうございました。
0448デフォルトの名無しさん
05/02/14 23:54:06そりゃいくらなんでも...
0449デフォルトの名無しさん
05/02/15 09:01:530450デフォルトの名無しさん
05/02/19 10:17:340451デフォルトの名無しさん
05/03/01 22:39:56具体的にはReadFileでブロックしているのを特定の時に解除したいんだけど、
TerminateThreadでスレッドをヌッ殺すのはあんまり良くない見たいだし。
オーバーラップi/oにして、WaitForMultipleObjectsあたりで、ほかのイベントも
受けられるようにしとくしかないのかな。
0452デフォルトの名無しさん
05/03/01 23:16:19CloseHandle()したら強制エラーリターンしないだろうか。
・・・すまん、試してないので真偽は不明。
0453デフォルトの名無しさん
05/03/02 00:29:18Overlappedが正解だろ。
0454デフォルトの名無しさん
05/03/02 20:54:06それはやってみたけど駄目でした。CloseHandleした他のスレッドまでブロックして
戻らなくなってしまいましたよ。
ソケットのハンドルならcloseするとrecvがエラーリターンするからもしやと思って
試してみたんだけどね。
>>453
やっぱ重複i/oですか。UNIX(solaris)で使ってたコードを移植してるんだけど、
UNIXだとシグナルでブロックを中断させてるから似たようなことできないかなぁ
と思ったもんで。重複i/oにしときます。
でもだとすると、同期i/oつかったアプリってブロックを解除する手立てがないとすると、
ウィンドウの×ボタン押されたときってどうやって終了すればいいんだろ?
別スレッドからTerminateThreadとかExitProcessとか乱暴な方法しかないような
気がするけど。それともコンソールアプリでしか使うなって事なのかな。
0455デフォルトの名無しさん
05/03/03 00:08:50×ボタンだとWM_CLOSEが飛んで来て普通は終わる。無視するのも自由。
無視して動き続けるとタスクマネージャからユーザーに止められる。
シャットダウン中だと暫く待って強制終了。
使われるのはおそらくTerminateProcessかその類似品。
TerminateThreadして動き続けるのはゴミ残るから(・A ・)イクナイ!けど、
ExitProcessはプロセス間で共有するリソースを使ってるような場合を
除いて問題なし。大半のリソースはプロセスと共に解放される。
0456デフォルトの名無しさん
05/03/03 02:36:02スレッドではなく、純粋な割り込みと考えてよいのかな?
0457デフォルトの名無しさん
05/03/03 02:36:310458デフォルトの名無しさん
05/03/03 02:49:370459デフォルトの名無しさん
05/03/03 07:38:080460デフォルトの名無しさん
05/03/04 22:21:07WM_CLOSEが飛んで来たとき、何とかしてサブスレッドのブロックを解除後、
サブスレッドを終了。
メインスレッドでWaitFor何がしObjectでサブスレッドが終了するまで待機後、
サブスレッドのハンドルをクローズ。その他諸々のハンドルを閉じてプロセス
終了へ。と言う風に思ってたんだけど
終了時ならそんなにムキになって後始末しなくていいんだ。
0461デフォルトの名無しさん
05/03/06 23:41:01少し前に「Windowsではmutexの静的な初期化が出来ない」という
話があったような気がするが
実際に必要になりそうなケースに遭遇したので、解決法の案。
(double-checked lockingなのは趣味だから気にするな)
static data_t *data;
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_lock(&mutex);
if (!data)
data = get_initial_data();
pthread_mutex_unlock(&mutex);
pthreadでは↑のように行う処理を、Windowsでやりたい。
CRITICAL_SECTION *csection;
if (!csection) {
CRITICAL_SECTION *p = new CRITICAL_SECTION;
InitializeCriticalSection(p);
InterlockedCompareExchangePointer(&csection, p, NULL);
if (csection != p) {
// 解放部は場合によっては不要だと思われる
DeleteCriticalSection(p);
delete p;
}
}
EnterCriticalSection(csection);
以下略
面倒ではあるが、こんな感じで正常に動くと思うのだが、どうだろうか。
0462デフォルトの名無しさん
05/03/08 15:28:58WinXP Pro
VC++ 6.0
マルチスレッドのサーバプログラムを作りたいと思っているのですが、
参考になるようなHP又はアドバイス等ありましたらご教授願います。
サーバの処理内容は、SQLDBに接続して処理結果を
クライアントに返すというものです。
0463デフォルトの名無しさん
05/03/09 02:21:10自前でマルチスレッドサーバプロセスを作るのは面倒なので、COMコ
ンポーネントを作ってCOM+に登録するというのはどうでしょうか。
スレッドやトランザクションの管理をお任せに出来るのが楽だと思
います。COMコンポーネントの作成に抵抗がなければですが……
0465デフォルトの名無しさん
05/03/09 09:39:05構造化例外の成れの果て
だったと思ったけど。
0466デフォルトの名無しさん
05/03/09 23:39:05だな。準拠のためのやっつけ仕事。
な〜んの役にも立たんぞ。
0467デフォルトの名無しさん
05/03/12 02:45:10どうやって作るのか教えて下さい。
そもそもその定義とは何ですか?
0468467
05/03/12 02:47:100469デフォルトの名無しさん
05/03/12 14:37:30糞初心者が。
0470デフォルトの名無しさん
05/03/15 05:37:070471デフォルトの名無しさん
05/03/15 14:49:30自分でboostやg++をmakeする気持があればどっちも同じ。
0472デフォルトの名無しさん
05/03/15 15:15:53新しくすればいい。
0473デフォルトの名無しさん
05/03/15 22:52:31boostはWindowsでも使える。
pthreadはWindows上では動かない。
そういう意味ではboostの方がポータブルだな。
・・・まあCygwin使えばpthreadも動くわけだが。
0474471
05/03/16 00:17:52それはちょっと知識が古いかな。
Pthread Support in Microsoft Windows Services for UNIX Version 3.5
http://www.microsoft.com/technet/interopmigration/unix/sfu/pthreads0.mspx
SFU 3.5はなぜ無償化されたのか
Services for UNIX最新版を無償化したマイクロソフトのマーケティング戦略
http://www.atmarkit.co.jp/fwin2k/insiderseye/20040319sfu35/sfu35.html
一時アメリカの政府機関の導入用件にPOSIX準拠であることを策定したので、
その流れでPOSIX対応じゃないと導入できないところがまだある。
C2 securityしかり。
0475デフォルトの名無しさん
05/03/16 01:27:50確かにNTにPOSIXサブシステムがあったのはそれが理由だが
SFUは違うというか普通にMacOSX対策じゃない?
0476デフォルトの名無しさん
05/03/16 14:15:46つかえねーPOSIXサブシステムは捨てたから、
POSIX互換が必要ならSFU使えって事でないの?
0477デフォルトの名無しさん
05/03/16 14:22:49導入用件をクリアさえすればいいだけで使えるようにする必要は無いんだから
わざわざ買収までしてSFUに切り替える理由がそれだけでは弱い
0478デフォルトの名無しさん
05/03/16 15:30:26Citrix ターミナルサーバ、Interix SFUは、いい決断だったと思います。
0479デフォルトの名無しさん
05/03/16 16:24:52>>476-477が言ってる使えないと>>478の言ってる使えないのニュアンスは多分違う
0480デフォルトの名無しさん
05/03/18 11:15:29環境
WinXP Pro
VC++ 6.0
VC++でマルチスレッドを用いた複数端末通信プログラムを作っています。
端末との通信はできたのですが、プログラムが終了するときにメモリリークが発生してしまいます。
プログラム構成は以下の通りです。
MainApp : CWinApp (アプリケーション)
MainSock : CAsyncSocket (アプリケーションメインソケット)
SubThread : CWinThread (各端末毎の接続を担当するスレッド)
SubSock : CSocket (端末とのデータ送受信用ソケット)
MainApp::InitInstance(){
g_Sock = new MainSock(); // メインソケット生成
g_Sock->Listen(); // 接続要求待ち
}
MainSock::OnAccept(){
SubThread* pThread = (SubThread*)AfxBeginThread()
スレッドにソケットを引き渡す
pThread->ResumeThread();
}
SubThread::InitInstance(){
m_SubSock.Attach( 渡されたソケット );
}
void SubSock::OnReceive(){
受信データの読み込み
}
0481デフォルトの名無しさん
05/03/18 11:16:00デバッグウィンドウのメッセージは以下の通りです。
Detected memory leaks!
Dumping objects ->
C:\Server\SubThread.cpp(17) :
{100} client block at 0x005F2F60, subtype 0, 140 bytes long.
a SubThread object at $005F2F60, 140 bytes long
Object dump complete.
SubThread.cpp(17)には、
IMPLEMENT_DYNCREATE(SubThread, CWinThread)
が記述してあります。
端末との接続用に生成したスレッドが終了していない事が原因と考えています。
スレッド内から AfxEndThread を呼べば終了できる事は確認していますが、
スレッドではSubSockオブジェクトを初期化しているだけで
Run()内でループ処理しているわけではないので、外部からフラグ等で終了させる事はできません。
外部から終了するにはどうすればいいのでしょうか?
0482デフォルトの名無しさん
05/03/18 12:17:150483480
05/03/18 12:46:33じゃあ、単純にソケットを複数個用意して、処理を割り当てればいいんですかね・・・?
何か参考になるHPとかあったら教えて頂けませんか?
0484デフォルトの名無しさん
05/03/18 13:10:34お好きなのをどうぞ。
マルチスレッドにするのならヒントとしては、
接続のためだけにワーカースレッドを用意して、
通信はメインスレッドに任せるっていう考え方よりも、
メインスレッド側で接続管理をして、
それぞれの通信管理をスレッドに任せる方が、
スマートだと思うけど。
0485480
05/03/18 14:07:42�@メインスレッドでメインソケットをListenで待機
�AメインソケットのOnAcceptでサブスレッドを生成、サブスレッドのメンバ変数にソケットを渡す
�Bサブスレッドのソケットでデータ送受信
�Cサブスレッドのソケットを閉じる
というところまではできたのですが、�Aで生成したサブスレッドが終了できない、という状況です。
>MFC ソケットでぐぐると一杯出てくるよ。
散々ぐぐって色々見てみたんですが、ソースの一部しか載ってなかったり
プロジェクトの性質から使えなかったり、という感じだったので
足りない部分を自分で作ってみたらこんな感じになってしまいました。
0486デフォルトの名無しさん
05/03/18 14:32:44スレッドは生かしつづけたままって事?
通常はその流れなら、
�@メインスレッドでメインソケットをListenで待機
�AメインソケットのOnAcceptでサブスレッドを生成、サブスレッドのメンバ変数にソケットを渡す
�Bサブスレッドのソケットでデータ送受信
�Cサブスレッドのソケットを閉じる
�Dサブスレッドから抜ける(スレッドの終了)
と言う様になると思うんだけど。
途中でスレッドを停止させるケースに対応したいっていうなら、
イベントカーネルオブジェクトなりで、メインスレッド<->サブスレッド間の
通知機構を実装しなきゃだと思う。
スレッドを生かしつづけてソケットだけを生成->割り当てとするなら、
スレッドプールの実装も考えた方がいい。
アプリケーションの終了時リークするのは、スレッドが停止していない状態で、
プロセスを終了しているからでは?
それならば、スレッドの終了をきちんと待ってからアプリは終了するべき。
スレッドの緊急停止は最終手段。
0487480
05/03/18 14:56:13>通知機構を実装しなきゃだと思う。
VC++あまり弄った事がなくてソケットの部分だけ調べまくってやってたので、
存在を忘れていました。
今回はとりあえず動かなければどうしようもないので、
Run()の中ですぐSubSock.Receive()を呼んでデータを受信し、
ループ処理せずにAfxEndThread(0,true);で終了する、という方法でやる事にしました。
他にも色々いい方法があるようなので、今度調べてみたいと思います。
どうも有難うございました。
0488デフォルトの名無しさん
05/03/18 14:59:13AdvancedWindows第4版は買っておいたほうがいいよ。
0489デフォルトの名無しさん
05/03/18 15:01:14AfxEndThread()で終了すると、そのスレッド内で実体化したクラスのデストラクタが呼ばれない。
なので、単にreturnする方がいい。
0490480
05/03/18 15:18:320491デフォルトの名無しさん
05/03/18 21:46:31どんなことが書いてある(その本でしか読めない)の?
0492デフォルトの名無しさん
05/03/19 00:21:09http://www.ascii.co.jp/pb/msp/38055/38055.htm
0493デフォルトの名無しさん
05/03/19 00:59:08volatile
0494デフォルトの名無しさん
05/03/19 03:48:540495デフォルトの名無しさん
05/03/21 00:11:17オススメの排他制御は何ですか?
対象のシステムは、突然電源が落とされる可能性があるものとします。
0496デフォルトの名無しさん
05/03/21 00:14:53ありません
0497デフォルトの名無しさん
05/03/21 00:25:59プロセスをまたいだら、既にスレ違い (マルチスレッドじゃない)
だろ。fcntl(2) で F_SETLKW。
てゆうかAPUE(http://pc5.2ch.net/test/read.cgi/tech/1105723117/13)嫁。
0498デフォルトの名無しさん
05/03/21 01:15:22ごめんなさい。
0499デフォルトの名無しさん
2005/03/24(木) 09:51:02おお、懐かしいな。俺が買った頃はまだ「Advanced Windows NT」
だったけど、Win32スレッドの使い方は大部分それで理解したよ。
最近JavaばっかでWin32方面は色々知らん事も多くなってきたから
また買ってみよ。あんがと。
0500デフォルトの名無しさん
2005/03/25(金) 13:54:270501デフォルトの名無しさん
2005/03/26(土) 19:05:24EnterCriticalSectionでSTATUS_NO_MEMORYの例外が発生する可能性があるそうですが、
皆さんどのように対策していますか?
InitializeCriticalSectionではなくInitializeCriticalSectionAndSpinCountを使えば回避できるようですが
Windows95等では対応していないようなので構造化例外処理を使用してどうにかしたいのですが
スマートな方法が思いつきません(´・ω・`)
0502デフォルトの名無しさん
2005/03/26(土) 19:34:30説明文の構成の仕方が変なのは気付いてますか?
「〜ですが、」ばかりで、丁寧語を使っていたとしても、
これではまるで馬鹿な子を見ている様です。丁寧語も中途半端です。
もっと本を読んだ方が良いでしょう。
私が書き直すとしたら、以下のようにするでしょう。
--------------------------------------------------------------
Windowsでのスレッド同期でクリティカルセクションを使用しています。
EnterCriticalSectionにてSTATUS_NO_MEMORY例外が発生する
可能性があるようですが、
皆さんはどのように対策しておられますか?
1つの対策としてInitializeCriticalSectionの代わりに、
InitializeCriticalSectionAndSpinCountを使う方法がありますが、
Windows95等では未対応のため、構造化例外処理からどうにかしたいのです。
スマートな方法が思いつきません。(`・ω・´)
0503デフォルトの名無しさん
2005/03/26(土) 19:38:34これを読み違えないで下さいね。
それ以外はあまり気にする必要はないでしょう。
0504デフォルトの名無しさん
2005/03/26(土) 20:14:070505デフォルトの名無しさん
2005/03/26(土) 20:17:090506デフォルトの名無しさん
2005/03/26(土) 21:31:11EnterCriticalSectionでSTATUS_NO_MEMORYの例外が発生する可能性があるそうですが、
皆さんどのように対策していますか?
InitializeCriticalSectionではなくInitializeCriticalSectionAndSpinCountを使えば回避できるようですが
Windows95等では対応していないようなので構造化例外処理を使用してどうにかしたいのですが
スマートな方法が思いつきません(´・ω・`)
0507デフォルトの名無しさん
2005/03/26(土) 22:06:300508デフォルトの名無しさん
2005/03/26(土) 22:11:29Win98以降で使えるみたいだから、捨てるのはWin95だけでいいみたい。
どうせもはやMSのサポート終了した製品だし。
0509デフォルトの名無しさん
2005/03/27(日) 00:30:190510デフォルトの名無しさん
2005/03/27(日) 02:41:40C#のメモリモデルについての記事。
DCLについても載ってるよ。
0511デフォルトの名無しさん
2005/03/27(日) 08:44:290512デフォルトの名無しさん
2005/03/28(月) 19:45:29http://www5e.biglobe.ne.jp/~liquor/raytrace/
http://www5e.biglobe.ne.jp/~liquor/prime/
マルチスレッドならここに聞け
0513釣り
2005/03/29(火) 21:53:11なるほど、C#ではvolatileでいいんですね
0514デフォルトの名無しさん
2005/04/03(日) 17:32:47.| | | レ | | | | | J || | |
∩___∩ | | | J | | | し || | |
| ノ\ ,_ ヽ .| レ | | レ| || J |
/ ●゛ ● | .J し | | || J
| ∪ ( _●_) ミ .| し J|
彡、 |∪| | .J レ
/ ∩ノ ⊃ ヽ
( \ / _ノ | |
\ " / | |
\ / ̄ ̄ ̄ /
 ̄ ̄ ̄ ̄
0515デフォルトの名無しさん
2005/04/03(日) 19:28:11http://www.microsoft.com/japan/msdn/library/default.asp?url=/japan/msdn/library/ja/dnpatterns/htm/ImpSingletonInCsharp.asp
http://discuss.develop.com/archives/wa.exe?A2=ind0203B&L=DOTNET&P=R375
0516デフォルトの名無しさん
2005/04/03(日) 21:53:230517デフォルトの名無しさん
2005/04/04(月) 00:30:000518デフォルトの名無しさん
2005/04/15(金) 14:29:59Enter〜Leaveの間はプロセス内のそのスレッド以外は動かないと
言う考えであってますか?
例えば2つのスレッドで同じ関数を呼ぶ場合、その関数の頭でEnterして
最後でLeaveしたとするとその関数自体複数のスレッドで同時に呼ばれる事が
無くなると言う事でしょうか?
0519デフォルトの名無しさん
2005/04/15(金) 15:55:45けど関数は自体は同時コール出来る
関数の中に入った時点で片方のスレッドがロックされる。
0520デフォルトの名無しさん
2005/04/15(金) 15:59:07回答ありがとうございます。
今そういった感じのアプリケーションを作ってるのですが
どうもその辺りに自信がなかったもので・・・。
0521デフォルトの名無しさん
2005/04/15(金) 20:03:04同じクリティカルセッションオブジェクトに対してEnterするとブロック(一時停止)される。というだけ。
0522デフォルトの名無しさん
2005/04/16(土) 00:51:27その表現では曖昧じゃね?
他のスレッドは少なくともEnterできないと思うが
同じスレッドが複数回Enterできるかどうかはモノによるような。
0523デフォルトの名無しさん
2005/04/16(土) 08:10:24もし「ブロックする」という実装ならば、その旨(複数回Enterするなと)明記されているのが普通と思う。
むしろ、複数回Enterした後、1回のLeaveで解除されるかが
実装依存な部分な気がする。
0524デフォルトの名無しさん
2005/04/16(土) 10:49:280525デフォルトの名無しさん
2005/04/16(土) 11:00:32MSDNのLeveCriticalSection()の解説にこう書いてあるよ。
>クリティカルセクションの所有権を解放するには、各スレッドはクリティカルセクションに入るたびに、
>LeaveCriticalSection 関数を 1 回呼び出さなければなりません。
>>524
CriticalSection=Windows固有のプロセス内限定のリカーシブなmutexみたいなもの。
EnterCriticalSection()でロックされて、LeaveCriticalSection()でアンロックされる。
たぶん....。
0526デフォルトの名無しさん
2005/04/16(土) 16:13:40何を難しく考えているんだか
0527デフォルトの名無しさん
2005/04/16(土) 16:24:280528デフォルトの名無しさん
2005/04/16(土) 17:02:46どこが?
0529デフォルトの名無しさん
2005/04/16(土) 17:20:03「クリチカルセクション」ってのが EnterCriticalSectionからLeaveCriticalSection間の
ことを指してるんなら、スレッドの切り替えは普通に行われるよ。
Windows 以外の環境の「クリチカルセクション」ってのについては知らないけど。
0530デフォルトの名無しさん
2005/04/16(土) 17:31:190531デフォルトの名無しさん
2005/04/18(月) 00:59:48ただし、同一 CriticalSection 間にはひとつのスレッドしか入れない。
スレッド A
EnterCriticalSection(&cs)
printf("A");
printf("a");
LeaveCriticalSection(&cs)
printf("1");
と
スレッド B
EnterCriticalSection(&cs)
printf("B");
printf("b");
LeaveCriticalSection(&cs)
printf("2");
を動かしてみればいい。
"Aa" の間に "Bb" は絶対に入らないが A2a はあるハズ。
0532デフォルトの名無しさん
2005/04/18(月) 23:15:230533デフォルトの名無しさん
2005/04/18(月) 23:41:32ワークパイルとワーカースレッドの違いがわからんとです
0534デフォルトの名無しさん
2005/04/19(火) 00:07:550535デフォルトの名無しさん
2005/04/19(火) 12:09:56組み込み用に書かれた OS (というかリアルタイムモニタというか) やプログラムなら、
クリティカルセクションをそんな風に実装することもあるよ。
単に割り込み禁止にしたりしてさ。
0536デフォルトの名無しさん
2005/04/19(火) 12:23:55メインスレッド無限ループ中にKERNEL32でエラーが出てしまいました!
スレッドも最近学んだ程度で、カーネルだって知らない!
助けてください!
0537デフォルトの名無しさん
2005/04/19(火) 12:46:110538デフォルトの名無しさん
2005/04/19(火) 13:04:220539デフォルトの名無しさん
2005/04/19(火) 13:05:57クリティカルセクションでスレッドそのものを制御する事も出来るの?
0540デフォルトの名無しさん
2005/04/19(火) 13:15:20トスイッチが起きないようにできます。シングルプロセッサのときは、
RASを使ってpthread_mutex_lock/unlockが実現されています。
0541デフォルトの名無しさん
2005/04/19(火) 13:33:160542デフォルトの名無しさん
2005/04/19(火) 13:36:150543デフォルトの名無しさん
2005/04/19(火) 14:07:17enter中に数分間の長い処理を行っただけで
他スレッドの処理が止まってしまい困るのでは?
0544デフォルトの名無しさん
2005/04/19(火) 14:12:34そういうOSの場合、困らないプログラムを動かすから何の問題も無い。
処理が短いとか別スレッドが動かなくてもいいとか。
0545デフォルトの名無しさん
2005/04/19(火) 14:20:11数分も何らかの排他処理を行いたいなら、
mutexやセマフォを実装すれば良いわけで。
んでそのセマフォなりmutexなりの操作する部分だけを
クリティカルセクションで保護する。
0546デフォルトの名無しさん
2005/04/19(火) 14:28:06保護すべき領域をクリティカルセクションと呼ぶのであって、
保護するための仕組みのことではないよね...
0547デフォルトの名無しさん
2005/04/19(火) 14:35:33ユーザプロセスが異常な振舞いをしたから他のプロセスの実行に支障が出るってのは
まずいだろ。
enterしたままビジーループに入ってしまったらどうすんの?
0548デフォルトの名無しさん
2005/04/19(火) 14:46:19組み込み系だと普通はWDTで電源落ちにします。
0549デフォルトの名無しさん
2005/04/19(火) 14:50:500550デフォルトの名無しさん
2005/04/19(火) 14:57:15>他スレッドの処理が止まってしまい困るのでは?
>>547
>他のプロセスの実行に支障が出るってのはまずいだろ。
話がずれてますな。
0551デフォルトの名無しさん
2005/04/19(火) 14:59:48>>543はハードリアルタイムを保証するかどうかどうかで、
>>547は協調的マルチタスクを必要とするかどうかじゃない?
いくらなんでもユーザプロセスがおいたして機能不全に陥いるのはまずいべ。
少なくともUNIXでは普通は予期しないだろう。
0552デフォルトの名無しさん
2005/04/19(火) 15:06:40任されているならありかなとは思う。
0553デフォルトの名無しさん
2005/04/19(火) 15:45:46>ある区間においてコンテキストスイッチが起きないようにできます。
というような乱暴なものではないと思うんだけど・・・
組み込み用OSでは、まずい設計のプログラムを書けば
まずい結果が得られるのはごく普通。
普通のOSでもデバイスドライバ等では同様。
0554デフォルトの名無しさん
2005/04/19(火) 20:00:030555デフォルトの名無しさん
2005/04/19(火) 20:08:590556デフォルトの名無しさん
2005/04/19(火) 20:16:58共有メモリに対するアクセスにセマフォを使って
排他制御をかけようとしています。できれば排他ではなくて
reader/writer ロックを実装したいのですが、普通こういうのは
どのように実装するんでしょうか? なんらかのライブラリ?は
なさそうですし・・。ちなみに Linux の C です。
スレ違い、勘違い発言でしたらすみません。。
0557デフォルトの名無しさん
2005/04/19(火) 20:23:260558デフォルトの名無しさん
2005/04/19(火) 23:48:02UNIXプログラミングスレ言って、
System V IPCのセマフォの使い方聞け。
(man semop)
0559556
2005/04/20(水) 00:03:24>>558
コメントありがとうございます。
「最前線UNIXのカーネル」という書籍があったので
自分なりに調べましたが、reader/writerの実装は
結構ややこしそう(めんどくさそう)でした。
現状はセマフォで実装しており常に排他になってしまってますが
まあなんとなくこれでしばらくは我慢しようという気持ちに
なってきたところです。
ともあれ、コメントありがとうございました。
0560558
2005/04/20(水) 00:51:15reader/writer lockは。一つカウンタ管理するだけだぞ。
ただスレ違いだから、必要だったらあっちで聞いてね。
0561デフォルトの名無しさん
2005/05/01(日) 17:39:45ああ、Linuxだと 一個増えて表示されるからややこしいかな?
Solarisならいいんだけど
0562デフォルトの名無しさん
2005/05/03(火) 22:49:16だとしたら無茶言うな
0563デフォルトの名無しさん
2005/05/15(日) 13:30:230564デフォルトの名無しさん
2005/05/15(日) 13:33:26>>563 が考えているコストの1.5倍ぐらい。
0565デフォルトの名無しさん
2005/05/15(日) 13:56:12結構高いんですね。
頻繁に作成消滅を繰り返すよりも、使用しないときはmutexで停止させて眠らせておいた方が良さそうですね。
0566デフォルトの名無しさん
2005/05/15(日) 14:52:16だいたい1msで作れてた気がするな
0567デフォルトの名無しさん
2005/05/15(日) 15:06:290568デフォルトの名無しさん
2005/05/16(月) 00:07:59死ねクズって感じ
0569デフォルトの名無しさん
2005/05/16(月) 01:16:21Windowsのbeginthreadexの場合はまずCランタイムの初期化とかもあるし、
内部的にVirtualAllocでメモリマップを割り当てたりCriticalSection
とかで排他したりしてるわけだから、
実際計ったことないけど1msで作れれば良いほうだと思うよ。
これに比べるとUNIXのforkなんか目も当てられない。
0570デフォルトの名無しさん
2005/05/16(月) 01:20:09プロセスが割り当てるメモリマップに依存し有限だから、
forkのようにいくらでも作れるというわけじゃない。
Windowsのスレッドはデフォルトで1MBのスタックを個別にマップするわけで、
プロセスのメモリ空間が32bitの範囲のOSなら、約2000個のスレッドを
作れれば良い方だと思う。
スタックサイズを調節したらもっと多くできるだろうけど。
つーか1プロセスの最大スレッド数って定義されてたっけ?
誰か試してみませんか?
0571デフォルトの名無しさん
2005/05/16(月) 01:58:550572デフォルトの名無しさん
2005/05/16(月) 11:22:58スレッドとプロセスを比べられても…
0573デフォルトの名無しさん
2005/05/16(月) 20:53:180574デフォルトの名無しさん
2005/05/16(月) 21:26:140575デフォルトの名無しさん
2005/05/17(火) 00:39:33そりゃ後発で糞だったら目も当てられないw
まあスレッドだけ早くなってもXはもっさりのまんまだし、
UNIXって前途多難だよな。
0576デフォルトの名無しさん
2005/05/17(火) 01:42:21> UNIXって前途多難だよな。
2037年が寿命ならもう半分は過ぎてしまったわけで、もう前途はないわけで
0577デフォルトの名無しさん
2005/05/17(火) 08:23:21これはもう、OSの所為ではなくてプロトコルが余りに古すぎる所為なのだが。
タランテラみたいなミドルウェア経由の方がよっぽど速くなる罠。
0578デフォルトの名無しさん
2005/05/17(火) 18:35:29(2)で自分のシグナルを受信しちゃいます?
pthread_mutex_lock( &mutex );
pthread_cond_signal( &cond ); // (1)
Value = 1;
do {
pthread_cond_wait( &cond, &mutex ); // (2)
} while ( Value != 0 );
pthread_mutex_unlock( &DataProcMutex );
0579デフォルトの名無しさん
2005/05/18(水) 23:30:410580デフォルトの名無しさん
2005/05/19(木) 00:01:10単純にDisplayの設定を変えるだけで早くなる場合があるがな
0581デフォルトの名無しさん
2005/05/19(木) 00:11:27Intel PDF IA-32より
service pending iterrupts (if any)
だから切り替えは起きません。
0582デフォルトの名無しさん
2005/05/19(木) 00:12:20○interrupts
0583デフォルトの名無しさん
2005/05/19(木) 00:20:30スレッド切替え発生するだろ。
>service pending iterrupts (if any)
それ割り込みじゃねーのか?
0584デフォルトの名無しさん
2005/05/19(木) 00:23:250585デフォルトの名無しさん
2005/05/19(木) 00:26:18コンテキスト切り替えって、何らかの割り込みで起こすんじゃねーの?
0586デフォルトの名無しさん
2005/05/19(木) 00:34:17転送する重い処理を、もう一つは単純なループなどを実行し、それぞれのスレッド
に実質的に割り当てられたCPU時間を比較してみてもいいな。
あ、でもタイムスライスより長いREP命令なんてなかなかないかも。
0587デフォルトの名無しさん
2005/05/19(木) 01:08:19言語はCです。。教えてエロイ人〜!!
0588デフォルトの名無しさん
2005/05/19(木) 01:15:530589デフォルトの名無しさん
2005/05/19(木) 01:31:34とりあえず文字列がサーバ(?)からクライアント(?)に送れるようにはなったとです。
でもチャットってサーバとかクライアントとか関係なく送信も受信もできなきゃダメじゃないですか・・・。
スレッド使えばうまくいくのかなぁとか思ったとですけど、うまくいかんとです。
もっと良い方法があるとですか??
0590デフォルトの名無しさん
2005/05/19(木) 01:41:290591デフォルトの名無しさん
2005/05/19(木) 01:53:27マニュアル中巻より
リピート・ストリング操作は、例外または割り込みによって中断されることがある。
とあるから、rep〜中にもスレッドの切り替えはあるでしょう。
0592デフォルトの名無しさん
2005/05/19(木) 03:02:22割り込みと言っても色々あるのだ。
0593デフォルトの名無しさん
2005/05/19(木) 03:08:310594デフォルトの名無しさん
2005/05/20(金) 15:02:120595デフォルトの名無しさん
2005/05/20(金) 18:47:520596デフォルトの名無しさん
2005/05/20(金) 18:49:120597デフォルトの名無しさん
2005/05/20(金) 19:30:430598デフォルトの名無しさん
2005/05/20(金) 19:34:130599デフォルトの名無しさん
2005/05/24(火) 03:27:33これまで,スレッドを使用したプログラムではいくつかの動作を
メインループから指示するために
WaitForSingleObjectもしくはWaitForMultipleObjectsを使用し
Signalによって動作を起動させていました.
今回,いくつかのパラメータをスレッドに渡す必要が生じたのです
がどのような方法が簡単で安全でしょうか?
0600デフォルトの名無しさん
2005/05/24(火) 05:18:440601デフォルトの名無しさん
2005/05/24(火) 07:24:28QueueUserAPCで渡す。
0602デフォルトの名無しさん
2005/05/24(火) 12:58:44全スレッドの合計値を得たい場合どうすればよいのでしょうか?
0603デフォルトの名無しさん
2005/05/24(火) 13:04:100604デフォルトの名無しさん
2005/05/24(火) 14:38:540605デフォルトの名無しさん
2005/05/24(火) 14:55:340606デフォルトの名無しさん
2005/05/24(火) 15:02:480607デフォルトの名無しさん
2005/05/24(火) 23:15:35dlopen等でShared Objectをロードする場合なんかは要るかもね。
そいつが-lpthread必要としてたりすると動かないから。
-lpthreadはいくつかのシステムコールとかを上書きするから、
プロセス開始時に一緒にロードされてないと困ることになるはず。
昔の記憶なんで今は違ってたらスマソ。
0608デフォルトの名無しさん
2005/05/25(水) 00:30:580609デフォルトの名無しさん
2005/05/25(水) 12:22:03言いたいことがあるならはっきり言えよ
0610デフォルトの名無しさん
2005/05/25(水) 14:13:50チンコかゆい
0611デフォルトの名無しさん
2005/05/25(水) 23:34:09java.util.concurrent.ConcurrentHashMapって
(*´д`*)ハァハァできまつか?
0612デフォルトの名無しさん
2005/06/05(日) 14:31:530613デフォルトの名無しさん
2005/06/06(月) 00:38:11似たような感じなんですが、どう使い分けましょうか?
0614デフォルトの名無しさん
2005/06/06(月) 01:08:45ドキュメントは読んだか?
0615デフォルトの名無しさん
2005/06/06(月) 01:17:26http://www.opengroup.org/onlinepubs/009695399/functions/pthread_spin_lock.html
The pthread_spin_lock() function shall lock the spin lock referenced by lock.
The calling thread shall acquire the lock
if it is not held by another thread.
Otherwise, the thread shall spin (that is, shall not return from the pthread_spin_lock() call)
until the lock becomes available.
この辺りは、pthread_mutex_lock()と実質的に変わらん予感。
The results are undefined if the calling thread holds
the lock at the time the call is made.
は、PTHREAD_MUTEX_DEFAULTのmutexと変わらんと思う。
で、どこが違うのだろうか...
唯一違いそうなのが、spinというくらいだから
カーネルやらスレッドスケジューラによらずクルクル回って
スピンしているのか?だしかにspinするって書いてあるが。
だからどうなの?
0616デフォルトの名無しさん
2005/06/06(月) 01:23:11そこまでわかってるなら、パフォーマンスでも比べてみると良いんじゃないかな?
0617デフォルトの名無しさん
2005/06/06(月) 01:43:41それは、たまたま、そのOSの実装でってことだよね。
一般的にPOSIXの定義として
ドキュメントのどこにもパフォーマンスのことなんか
書いていないんだが...俺が見落としているんだろうか?
0618デフォルトの名無しさん
2005/06/06(月) 01:43:47スレッドをブロックさせたりとかいうめんどい処理がないので、
ごく短い時間しか待たないならむしろ効率が良い。
んじゃないかなあ...
0619デフォルトの名無しさん
2005/06/06(月) 01:46:25> ドキュメントのどこにもパフォーマンスのことなんか
> 書いていない
スレッドの仕様にパフォーマンスへの要求を含めちゃうと
いろいろよろしくないっしょ
0620デフォルトの名無しさん
2005/06/06(月) 01:47:59lock期間が長くなりそうな場合はmutex
短い(数ステップ?)ならspin
てな感じでいいや。
0621デフォルトの名無しさん
2005/06/06(月) 01:50:22mutexよりspinの方がパフォーマンスがよろしい(たいていは)。
ということだけでもあってもいいと思いますが。
0622デフォルトの名無しさん
2005/06/06(月) 02:01:240623デフォルトの名無しさん
2005/06/06(月) 02:04:170624デフォルトの名無しさん
2005/06/06(月) 03:08:28んなわけねーだろ
0625デフォルトの名無しさん
2005/06/06(月) 17:34:500626デフォルトの名無しさん
2005/06/06(月) 20:05:460627デフォルトの名無しさん
2005/06/09(木) 22:00:52そりゃ自分以外に頼れるものがない寂しい子だからでしょ。
0628デフォルトの名無しさん
2005/06/11(土) 20:30:090629デフォルトの名無しさん
2005/06/12(日) 12:14:51pthread_createでスレッドを作るときメンバ関数は
そのままでは入らないみたいなのでぐぐってみたところ
この関数を入れれば良いとのことでした
static void *ThreadEntry(void *ptr){
static_cast<CLASS *>(ptr)->Thread(ptr);
return ptr;
}
しかし、この関数で呼んだメンバ関数Threadはメンバ変数を
使うとSegmentation faultしてしまいます。
なんとかpthread_createでメンバ関数をスレッドとして
立ち上げることはできないでしょうか?
環境はFreeBSD4.11でコンパイラはg++です
よろしくお願いします
0630デフォルトの名無しさん
2005/06/12(日) 12:18:580631629
2005/06/12(日) 12:22:15pthread_create(&tid[i], NULL, CLASS::ThreadEntry, (void *)i)
これです。"i"はスレッド番号
0632デフォルトの名無しさん
2005/06/12(日) 12:24:050633629
2005/06/12(日) 12:25:300634デフォルトの名無しさん
2005/06/12(日) 12:27:52つまるところ
static_cast<CLASS*>((void*)i))->Thread((void*)i);
を実行していることになる。
Cの勉強しなおしたほうがいいんじゃねえの?
0635629
2005/06/12(日) 12:36:17・・・自分のオブジェクトってどうやって取得すればいいんでしょうか
適当な関数作って引数として自分のポインタをもらうしかないのかな・・・
0636デフォルトの名無しさん
2005/06/12(日) 13:42:29C/C++の基礎を勉強すべきだ。
0637デフォルトの名無しさん
2005/06/12(日) 17:57:30CPUの数を取得する方法がわかりません。LinuxでCPU数を取得する方法を教えてください。
0638デフォルトの名無しさん
2005/06/12(日) 19:22:48リナザウしか持ってないから分からんけど、/proc/cpuinfoでも見れば
分かるんじゃないの。わかんなかったらLinux板でも行って聞いて。
ここじゃ板違いだし。
0639デフォルトの名無しさん
2005/06/13(月) 00:10:08「this」って予約語知らない奴がマルチスレッドか…こんなんだから…
関係ないが (void*) と static_cast<CLASS*>() が混ざってるのもキモイな。
0640デフォルトの名無しさん
2005/06/13(月) 00:12:530641デフォルトの名無しさん
2005/06/13(月) 00:17:120642デフォルトの名無しさん
2005/06/13(月) 00:30:39static_cast<CLASS*>(static_cast<void*>(i))->Thread(static_cast<void*>(i))
0643デフォルトの名無しさん
2005/06/13(月) 19:28:21>>642 の様に長くなって読みづらいけど… cast の種類が明示される方がいいという考え
方もあるのだよ。
Cタイプのキャストだと、reinterpret_cast と static_cast の違いが明確でないし。
って、スレ違いスマソ。
0644デフォルトの名無しさん
2005/06/17(金) 08:07:58言語がわからないようなアホは
スレッドなんてやるなって。
って会社で言ったら、
「そんなの難しいのが悪い」と真顔で反論されたことがある。
0645デフォルトの名無しさん
2005/06/17(金) 12:28:36ラッパークラスでもなんでも作りやがれや
0646デフォルトの名無しさん
2005/06/17(金) 14:12:240647デフォルトの名無しさん
2005/06/17(金) 14:32:05まず最初に党員に(ry
0648デフォルトの名無しさん
2005/06/17(金) 14:36:05金に関わるところですらまだ曖昧なままだし
法で縛らんとだめだろうね
0649デフォルトの名無しさん
2005/06/18(土) 00:51:38たとえ俺に役目があったとして、
お前の無努力や無能力が正当化されるわけではない。
0650デフォルトの名無しさん
2005/06/18(土) 01:00:48プログラムを組むのは難しくないか?
0651デフォルトの名無しさん
2005/06/18(土) 01:06:100652デフォルトの名無しさん
2005/06/18(土) 01:14:370653デフォルトの名無しさん
2005/06/18(土) 02:57:450654デフォルトの名無しさん
2005/06/18(土) 09:28:24なんでもAPI一発でインスタントにできると思ってる上司に
真顔で一発でできるようにしろと言われたことがある。
まあ、技術は弱いけどマネージメントできる人だからいいんだけど。
0655デフォルトの名無しさん
2005/06/18(土) 13:12:48linux の boost::thread で 400 以上のスレッドを作ろうとすると
リソース不足の例外が発生してそれ以上作れないのだが、
この上限をもっと増やすにはどうしたら良いのだろうか・・・?
0656デフォルトの名無しさん
2005/06/18(土) 13:43:38とネットワークプログラミングのスレには書いてあったが、何故ここでも書かない?
thread::join()とかpthread_join()は理解できているの?
0657デフォルトの名無しさん
2005/06/18(土) 13:54:04開いているファイルを閉じる
0658デフォルトの名無しさん
2005/06/18(土) 14:00:42ごみになっているスレッドを終わらせる
>http://pc8.2ch.net/test/read.cgi/tech/1118469143/
>
>>スレッド終了してもスレッドオブジェクトが残っていて、作れなくなっていた。
>を解決するのが先だろ。なんでシステム上限を上げて対処しようとするかな……
0659デフォルトの名無しさん
2005/06/18(土) 16:09:53残ったままというのはもう解決したから。
しかし、次のステップでは 400 以上平行して走らせたいのだ。
どうやら、スタックのメモリ量が関係しているらしい事までは
掴んだ・・・が、ulimit -s で少なめにしてみても、今度は
システムがスローダウンして・・・なにが起きているのやら・・・
0660デフォルトの名無しさん
2005/06/18(土) 18:13:1264CPUとか128CPUのマシンをパーティショニングせずに運用するのかな。
0661デフォルトの名無しさん
2005/06/18(土) 18:42:410662デフォルトの名無しさん
2005/06/18(土) 19:45:27つーか今度はthread数の上限(ulimit -u)は解決してんじゃん(w
遅いのは仕方ないでしょ。(たぶん)CPUもメモリも喰ってんだから。
0663デフォルトの名無しさん
2005/06/19(日) 02:55:000664デフォルトの名無しさん
2005/06/19(日) 10:33:20空きがなくなりそうになると極端に遅くなるから。(スラッシング)
0665デフォルトの名無しさん
2005/06/19(日) 11:22:13作りがショボい or ハード/OSの選定ミスだとは思うが。
0666デフォルトの名無しさん
2005/06/19(日) 12:41:49俺も思った。何か致命的な設計仕様上の欠陥がある気がする。
0667デフォルトの名無しさん
2005/06/19(日) 12:46:530668デフォルトの名無しさん
2005/06/19(日) 13:43:250669デフォルトの名無しさん
2005/06/19(日) 22:39:24通常のdefaultは2000超えるからね。
それ以上必要で、リソースが十分なら、ulimit -uで増やせばいいだけだよ。
メモリかスワップが足りないだけじゃない?
0670デフォルトの名無しさん
2005/06/20(月) 02:47:40なんか現象変わらず ・・
ulimit とかでイロイロ試すと、さっきまで
落ちていた場所では落ちなくなったものの ・・
なぜか、スレッド 300 作る辺りまではすごく
高速に生成できるのに、さっきまでエラーで
落ちていた回数を少し超えた辺りから、生成
スピードが指数関数的に遅くなり、330 ぐらい
でシステム全体のレスポンスが極端に遅く
なり ・・・ 固まった。 orz.
なんなんだこれは?
どうにも良く判らないな ・・・
カーネルにスレッド数のパラメータなんてあったっけ?
0671デフォルトの名無しさん
2005/06/20(月) 02:56:320672デフォルトの名無しさん
2005/06/20(月) 02:56:48Solaris だと lockstat, truss, prstat -L あたりで何となく分かる事もあるけど、
Linux のコマンドでも同じ様なのあるでしょ。
0673デフォルトの名無しさん
2005/06/20(月) 08:22:51実装メモリとCPUパワーが足りないんだよ。
Athron 64 x 4 + Memory 32GBくらいにしてみ?
0674デフォルトの名無しさん
2005/06/20(月) 08:29:45各スレッドは何してる?
0675デフォルトの名無しさん
2005/06/20(月) 10:26:25ttp://pc8.2ch.net/test/read.cgi/tech/1118469143/51-
0676デフォルトの名無しさん
2005/06/20(月) 10:33:45ulimit でスタック使用量減らしたら生成できるスレッド数の限界は解決した。
沢山生成で遅くなったのは、スレッドの開放が usleep 呼び出しでできるものと
思い込んでいたのが原因だった。Windows では Sleep() で開放してたんで。
sched_yield() をいれてやったら、アッサリ 3000 以上生成できるようになった。
(ulimit でスタック使用量を 10 分の 1 にした時)
0677デフォルトの名無しさん
2005/06/20(月) 11:04:55> スレッドの開放が usleep 呼び出しでできるものと思い込んでいた
orz
0678デフォルトの名無しさん
2005/06/20(月) 20:51:070679デフォルトの名無しさん
2005/06/20(月) 21:53:510680デフォルトの名無しさん
2005/06/20(月) 22:48:26待機させて、broadcastして一気に目覚めさせればいいのに。
WindowsだってEvent使って初期化終わるまで待機させた方が
お行儀のいいプログラムになると思うぞ?
0681デフォルトの名無しさん
2005/06/20(月) 23:52:51これだから犬厨は。
0682デフォルトの名無しさん
2005/06/20(月) 23:53:550683デフォルトの名無しさん
2005/06/21(火) 00:14:15> スレッドの開放が usleep 呼び出しでできるものと思い込んでいた
< スレッドからのCPU明け渡しが usleep 呼び出しでできるものと思い込んでいた
だろ? orz
0684デフォルトの名無しさん
2005/06/22(水) 00:30:03WindowsXpだと全体で5000くらいが限度みたいで、VC++でもmingwでもおなじ。
CPUはPentium-M、IA32でのスレッド上限は8192個らしいからそんなもんかもしれんが。
メモリ食いなのでリンカのメモリ設定をいじるうまくいく。
mingw-gcc なら -lW,--heap,1024,--stack,4096とか、
1秒に一回 std::string s を s+="x";するだけのスレッドを約5000個起動、
スレッド生成時は100%負荷がかかる、1秒で100個程度しか作れない。
boost::thread_resource_error例外がバンバンでたあたりで、
システム全体の調子が変になり、動作は重くは無いが、他のプロセスが起動できなくなる。
全スレッド生成後タスクマネージャは平均10%の負荷、50MBくらい使う、チクショウ、
タスクマネージャー自体がややフリーズしはじめたので、これはたぶん正確ではない。
なんにせよスレッドがいちどきに最大たったの5000程度しかうごかないのは残念だ、
しかも、OS全体で5000で、プロセスごとに5000が上限ではない、
つまり1000個のスレッドを同時に動かすプロセスは5個が限度というこった。
WIN64やらEM64Tやらなんかではどのくらいまで平気なのか気になる。かゆうま。
0685デフォルトの名無しさん
2005/06/22(水) 00:35:400686デフォルトの名無しさん
2005/06/22(水) 13:18:44> CPUはPentium-M、IA32でのスレッド上限は8192個らしいからそんなもんかもしれんが。
(゚Д゚)ハァ?
0687デフォルトの名無しさん
2005/06/22(水) 15:47:51数が上限だった気がする。
0688デフォルトの名無しさん
2005/06/22(水) 20:03:38OS は Linux です。
pthread_cleanup_push によってクリーンアップハンドラを登録します。
そのクリーンアップハンドラの中で、さらに pthread_cleanup_push を呼び出すことは許されるのでしょうか。
というのは、確保したリソースをクリーンアップハンドラで解放したいのですが、この解放処理に排他制御が
必要なのです。
排他処理には mutex を使っているのですが、pthread_mutex_lock の前に pthread_cleanup_push を行って
pthread_mutex_unlock を登録しているのです。
いかがなものでしょうか?
実は別スレで質問したのですが、スレ違いを指摘されてこっちに移動してきたのですが、よろしくお願いします。
0689688
2005/06/22(水) 20:07:240690デフォルトの名無しさん
2005/06/24(金) 01:10:35詳しく教えてはくれまいか。エロイ人。
0691せめてOSくらい明記しようや
2005/06/24(金) 01:15:05やだ。
0692デフォルトの名無しさん
2005/06/24(金) 01:21:39A君がXちゃんにお話したい時はQ太郎にお願いする
Q太郎はA君のお願いを自分のキューに入れる
B君もXちゃんにお話したい時はQ太郎にお願いする
XちゃんはA君やB君やC君がいようと
Q太郎から単純に順番にお願いをとりだすだけで済む
0693デフォルトの名無しさん
2005/06/24(金) 01:27:07Q太郎が4人くらい居たら便利?
0694デフォルトの名無しさん
2005/06/24(金) 04:46:360695デフォルトの名無しさん
2005/06/24(金) 04:59:07というシチュエーションはよくある。
0696デフォルトの名無しさん
2005/06/24(金) 06:41:37あずかったお願いも、犬に追いかけられているうちに
なくしてしまいました。
でもQ太郎は気にしません。元気がとりえです。
0697デフォルトの名無しさん
2005/06/24(金) 11:15:330698デフォルトの名無しさん
2005/06/24(金) 22:16:59マルチスレッドのスレッド構成の指針みたいなのはWebに情報ないよね。
と思った。
0699デフォルトの名無しさん
2005/06/24(金) 22:39:13なんで、
void my_cleanup_handler(void*) {
:
:
pthread_mutex_lock(...);
排他が必要な解放処理;
pthread_mutex_unlock(...);
}
ではダメなの?
SUSにはとくにできるともできないとも記述されてないように見えるけ
ど、素直に実装したら、クリーンアップ中にpushしてももう手遅れな気
がする。
0701デフォルトの名無しさん
2005/06/25(土) 00:56:180702688
2005/06/25(土) 01:07:04ロックを獲得する関数を呼んだならば、それを解放する処理も必ず呼ばなくちゃいけない。
だからその解放処理をクリーンアップハンドラに指定するんだけど、その解放処理自身も mutex を使ってるから、
mutex の解放を確実にするため、pthread_mutex_unlock もクリーンアップハンドラにしたい。
処理を単純化して書くと、こんなかんじ。
void my_lock(void *my_resource)
{
pthread_cleanup_push(pthread_mutex_unlock, &mtx);
pthread_mutex_lock(&mtx);
ロック処理
pthread_cleanup_pop(1);
}
void my_unlock(void *my_resource)
{
pthread_cleanup_push(pthread_mutex_unlock, &mtx);
pthread_mutex_lock(&mtx);
アンロック処理
pthread_cleanup_pop(1);
}
で、
pthread_cleanup_push(my_unlock, &my_resource);
my_lock(&my_resource);
なんらかの処理
pthread_cleanup_pop(1);
というわけ。
そんなにおかしなことしてる?
0703デフォルトの名無しさん
2005/06/25(土) 10:22:27この説明は正しいですか?
http://www.linux.or.jp/JM/html/glibc-linuxthreads/man3/sem_init.3.html
引っかかる点は、「sem で指定されるセマフォのカウントが非 0 になるまで呼び出しスレッドの実行を停止する。」というところです。
「非0 になるまで」ではなくて、「0 になるまで」の間違いではないでしょうか?
あともう一点。
sem_wait は、取り消しポイントということになっています。
ということは、次のようなコードは間違いになりますよね。
pthread_cleanup_push(sem_post, &sem);
sem_wait(&sem);
処理
pthread_cleanup_pop(1);
では、スレッドがキャンセルされたときにセマフォの解放を確実にしたい場合、どのようにコーディングすればいいのでしょうか?
0704デフォルトの名無しさん
2005/06/25(土) 11:41:01非0であってる。
sem_waitは、セマフォが0より大きければ1減らして通過。
セマフォが0なら1以上になるまで待って、1減らして通過。
0705703
2005/06/25(土) 16:19:52なるほど。
じゃあカウンタの初期値は 1 とかにしておく、ってことですか。
ありがとうございます。
あとは取り消しポイントであることについての疑問が残るのみです。
どなたかよろしくお願いします。
0706デフォルトの名無しさん
2005/06/25(土) 16:28:00sem_waitの最中に取り消されたなら、クリーンナップは要らないだろ。
0707デフォルトの名無しさん
2005/06/25(土) 16:39:54sem_wait(&sem);
pthread_cleanup_push(sem_post, &sem);
処理
pthread_cleanup_pop(1);
0708デフォルトの名無しさん
2005/06/25(土) 16:42:35問題は、sem_wait が完了した後に取り消されたときなんです。
それに備えてクリーンアップハンドラを登録しようにも、その登録を sem_wait の前でやっても
後でやっても具合の悪いタイミングが存在しますよね?
それとも、sem_wait 〜 sem_post の間には、キャンセルポイントが無いようにしないといけないという
ことなのでしょうか?
0709デフォルトの名無しさん
2005/06/25(土) 16:45:50sem_wait の後で登録したら、どう具合が悪いの?
0710デフォルトの名無しさん
2005/06/25(土) 16:47:38それだと、sem_wait がキャンセルされて復帰した場合、セマフォの獲得をしていないにもかかわらず
セマフォの解放を行ったりしませんか?
と言ってみたものの、もしや sem_wait が復帰するときというのは、必ずキャンセルされていないことが
保証されているのですね?
キャンセルされたら、sem_wait から復帰することなく、クリーンアップ処理が走る、ってことでしょうか?
0711デフォルトの名無しさん
2005/06/25(土) 16:52:57キャンセルされて復帰したとはどういう事だ?
sem_waitがキャンセルされたなら、事前に登録してあるクリーンナップ
ハンドラが呼ばれて、そのスレッドはそこで終わりじゃないのか。
0712デフォルトの名無しさん
2005/06/25(土) 16:56:03はい。理解しました。
自分でも何を勘違いしていたのか疑問です。
0713デフォルトの名無しさん
2005/06/27(月) 02:16:21○| ̄|_ の小さい版とは知っていたが、
四つんばいとは知らなんだ。
拳を握り、目を細めて ウググググ・・・って悔しがってるのかと思ってた。
0714デフォルトの名無しさん
2005/06/27(月) 03:11:43が分からん。orz
0715デフォルトの名無しさん
2005/06/27(月) 03:52:260716デフォルトの名無しさん
2005/06/27(月) 04:32:17顔の線
↓
○| ̄|_
↑ ↑ ↑
拳 目 鼻
0717せめてOSくらい明記しようや
2005/06/27(月) 04:58:15○| ̄|_  ̄|○
0718デフォルトの名無しさん
2005/06/27(月) 05:01:520719デフォルトの名無しさん
2005/06/27(月) 08:07:340720デフォルトの名無しさん
2005/06/27(月) 08:15:57@@@@
○| ̄|_  ̄|○
\◎/
| | ̄|_ ○| ̄|_ orz
0721デフォルトの名無しさん
2005/06/27(月) 08:59:46見えるぞ、私にも見える!
0722デフォルトの名無しさん
2005/06/27(月) 12:15:22○| ̄|_
なら顔には見えまい。
0723デフォルトの名無しさん
2005/06/27(月) 13:02:14@@@@
○| ̄|_  ̄|○
\ー/ ニヤリッ
0724デフォルトの名無しさん
2005/06/27(月) 14:20:340725713
2005/06/27(月) 19:49:480726デフォルトの名無しさん
2005/06/27(月) 23:42:560727713
2005/06/27(月) 23:54:47↓
○| ̄|_
↑ ↑↑
拳 目 口
これ、口だから。崩さんといて。<@
0728デフォルトの名無しさん
2005/06/28(火) 00:04:570729713
2005/06/28(火) 00:08:58そうです。
0730デフォルトの名無しさん
2005/06/28(火) 00:20:45クリーンアップしてる間はキャンセル禁止(か遅延)にしとけば?
0731デフォルトの名無しさん
2005/07/03(日) 22:45:44再度クリーンナップされるのはPOSIXの正しい仕様ですか?
0732デフォルトの名無しさん
2005/07/05(火) 01:44:58三つの穴にとっかえひっかえ入れられて。入れてない哲学者は瞑想にふけて、
順番が来るのを待ってました。
アタシはセマフォなんて信じない。
デッドロックは無かったです。(T T)
0733デフォルトの名無しさん
2005/07/05(火) 07:38:240734デフォルトの名無しさん
2005/07/05(火) 09:33:430735デフォルトの名無しさん
2005/07/05(火) 09:40:380736デフォルトの名無しさん
2005/07/05(火) 10:04:15for (int i=0;i<threadnum;i++)
{
if(pthread_create(&tid[i],NULL,(THREADFUNC)threadRoutine,(void*)i) != 0)
{
perror("pthread_create");
}
}
と書くと、3行目のところで
error: invalid use of member (did you forget the '&' ?)
というエラーが出てしまいます。
プライベートメンバ関数の
threadRoutine
を
void threadRoutine(void* pParam);
と宣言するところを
static void threadRoutine(void* pParam);
にすると、コンパイル可能なようなのですが、今度は、そのメンバ関数内で、staticではないメンバ変数が使えなくなってしまいます。
どのようにすればよいのでしょうか?
0737736
2005/07/05(火) 10:06:02typedef void *(*THREADFUNC)(void *);
pthread_t tid[threadnum];
です。
0738デフォルトの名無しさん
2005/07/05(火) 10:06:390739デフォルトの名無しさん
2005/07/05(火) 16:20:26これって、ルイ14世のAA?
0740デフォルトの名無しさん
2005/07/05(火) 16:36:550741デフォルトの名無しさん
2005/07/05(火) 18:35:090742デフォルトの名無しさん
2005/07/05(火) 18:41:470743デフォルトの名無しさん
2005/07/05(火) 23:37:12なんでこう同じ質問がなんども... _ ̄|○
0744デフォルトの名無しさん
2005/07/06(水) 01:40:50Ψ
○| ̄|_| ̄|○
Ψ Ψ
○| ̄|_| ̄|○ ○| ̄|_| ̄|○
Ψ Ψ
○| ̄|_| ̄|○ ○| ̄|_| ̄|○
0745デフォルトの名無しさん
2005/07/06(水) 06:21:06関数はstaticにして、クラス内の変数を使いたければ、クラス自体をその関数に
ポインタとして渡すしかない。
0746デフォルトの名無しさん
2005/07/06(水) 08:56:21○| ̄|_ ̄|○ <君もC/C++の勉強をしたまえ!
0747デフォルトの名無しさん
2005/07/06(水) 09:09:19Javaつかえ。C++はあまりマルチスレッド向きではない。
0748736
2005/07/06(水) 14:25:390749デフォルトの名無しさん
2005/07/06(水) 14:31:450750デフォルトの名無しさん
2005/07/06(水) 14:34:21745に答えが書いてあるではないか。
0751デフォルトの名無しさん
2005/07/06(水) 14:47:590752デフォルトの名無しさん
2005/07/06(水) 16:40:00○| ̄|_ ̄|○ >>745はクラスをファーストクラスのオブジェクトのように語っておるが…
0753デフォルトの名無しさん
2005/07/06(水) 16:42:480754デフォルトの名無しさん
2005/07/06(水) 16:56:320755デフォルトの名無しさん
2005/07/09(土) 02:56:04最大化やウィンドウのリサイズを禁止するにはどうすればいいんでしょうか?
最小化はそのまま使えるようにしたいのですが…
0756デフォルトの名無しさん
2005/07/09(土) 06:21:530757デフォルトの名無しさん
2005/07/09(土) 09:11:270758デフォルトの名無しさん
2005/07/10(日) 11:52:37- Linuxでマルチスレッド・アプリケーションとなったとき、
pthreadは'事実上の標準'もしくは'アッタリマエ'か?
- pthradはLinuxの一部ではないが、たいていのディストリビューション
には添付されている。という認識で正しいか?
- スレッド起こすのにはcloneとかいうsystem-callがあるが、
こいつはコンテキストの切り替えにプロセスと同じことやる
ので決して速くはない。は真か?
0759デフォルトの名無しさん
2005/07/10(日) 12:06:00最後のはよくわからんが普通にスレッド起こすのは十分速いよ。
0760デフォルトの名無しさん
2005/07/10(日) 12:06:16- pthradは一部でも添付されてもいないが、pthreadは標準
- clone(2)はpthread_create(3)を実現するためのシステムコール。
あんたが使う類いのものじゃない。
0761デフォルトの名無しさん
2005/07/10(日) 13:53:41pthreadってのは単なるAPIのこと。
ttp://www.opengroup.org/onlinepubs/009695399/basedefs/pthread.h.html
で、UNIX系のOS上でC言語によるマルチスレッド・アプリケーションを記述するのなら、
pthread APIを使うのが「事実上の標準」。
ただし、pthread APIにはオプション的な扱いの関数などがあり、
これらは実装によっては使えないことがある。
Linux上で動作するpthread APIの実装としては、
- LinuxThreads … glibcに取り込まれたため、事実上の標準。
- Native POSIX Threading Library (NPTL) … LinuxThreadsの後継。これもglibcに取り込まれた。
- Next Generation POSIX Threading (NGPT) … NPTLの対抗馬だったが、あぼ〜ん
などがある。
ほとんどLinuxディストリビューションでは、LinuxThreadsかNPTLが使えるはず。
clone(2)ってのは、LinuxThreads、NPTLなどが内部で使ってるシステムコールであり、
アプリケーションプログラマが直接触るものではない。
0762デフォルトの名無しさん
2005/07/10(日) 18:24:170763デフォルトの名無しさん
2005/07/12(火) 23:40:36操作するライブラリ書いてるんだけど、
こういった場合スレッドセーフにするにはどこまでやるべき?
バッファやデバイス設定値を読み書きする所全て排他?
それともTLSでスレッド個別にメモリ確保のみ?
TLSだと複数スレッドから同一デバイスに対して
操作するときどうなるかわからんけどこれで許してもらえるかな?
仕様には特に明記されていないので、
俺様ルールでいいのかなとも思うんですが、
やっぱり普通はスレッドセーフにしないと駄目ですよね。
0764デフォルトの名無しさん
2005/07/13(水) 01:38:08(つまりリクエスト呼び出し復帰時に結果が返る)
排他が必要な場合が結構ある。
0765デフォルトの名無しさん
2005/07/13(水) 02:08:13どこまでやるべきかは、前提とすべきスレッディングモデルの定義による。
話はそれからだ。
0766デフォルトの名無しさん
2005/07/14(木) 01:15:07printfなどをmutexでロックしても同じでした。
初歩的なことかもしれませんが、よろしくお願いします。
#include <stdio.h>
#include <pthread.h>
void *ThreadFunc(void *pdata)
{
int i;
for (i = 0; i < 10; i++) {
printf("%c", *(char *)pdata);
}
return NULL;
}
int main(void)
{
int i;
pthread_t pthId;
char a[10];
for (i=0;i<10;i++) {
a[i] = i + '0';
pthread_create(&pthId, NULL, ThreadFunc, (void *)&a[i]);
}
for (;;) {
;
}
return 0;
}
0767デフォルトの名無しさん
2005/07/14(木) 01:25:25とかいうオチじゃないだろうな
0768766
2005/07/14(木) 02:21:27ありがとうございます。
やってみたのですが、バッファリングの問題ではないようです。
書き忘れましたが、どうやらスレッドが終了(return)するとロックするようなのです。
ネットにあるような単一スレッドのサンプルは問題なく動いています。
_beginthreadを使った場合はこのようなことは起こりません。
なんでだろう・・・。
0769デフォルトの名無しさん
2005/07/14(木) 07:16:20何でpthIdは1個?
0770デフォルトの名無しさん
2005/07/14(木) 07:22:430771デフォルトの名無しさん
2005/07/14(木) 07:29:36つまりCreateThread使ってるってこと?
Cランタイムライブラリを使う場合は_beginthreadを使う必要があると思うんだけど
0772デフォルトの名無しさん
2005/07/14(木) 08:11:24for (;;) {
;
}
ってなんだよ。
MSDOSならともかく、今時のOSで許されるコーディングじゃないぜ。
0773766
2005/07/14(木) 08:37:48返り値のIDを使わないからです。
配列にして個々にIDを入れても固まってしまいます。
>>770
メインスレッド側はjoinが必須なんでしょうか?
一応joinしてみたのですが、やはり固まります。
>>771
process.hの_beginthreadを使っています。
先ほど>>770さんに指摘されたjoinなどについて調べて、
結果的にはdetachを使用することでテストケースの場合はロックすることはなくなりました。
が、本件の方はdetachしてもロックしてしまいます。
もう少し調べてみます。
0774デフォルトの名無しさん
2005/07/14(木) 10:30:590775デフォルトの名無しさん
2005/07/14(木) 11:31:53printf("%c", *(char *)pdata);
}
fflush(stdout); <-- これ付け足したら動く予感
0776デフォルトの名無しさん
2005/07/14(木) 11:51:49> > 書き忘れましたが、どうやらスレッドが終了(return)するとロックするようなのです。
お前の言いたいのは、
・出力されません
に過ぎないのと違うのかと…
「ロック」言いたいだけと違うんかと…
0777デフォルトの名無しさん
2005/07/15(金) 00:34:30for( ; ; ) {{
sched_yield();
}
ってして他のスレッドを動かすのが基本。
○| ̄|_ ̄|○
0778デフォルトの名無しさん
2005/07/15(金) 00:48:27> ○| ̄|_ ̄|○
○| ̄|_ ̄|○ <お前が喋れよ。登場するだけかよ!
0779デフォルトの名無しさん
2005/07/15(金) 00:53:50おいおい、それもビジーループなんだよ。
待ってるだけなら pthread_join() を使うのが基本中の基本。
大丈夫かホントに。
0780766
2005/07/15(金) 01:36:12ロックと書いたのは固まったプロセスを強制終了するのに数秒かかるからです。
先に書いた通り、ロックは防げましたし、その原因も分かりました(join、detachしてなかった)。
しかしまだ怪しい部分があります。
joinしても期待した動作という意味では「ダメ」なのでソース曝します。
ttp://kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/img/723.c
実行毎に表示される数字の個数が違いますし、最後のEndも表示されません。
joinの使い方は間違ってないと思うのですが・・・。
環境がNT4sp6、デュアルプロセッサです。
0781デフォルトの名無しさん
2005/07/15(金) 02:05:190782デフォルトの名無しさん
2005/07/15(金) 02:37:34>>781 と同感なんだがどうやってるの?
cygwin?
0783デフォルトの名無しさん
2005/07/15(金) 04:47:190784デフォルトの名無しさん
2005/07/15(金) 09:16:06○| ̄|_ ̄|○ <Win2kのcygwinで実行したところ一瞬で終了して以下が表示された。
01021304215360742819536074281953607428195360742819536074281953607428195360742819
53674289536748956789End
0785766
2005/07/15(金) 09:35:41マズイな、こりゃOSを疑うべきなのか。
それが分かっただけでも収穫です、どうもありがとうございました。
0786デフォルトの名無しさん
2005/07/15(金) 10:04:31Cygwinは「UNIXと同じソースで動いたらラッキー」ぐらいのものだと思っ
といたほうがいい。
0787デフォルトの名無しさん
2005/07/15(金) 11:08:06コンパイルできないのはOKだが、誤動作は勘弁してほしいな。
Windows 使う場合は Windows の native thread を使えってことか。
まあ、API は pthread とそんなに違わないから (というか、たぶん
両方とも Mach の cthread の真似だよね、きっと)、wrapper ライブ
ラリ書いて pthread と Windows のどちらでも動くプログラムにする
のは難しくないよ。
0788デフォルトの名無しさん
2005/07/15(金) 11:20:120789デフォルトの名無しさん
2005/07/15(金) 11:24:35つうかstdoutの排他は?
0790デフォルトの名無しさん
2005/07/15(金) 11:33:140791デフォルトの名無しさん
2005/07/16(土) 02:25:170792デフォルトの名無しさん
2005/07/16(土) 02:39:390793デフォルトの名無しさん
2005/07/17(日) 09:25:35こんなのはたまたま動いているだけのプログラム。
0794デフォルトの名無しさん
2005/07/17(日) 09:26:170795デフォルトの名無しさん
2005/07/17(日) 10:26:300796デフォルトの名無しさん
2005/07/18(月) 14:29:49cygwinを疑うのは正しい姿勢の予感。
0797デフォルトの名無しさん
2005/07/18(月) 14:33:370798デフォルトの名無しさん
2005/07/18(月) 16:54:17ってのに妙に引っかかるな。
デュアルプロセッサで、デュアルプロセッサカーネル使っていないとか
実は、cygwinはデュアルプロセッサに対応していない。とか
0799デフォルトの名無しさん
2005/07/18(月) 20:53:37さすがにそりゃねーべ
今NTで十分テストされているとはあんまり思えないんだが、そのへんかな
0800デフォルトの名無しさん
2005/07/18(月) 21:27:03うちのWinマシンはデュアルではないけどHTです。
OSからはCPU2個に見えてる状態。
0801デフォルトの名無しさん
2005/07/18(月) 21:43:08なんかstdioの排他とかゆってる人いるけど、
glibcのstdioって、スレッドセーフじゃないの?
0802デフォルトの名無しさん
2005/07/18(月) 21:57:01glibc じゃなくて newlib のはず。
0803デフォルトの名無しさん
2005/07/18(月) 23:35:30スピンロックによる排他制御のために
x86のxchg命令によるatomicなtest&setを使っているが
これがlockプリフィックスつきでないからね。
newlib/libc/sys/linux/linuxthreads/machine/i386/pt-machine.h
のlong int testandset(int *spinlock)を見よ。
cygwinがnewlibのlinuxthreadをつかって
pthreadを実現していたらだめだろう。
これがx86 linuxというconfigureでのみ使われているんなら
関係ないんだろうけど。
それとは別にcygwinにはpthreadの実装があるから関係無いとは思うが。
正直その辺りの関係は俺もわからん。
0804デフォルトの名無しさん
2005/07/19(火) 00:30:16PT_EI long int
testandset (int *spinlock)
{
long int ret;
__asm__ __volatile__(
"xchgl %0, %1"
: "=r"(ret), "=m"(*spinlock)
: "0"(1), "m"(*spinlock)
: "memory");
return ret;
}
○| ̄|_ ̄|○ <ダメじゃん。 >>newlib
0805デフォルトの名無しさん
2005/07/19(火) 00:48:320806803
2005/07/19(火) 01:04:02The XCHG instruction always asserts the LOCK# signal regardless of
the presence or absence of the LOCK prefix.
逝って来ます。
0807デフォルトの名無しさん
2005/07/24(日) 21:50:22http://pc8.2ch.net/test/read.cgi/tech/1121644782/62
にて質問しましたがこちらのスレッドのほうが適切だと思いますのでこちらで質問させてください。
今gcc3.3.3にてスレッドを利用したプログラムを作成しようとしています。
5回程度のスレッド生成はうまくいきますが
Segmentation fault (core dumped)
が表示されてエラー終了してしまいます。
原因が分かりません。
どこがエラーの原因か指摘していただけませんか?
ソースは以下の通りです。
void *thread_test(void *tmp)
{
struct testarg baa;
//終了時にリソース割り当てを解放
pthread_detach(pthread_self());
baa.id = ((struct testarg *)tmp)->id;
baa.cmd = ((struct testarg *)tmp)->cmd;
free((struct testarg *)tmp);
printf("++++++++++++++++++++++++++++++++++++++++\n");
switch (baa.cmd){
case 1:printf("good morning\n");break;
case 2:printf("hello world\n");break;
case 3:printf("good bye\n");break;
default:printf("oh no!\n");break;
}
printf("++++++++++++++++++++++++++++++++++++++++\n");
return (NULL);
}
0808807続き
2005/07/24(日) 21:51:42#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
struct testarg{
int cmd;
int id;
};
void *thread_test(void *);
int main(void)
{
struct testarg *foo;char ss[80], *p, *pp;pthread_t threadID;int i = 0, j = 0;
for(;;){
j++;
printf("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n");
printf("%d回目\n", j);
//メモリ確保
if((foo = (struct testarg *)malloc(sizeof(struct testarg))) == NULL){
puts("malloc() error");
exit(1);
}
0809807続きの続き
2005/07/24(日) 21:52:33i %= 3;sleep(3);
foo->id = i;foo->cmd = i;i++;
//デバッグ用
printf("foo\nid = %d\ncmd = %d\n", foo->id, foo->cmd);
if(foo->id == -1)
break;
//クライアントスレッドを生成
if(pthread_create(&threadID, NULL, thread_test, (void *)foo) != 0){
puts("pthread_create() error");
exit(1);
}
printf("with thread %ld\n", (long int) threadID);
if(i==100)
break;
}
puts("good end");
return 0;
}
0810デフォルトの名無しさん
2005/07/24(日) 22:32:54うちでは落ちないでいつまでも動き続ける。
gcc は 3.3.5。
0811デフォルトの名無しさん
2005/07/24(日) 22:43:480812807
2005/07/24(日) 23:12:26thread_test()の中のpthead_detach()を削除することで解決しました。
>811さんありがとうございます。
すいませんが、一つ疑問があります。
pthread_create()の引数が取ってきたpthread_t型の変数で正しい値ならば
pthread_detach()はいつでもどこの関数でやってもいいんでしょうか?
>810さんありがとうございます。
いまバージョンアップ中です。
gcc 3.3.5にしたらどうなるかも報告したいと思います。
あと、一応私が書いたソースにはバグはなく、
Segmentation fault (core dumped) で落ちてしまうのは
gcc ver 3.3.3のせいだと考えてよいのでしょうか?
0813デフォルトの名無しさん
2005/07/24(日) 23:40:180814807
2005/07/25(月) 20:32:29int cmd;
int id;
pthread_t threadID;
};
として、
if(pthread_create(&foo->threadID, NULL, thread_test, (void *)foo) != 0){
・・・
}
void *thread_test(void *tmp)
{
struct testarg baa;
//終了時にリソース割り当てを解放
pthread_detach(((struct testarg *)tmp)->threadID);
・・・・・・
}
としたら問題が解決しました。
pthread_self()の問題だと思いますが、
原因はよくわかりませんでした。
失礼しました。
0815デフォルトの名無しさん
2005/07/26(火) 00:33:54あるスレッドがfcntlでファイルをロックしているとき、
同じプロセスの別のスレッドが同様にロックをしようとすると、
ロックが取得できてしまうんですか?
0816デフォルトの名無しさん
2005/07/26(火) 01:31:45fcntlはロックの所有権がプロセス単位だから。
0817デフォルトの名無しさん
2005/07/29(金) 22:40:150818デフォルトの名無しさん
2005/07/29(金) 23:05:361.スレッドの中でスレッドを作成した場合にいうのでしょうか
2.一つのプロセスで複数のスレッドを作成した場合にいうのでしょうか。
それとも両方マルチスレッドセーフというのですか?
0819デフォルトの名無しさん
2005/07/29(金) 23:07:350820デフォルトの名無しさん
2005/07/29(金) 23:08:540821デフォルトの名無しさん
2005/07/29(金) 23:34:22pthread_create(&threadID0, NULL, func0, (void *)foo);
pthread_create(&threadID1, NULL, func1, (void *)fooo);
func0()が実行されている間にメインスレッドにて新しく他のスレッドが作成される。
2.
void *func0(void *arg)
{
pthread_t theadID2;
pthead_create(&threadID2, NULL, function, (void *)arg);
}
メインスレッドから呼び出されたfunc0()の中で別のスレッドを作った。
こういうのを考えて818を書きました。
0822デフォルトの名無しさん
2005/07/29(金) 23:41:490823デフォルトの名無しさん
2005/07/29(金) 23:42:020824デフォルトの名無しさん
2005/07/29(金) 23:42:020825デフォルトの名無しさん
2005/07/29(金) 23:45:44{;;;;;;ゝ T辷iフ i f'辷jァ !i;;;;; >>821 お前にはマルチスレッドは無理。
ヾ;;;ハ ノ .::!lリ;;r゙
`Z;i 〈.,_..,. ノ;;;;;;;;>
,;ぇハ、 、_,.ー-、_',. ,f゙: Y;;f そんなふうにかんがえていた時期が
~''戈ヽ `二´ r'´:::. `! 俺にもありました
0826821
2005/07/29(金) 23:55:01{;;;;;;ゝ T辷iフ i f'辷jァ !i;;;;; 2chネラは真面目な人が多い
ヾ;;;ハ ノ .::!lリ;;r゙ 人を馬鹿にするようなことはないだろう
`Z;i 〈.,_..,. ノ;;;;;;;;>
,;ぇハ、 、_,.ー-、_',. ,f゙: Y;;f そんなふうにかんがえていた時期が
~''戈ヽ `二´ r'´:::. `! 俺にもありました
0827デフォルトの名無しさん
2005/07/29(金) 23:59:510828デフォルトの名無しさん
2005/07/30(土) 00:12:37マルチスレッドセーフを冒すのは、
1.〜
2.〜
それとも両方マルチスレッドセーフを冒すのでしょうか?
だと、思うのは俺だけか?
俺は、1.2.ともその可能性をはらんでいると思う
お互いを蝕むのを避けるために、踏切りの警報灯のように交互にチカチカ同期採る手法や
片方をlockさせる手法があるのでしょう
>181は気にすることはない
リアルで溜まったウサを晴らしたいヤシが吐き捨ててる場合もあるんだから
そういう肥溜めはシカトしときゃいい
0829デフォルトの名無しさん
2005/07/30(土) 00:20:28( ´�D`) 誤爆れすか?
0830デフォルトの名無しさん
2005/07/30(土) 00:25:350831デフォルトの名無しさん
2005/07/30(土) 00:36:13�A| ̄|_ ̄|�A <その関数はスレッドセーフである、とかなんとか言われるのである。
�B| ̄|_ ̄|�B <きっとね!
0832デフォルトの名無しさん
2005/07/30(土) 01:04:39は、誤解招くから、補足しとくと、
お互いがどこまで進んだか分からないと、迂闊にお互いのデータを使えないから、同期を採って、進行度を相互確認する
それと、親プロセス、子プロセスの関係の、マルチプロセス、要はforkというのもあるけど(知っているかもしれないけど)、
これの弱点は、同じOSのshell上で動くから、処理が重くなる。だから、マルチスレッドが推奨されてるわけだけど、
利点もあって、親が終了しても、子は動き続けられる
0833デフォルトの名無しさん
2005/07/30(土) 01:08:520834デフォルトの名無しさん
2005/07/30(土) 11:27:37○| ̄|_ ̄|○ < これ読め! http://docs.sun.com/app/docs/doc/819-0390/6n2qp46f3?l=ja&a=view
0835デフォルトの名無しさん
2005/07/30(土) 17:56:410836デフォルトの名無しさん
2005/07/30(土) 20:52:170837デフォルトの名無しさん
2005/07/31(日) 00:13:53使っているのですが、とても微妙な使用方法だと思うのですが改善する方法ないですか?
あとpthreadのデバッグってどうしてますか?
0838デフォルトの名無しさん
2005/07/31(日) 06:37:15君の頭を改善。
デバッガ。
0839デフォルトの名無しさん
2005/08/01(月) 00:16:55わらた
0840デフォルトの名無しさん
2005/08/02(火) 20:41:39C言語でマルチスレッドプログラミングについて教えてもらいたいです。
問題は、
(1)簡単なスレッドプログラミング及びスレッドの動作について解説せよ。
(2)相互封鎖や相互実行が起こるプログラムを作成し、その動作を解説せよ。
(3)マルチスレッドで、turnやflagを使った排他制御のプログラムを作成し、その動作を解説せよ。
(4)消費者・生産者問題のプログラムを解説せよ。
です。宜しくお願いします。
0841デフォルトの名無しさん
2005/08/02(火) 20:44:01スレ違いです。
↓あたりへどうぞ。
内藤ホライゾンがC/C++の宿題を片付けます 49
http://pc8.2ch.net/test/read.cgi/tech/1122705615/
ぼるじょあがC/C++の宿題を片づけますYO! 48代目
http://pc8.2ch.net/test/read.cgi/tech/1121471445/
0842デフォルトの名無しさん
2005/08/03(水) 02:12:13誘導先でも煙たがられてるし...
0843デフォルトの名無しさん
2005/08/04(木) 21:05:37変数をロックして共有するのではなく、メンバ変数みたいな感じで状態管理に使いたいんです。
errornoとかはそうなっているみたいなんですけど。
0844デフォルトの名無しさん
2005/08/04(木) 21:35:41TLS
ちと調べればすぐわかりそうな気がするが。
0845デフォルトの名無しさん
2005/08/04(木) 21:38:290846デフォルトの名無しさん
2005/08/04(木) 21:50:33"Thread Specific Data" とか "Thread Local Storage" と呼ばれるものだな。
普通はスレッドライブラリのAPIとして用意されているものだし、
最近のC/C++標準では __thread というキーワードで言語仕様にも採り入れられている。
ttp://gcc.gnu.org/onlinedocs/gcc/Thread_002dLocal.html
ttp://www.linux.or.jp/JM/html/glibc-linuxthreads/man3/pthread_key_create.3.html
ttp://www.microsoft.com/japan/msdn/library/ja/vccore/html/_core_Thread_Local_Storage_.28.TLS.29.asp
0847デフォルトの名無しさん
2005/08/05(金) 00:11:19Cでも単純にスレッドごとに構造体のインスタンス別々にしてやればいいジャンとか思うの俺だけ?
0848デフォルトの名無しさん
2005/08/05(金) 02:02:30スレッド内関数呼び出しのそのレベルでも、
スレッドローカルな大域変数のように扱えるのが、
スレッドローカルストレージフレームワークだから…
Common Lispの*special*変数も似た風に使えるけど、
あれよりはコストが安い。
0849デフォルトの名無しさん
2005/08/05(金) 03:02:180850デフォルトの名無しさん
2005/08/05(金) 23:56:31>最近のC/C++標準では __thread というキーワードで言語仕様にも採り入れられている。
9899:1999 でも 14882:2003 でもそんなキーワードは引っかからないぞ。
つーか、__ で始まってる時点で処理系依存の拡張じゃないのか?
0851デフォルトの名無しさん
2005/08/06(土) 08:55:10C99を__threadで拡張するとすると標準文書はこう変更されるってことなんだけど。
>5.51.1 ISO/IEC 9899:1999 Edits for Thread-Local Storage
>
> The following are a set of changes to ISO/IEC 9899:1999 (aka C99) that
> document the exact semantics of the language extension.
0853デフォルトの名無しさん
2005/08/06(土) 19:47:34int pthread_key_create(pthread_key_t *key, void (*destr_function) (void*));
int pthread_key_delete(pthread_key_t key);
int pthread_setspecific(pthread_key_t key, const void *pointer);
void * pthread_getspecific(pthread_key_t key);
のsyntax sugar?
0854デフォルトの名無しさん
2005/08/06(土) 19:51:04大域変数みたいに使うことはできる。
てかCreateThreadに渡すダミーのスレッドプロシージャにthisポインタ渡してメンバ関数を起動するだけだから。
(Win32での話)
0855デフォルトの名無しさん
2005/08/06(土) 20:19:16機能的には同じようなものだが、普通は__threadのほうが遥かに高速に動作する。
ttp://people.redhat.com/drepper/tls.pdf
上記PDFにあるように、ローダやダイナミックリンカなどと連係して
間接参照数回程度のコストで動作するようになっている。
まあ、逆に言うと、スレッドライブラリだけでなく、
ローダやリンカも対応してないと__threadは使えないってことになるが。
0856デフォルトの名無しさん
2005/08/07(日) 01:27:51windowsでpthreadの状態変数みたいなのはどう実現すればよいのでしょうか?
排他変数にMutexをつかうならSignalObjectAndWaitをつかえばよいんだけれども
CriticalSectionを使いたいんです。
0857デフォルトの名無しさん
2005/08/07(日) 01:30:480858デフォルトの名無しさん
2005/08/07(日) 09:09:080859デフォルトの名無しさん
2005/08/07(日) 13:02:32○| ̄|_ ̄|○ <オマエ「状態遷移マシン」て言ってみたかっただけだろ!
0860デフォルトの名無しさん
2005/08/07(日) 13:03:24マルチスレッド関係ないな
0861856
2005/08/07(日) 13:18:58そうなんですけど、pthreadの場合、 状態変数をwaitするとき
mutexを渡して内部でアトミックにmutexをアンロック→シグナル待ち→mutexのロックをしてて
これをwindowsで実現できないかなと・・・
WindowsのばあいMutexをWait〜系関数で待つことは出来るけど、CriticalSectionは使えない。
たとえばpthreadで状態変数をつかっているようなところを
windowsに移植するときはどうしたらよいのかなと思いまして・・・
0862856
2005/08/07(日) 13:20:21そうなんですけど、pthreadの場合、 状態変数をwaitするとき
mutexを渡して内部でアトミックにmutexをアンロック→シグナル待ち→mutexのロックをしてて
これをwindowsで実現できないかなと・・・
WindowsのばあいMutexをWait〜系関数で待つことは出来るけど、CriticalSectionは使えない。
たとえばpthreadで状態変数をつかっているようなところを
windowsに移植するときはどうしたらよいのかなと思いまして・・・
0863デフォルトの名無しさん
2005/08/07(日) 13:51:27もちろん、cond_waitに渡すmutexはCRITICAL_SECTIONで良くて、
Mutexを使っているのはWaitForで待つためらしい。
http://apr.apache.org/
0864デフォルトの名無しさん
2005/08/07(日) 14:18:120865856
2005/08/07(日) 14:46:06ありがとうございます。参考になりました。
どうやらcondに渡すのはCRITICAL_SECTIONみたいだけど、
cond内部でMutexを持っていてそれを用いて排他制御を行いつつ、
CRITICAL_SECTIONアンロック→シグナル待ち→CRITICAL_SECTIONロックしているみたい。
(apr-1.1.1\locks\win32\thread_cond.c)
0866デフォルトの名無しさん
2005/08/07(日) 15:33:00ばれたか。
でもWindowsでWindowMessageを使って実装する例とか、
専用のクラスの実装例とか、どんな問題があってどんなメリットがあるとか
そういうことを勉強したかったのもあるよ。
0867デフォルトの名無しさん
2005/08/08(月) 01:01:11シグナルとウエイトをアトミックにやる必要がある。
「アトミックに」ってところが重要で
シグナルしてウエイトするというようにバラバラやっていたのではダメ。
それをする手段は、Win32だと、SignalObjectAndWaitしか知らん。
0868デフォルトの名無しさん
2005/08/08(月) 03:11:150869デフォルトの名無しさん
2005/08/09(火) 16:17:47CRITICAL_SECTION ではなくて、Mutex が利用されていたな。
Win32 の Mutex は遅いから、メータードセクションを利用して
実装して欲しかった。
0870デフォルトの名無しさん
2005/08/09(火) 19:11:37今1.32のソース見たけど、クリティカルセクション使ってたよ
0871デフォルトの名無しさん
2005/08/09(火) 20:12:15メータードセクションってこれ何時頃から実装されてるの?
MSDNみて、こんなの有ったのかと目から鱗状態なんだけど。
95でも使えるっぽいから、相当前からある様なんだけど。
0872デフォルトの名無しさん
2005/08/09(火) 21:36:20APIとしてSDKに実装されてるわけじゃないのね。
MSDN英に.hと.cのフルソース上がってたからもらってきた。
mutexと置き換えて遊んでみる。>>869ありがと。
0873デフォルトの名無しさん
2005/08/10(水) 15:20:21クリティカルセクションのつもりでリソースを1にして、
同じスレッドで複数回 EnterMeteredSection すると、あとあと面倒だったかも。
0874デフォルトの名無しさん
2005/08/16(火) 18:00:27みなさんスゴイすね
0875デフォルトの名無しさん
2005/08/21(日) 13:45:16それなら自分でReentrantな実装にしちゃえば?
0876デフォルトの名無しさん
2005/08/22(月) 16:00:40以前AdvancedWindowsのオプテックスを
セマフォ的にしたものを作ったのを思い出した。orz
とても不毛な月曜の午前。
0877デフォルトの名無しさん
2005/08/26(金) 14:48:45stringとかのポインタをスレッドに渡し、スレッドより先にメインが終了してしまった場合、
そのstringはもう生きていないですよね。
こういうときはどうやって処理をすればいいのでしょうか?
0878デフォルトの名無しさん
2005/08/26(金) 14:52:35寿命管理ができないなら、実体で渡す。
実体渡しが嫌なら、サボらずにちゃんと寿命管理を行う。
0879デフォルトの名無しさん
2005/08/26(金) 14:52:340880デフォルトの名無しさん
2005/08/26(金) 15:11:450881デフォルトの名無しさん
2005/08/26(金) 15:44:49スレッドでの処理が終わるまでメインを待たせろつーの。。
0882デフォルトの名無しさん
2005/08/26(金) 22:18:120883デフォルトの名無しさん
2005/08/28(日) 13:15:09この原因はグローバル変数glbを使っていることです。
通常、同一プロセス内でmultithreadout()を使うと駄目ですが、
multithreadout()をdllファイルにしてもマルチスレッドアウトのままでしょうか?
0884デフォルトの名無しさん
2005/08/28(日) 14:06:11Yes.
DLL(が読み込まれたメモリ空間) はプロセススコープの資源。
0885デフォルトの名無しさん
2005/08/28(日) 14:07:040886デフォルトの名無しさん
2005/08/28(日) 14:30:371).マルチプロセスにする。
2).multithreadout()だけをexeファイルにして引数を受け渡す(パイプを使う&dllを使用しない)
3).multithreadout()をdllファイルにし、multithreadout()呼び出し専用の
exeファイルを作り、パイプを使う
2).3).の違いはmultithreadout()が静的か動的かなのですが、
他に解決する方法はありますか?間違った解決方法を考えていませんか?
また、処理のほとんど(90%以上)はmultithreadout()が行います。
呼び出し回数は数回程度です。
0887デフォルトの名無しさん
2005/08/28(日) 14:40:34と言う選択肢もあるはず
0888デフォルトの名無しさん
2005/08/28(日) 14:42:41か何かにリネームして、
multithreadout()は、
multithreadout()
{
static CriticalSectionとかMutexとか lock;
Lock(lock);
multithreadout_real();
Unlock(lock);
}
あたりにすればいいんじゃないかと思う。
例外処理とか、lockの初期化は適当に。
0889856
2005/08/28(日) 17:35:49broadcastのときwaitしているスレッドを数えるためにカウントしているんだけど、
イベント待ちの直後そのカウンタをインクリメントする必要があって、その部分がクリチカルになっていない。
どうなんだろう?自分は怖いんでカウンタをCRITICAL_SECTIONで囲んだけれども。
0890856
2005/08/28(日) 17:46:490891デフォルトの名無しさん
2005/08/30(火) 06:42:29古いイベントで使うようなselectとかとどっちが速い?
0892デフォルトの名無しさん
2005/08/30(火) 06:44:41○古いイベント志向
すまそ。
0893デフォルトの名無しさん
2005/09/01(木) 23:51:20ま、それはさておき、遅いか早いかは
実装による。
以上だ!
0894デフォルトの名無しさん
2005/09/01(木) 23:51:28ま、それはさておき、遅いか早いかは
実装による。
以上だ!
0895デフォルトの名無しさん
2005/09/02(金) 00:20:22ちゃんと排他制御しろよ
0896デフォルトの名無しさん
2005/09/02(金) 00:41:560897デフォルトの名無しさん
2005/09/02(金) 00:43:20誤爆しました。メンゴ
0898デフォルトの名無しさん
2005/09/02(金) 03:07:40イベントとか割り込みって、中でselect使ってんじゃね?
0899デフォルトの名無しさん
2005/09/04(日) 08:45:050900デフォルトの名無しさん
2005/09/04(日) 13:10:28それは昔の話で、select(3)の実装がpoll(2)を使わないように2,3年前に変わらなかったっけ?
0901デフォルトの名無しさん
2005/09/04(日) 18:49:220902デフォルトの名無しさん
2005/09/04(日) 19:39:03「イベントとか割り込みって、中でpoll使ってんじゃね?」
と言えばいい?
0903デフォルトの名無しさん
2005/09/04(日) 21:32:12たまにビジーループぶん回すのがいるからのう…
0905デフォルトの名無しさん
2005/09/05(月) 10:46:59んなわけねー(w
>>904
お前以外にループする奴はいない。in お前のプログラム&カーネル。
0906891
2005/09/05(月) 23:58:310907デフォルトの名無しさん
2005/09/06(火) 14:49:26windowsはどうなんですか?
0908899
2005/09/06(火) 21:37:49というか、こんなの聞いてどうなるものでもないような
0909デフォルトの名無しさん
2005/09/06(火) 22:23:37> signalとかbroadcast待ってる香具師ってスピンしてんの?
ロックが競合したときにmutexの入口でスピンすることはあっても、
signalとかbroadcastを待ってる状態(つまり条件変数をwaitしている状態)で
スピンし続けてCPUを離さないってことはありえない。
そんな実装があったら、条件変数の意味が無くなるだろ。
0910デフォルトの名無しさん
2005/09/06(火) 22:44:190911デフォルトの名無しさん
2005/09/06(火) 22:54:370912デフォルトの名無しさん
2005/09/06(火) 23:21:03spinってのはSMPで一つのCPUだけがポーリング対象の資源を
得ることが出来るようなポーリングの仕方のことを言う。
皆がアクセスできる皿と、自分の手元の皿を夫々がくるくる入れ替えて
手元に来た皿に肉が乗ってたら食べていい、みたいな感じ。
0913デフォルトの名無しさん
2005/09/07(水) 03:41:53一面的な説明で「仕方のことを言う」はいかがなものか。
0914デフォルトの名無しさん
2005/09/07(水) 03:55:32文句だけじゃなくて、一面だけというのなら別の面からとか
包括的な説明とか、内容あるレスつけようぜ。
0915デフォルトの名無しさん
2005/09/07(水) 07:23:03スレッドとかシグナルってハードレベルでどうなってるのか
わからなくて効率が全然読めないんだが、
その辺をユーザーレベルで理解できる本、サイトない?
0916デフォルトの名無しさん
2005/09/07(水) 09:07:10これ読むとWindowsでポーリング待ちなんて馬鹿げてると思うはず。
0917デフォルトの名無しさん
2005/09/07(水) 09:13:54Windowsよく知らないので、詳しく!
0918デフォルトの名無しさん
2005/09/07(水) 09:14:46http://www.amazon.co.jp/exec/obidos/ASIN/4894711893/
Solarisインターナル−カーネル構造のすべて
http://www.amazon.co.jp/exec/obidos/ASIN/4894714582/
この辺りの本が詳しいけどね。どのOSでも基本は同じだし。
この辺りが難しいようなら、
OSの基礎と応用−設計から実装、DOSから分散OS Amoebaまで
http://www.amazon.co.jp/exec/obidos/tg/detail/-/books/4894712067/
なんかが定番になっているけれど、同期関係は記述が少ないし、
そもそもこの本は全般的におおざっぱな解説に終始するな。
0919デフォルトの名無しさん
2005/09/07(水) 09:53:000920デフォルトの名無しさん
2005/09/07(水) 09:54:380921デフォルトの名無しさん
2005/09/07(水) 12:05:28「Advanced Windows」嫁
あとは「Win32 マルチスレッドプログラミング」
つーかこの話で本が1冊出来るかもよ
0922デフォルトの名無しさん
2005/09/07(水) 12:58:32非SMPではspin lockなど使わずにタダのループによるポーリングで十分
(カーネルモードで、割り込みを考慮しないとして)。
また、競合するスレッド/プロセスがいない場合には、SMPだろうが割り込みが
あろうが単純ループのポーリングで十分。
効率的な点については、spin lock の一サイクルはメモリ<->レジスタ間の
値の入れ替えで完了するので、行儀良く短いクリティカルセクションから
なるコードの場合は(並列度にもよるけど)、わざわざスケジューラをいじって
スレッドをシグナル待ちにするような処理よりも単にspin lockの方が効率が良い。
0923デフォルトの名無しさん
2005/09/07(水) 13:14:22> (カーネルモードで、割り込みを考慮しないとして)。
> また、競合するスレッド/プロセスがいない場合には、
殆んどあり得ない仮定を置いて、何を言っているんだが…
0924デフォルトの名無しさん
2005/09/07(水) 13:30:57バカ?スピンロックについての話なら、普通割り込みも競合もあるけど、
915は「スピンしないポーリングって可能なのか。」って聞いてるわけで、
単に「ポーリング」って言った場合には>>922の条件は良く有ることだと
思うけど。
0925デフォルトの名無しさん
2005/09/07(水) 14:06:080926デフォルトの名無しさん
2005/09/07(水) 14:22:090927デフォルトの名無しさん
2005/09/07(水) 14:33:01同期無しでただ読むだけで済むように設計すればいい
0928デフォルトの名無しさん
2005/09/07(水) 16:24:15Windowz使ってないので、「Advanced Windows」読んでも意味ないし
0929デフォルトの名無しさん
2005/09/07(水) 18:41:220930デフォルトの名無しさん
2005/09/07(水) 19:13:46Windowsは業界スタンダードだから意味あるはずだけどねえ
0931デフォルトの名無しさん
2005/09/07(水) 20:05:260932デフォルトの名無しさん
2005/09/07(水) 20:08:360933デフォルトの名無しさん
2005/09/07(水) 22:20:40APIとしてはコードのその場所でじっとwaitしてる形になると思うけど
イベントやsignal自体の内部実装(カーネル側?)
では結局はポーリングで実現されてたりするわけ?
0934デフォルトの名無しさん
2005/09/07(水) 22:24:370935デフォルトの名無しさん
2005/09/07(水) 22:28:170936デフォルトの名無しさん
2005/09/07(水) 22:34:22signal trampoline
0937デフォルトの名無しさん
2005/09/13(火) 18:52:56イベントやシグナルみたいな大掛かりなものはスレッド自体が
待ち状態になってスケジュールしなおされる。
スピンロックで待つのはWin32でSMPのEnterCriticalSection(記憶違
いかも)とか、Windows の WDM のコードとか、linux のカーネル内の
コードとかでスケジューラを動かすまでもないホンのちょっとの排他
処理を行うとき。
0938デフォルトの名無しさん
2005/09/13(火) 22:59:200939デフォルトの名無しさん
2005/09/16(金) 02:59:23スレッド間でメモリ共有するだけでいいでしょうか?何か気をつけることないですか?
0940デフォルトの名無しさん
2005/09/16(金) 03:10:070941デフォルトの名無しさん
2005/09/16(金) 03:35:40共有してると、アクセス排他制御とか同期制御とかが絶対必要。
0942デフォルトの名無しさん
2005/09/16(金) 03:52:230943デフォルトの名無しさん
2005/09/16(金) 07:09:44メモリ空間は共有してても、同じメモリアドレスを共有してなきゃ問題ないじゃん。
0944デフォルトの名無しさん
2005/09/16(金) 08:49:07財布は共有してても生活空間は共有しない
という独立思考の高い夫婦モデルだな
0945デフォルトの名無しさん
2005/09/16(金) 09:48:150946デフォルトの名無しさん
2005/09/21(水) 19:20:26なんか変じゃない?
スレッドがスケジューリングされなきゃ、何時まで経っても他スレッドが実行されず、
状態が変化しないのと違う?
0947デフォルトの名無しさん
2005/09/21(水) 20:05:03完全に協調型ならそうなりますな。
普通は外的要因で叩き起こされると思いまふが。
0948デフォルトの名無しさん
2005/09/21(水) 20:15:08>>937のどの部分に対していっているの?
0949デフォルトの名無しさん
2005/09/21(水) 20:16:490950デフォルトの名無しさん
2005/09/21(水) 23:40:48いつまでもspinlockの所有権をacquire しようとし続けると
デッドロックしてしまうということ。
なわけでデッドロックしないように考慮する必要がある。
具体的には、
Win32 API のCritical Section の場合にはInitializeCriticalSectionAndSpinCountで
「スケジューリングしないでぐるぐる回る回数(の上限)」を設定して使う必要があるし、
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/initializecriticalsectionandspincount.asp
Windows のカーネル内でKeAcquireSpinLock なんかを使う場合にはdispatch level とか
も考慮して、acquire したら自コンテキストの実行が中断されないうちにすぐreleaseすることが
要求されている。
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/kmarch/hh/kmarch/Synchro_f74a900d-aad5-4473-8f46-00531c9ade89.xml.asp
0951デフォルトの名無しさん
2005/09/21(水) 23:50:19>>937
> スケジューラを動かすまでもない
を「自分からyeild()しないで」等に書き直した方がいいって事ね。
0952デフォルトの名無しさん
2005/09/22(木) 03:02:54スピンロック等の低レベルな排他機構が必要なわけで…
0953デフォルトの名無しさん
2005/09/22(木) 11:44:45現在、通信系のプログラムを書いています。
あるデータを受信したら処理をして、その結果を送信元に返信する。
という関数があるのですが、
1).スレッドを作り、そのスレッドで処理をさせる。
2).ウィンドウプロシージャを作り、メッセージにデータのポインタを渡す。
ウィンドウプロシージャで処理を行わせる。
この2通りを考えてみたんですが、楽なのは2)です。
どっちの方法が有効でしょうか?
0954デフォルトの名無しさん
2005/09/22(木) 11:48:000955デフォルトの名無しさん
2005/09/22(木) 14:02:05結局1)が楽です。
0956デフォルトの名無しさん
2005/09/22(木) 16:32:07gcc(RHEL), MinGW(Win), Visual Studio .NET(Win)の各環境でC++を使って私用ミニツールなど
を作ったりして仕事してる、一介の営業マンです。最近はサービスでお客さん用のツールなんか
も作ったりし始めました。SE受注減らしてどうするんだって感じですが。
C/C++でのpthreadに関する質問です。
pthread_createでガーっと並列にスレッドを作って仕事をさせ、pthread_joinを回して終了を待つわけな
のですが、
pthread_joinはブロックするので、先頭のスレッドが長引いちゃうと後に続くスレッドが先に終わってても
ボケーっと待ってしまいますよね。
これを、スレッドが終了した順に処理する方法ってありますでしょうか?
よろしくお願いします。
0957デフォルトの名無しさん
2005/09/22(木) 16:46:40* 生きてるスレッド数を数えるカウンタを用意しておく。(スレッド数で初期化)
* 各スレッドは終わるときにカウンタを減らして、ゼロになったら pthread_cond_signal() みたいなことをする。
* メインは pthread_cond_wait() かなんかで待ち。
* 起こされた時にはスレッドは全部終わってるはず。
* もちろんカウンタをいじるときは排他制御。
0958デフォルトの名無しさん
2005/09/22(木) 16:48:56* 各スレッドは終わるときにカウンタを減らして、 pthread_cond_signal() みたいなことをする。
* メインは pthread_cond_wait() かなんかで待ち。
起きたときにカウンタがゼロになってたら全部終わってるはず。
0959デフォルトの名無しさん
2005/09/22(木) 16:53:21メインスレッドはワーカースレッドを終了を順次待ちつつ何かしてる必要があるなら、
キューを用意してスレッドが終了前に自分のpthread_tを追加するとか、
メインスレッドがイベントループなら終了を通知するイベントを投げるとか。
0960デフォルトの名無しさん
2005/09/22(木) 19:33:15逆です
早く終わったスレッドの順に次のジョブキューに入れるやり方ですね
0961デフォルトの名無しさん
2005/09/22(木) 19:36:140962デフォルトの名無しさん
2005/09/22(木) 19:42:450963デフォルトの名無しさん
2005/09/22(木) 20:10:03>早く終わったスレッドの順に次のジョブキューに入れるやり方ですね
その場合はスレッド終わっちゃいけないから、joinなんか使えないと思われ
0964デフォルトの名無しさん
2005/09/22(木) 20:30:460965デフォルトの名無しさん
2005/09/23(金) 01:37:09pthread_cleanup_push()で登録するとか。
0966956
2005/09/29(木) 20:31:031. 子スレッドはその仕事の最後にグローバル関数で
「俺は終わりましたフラグ」を立ててから死ぬ
2. メインのスレッドは全部の子スレッドの「俺は終わり
ましたフラグ」を監視しながらぐるぐる回ってる
3. あるスレッドの「俺は終わりましたフラグ」が立ったら、
そのスレッドの計算結果を取得して次の仕事に放り込む
んー、スレッドの数が不定なので、俺は終わりましたフラグの
作り方と監視の仕方の実装に工夫が要りそうですね。
0967デフォルトの名無しさん
2005/09/29(木) 21:40:28なぜスレッドを使って並列でしようとしてるのかが見えないんだけど・
本当にマルチスレッドにする必要あるのかな
0968デフォルトの名無しさん
2005/09/29(木) 21:43:230969デフォルトの名無しさん
2005/09/29(木) 21:56:27//スレッドに持っていく構造体
typedef struct tag tag;
struct tag{
tag *next;//初期化してNULLにしておく
・・・
};
//メインが持つグローバルデータ
tag *root;
tag *last;
int flg;
計算が終わった子は
flgが特定の値であれば待機。
flgが特定の値でなければ特定の値にして
rootがNULLでなければlast->nextに自分の構造体のアドレスを登録。
rootがNULLであればrootとlastに自分の構造体のアドレスを登録。
メインスレッドは
flgが特定の値であれば待機。
flgが特定の値でなければ特定の値にして、
構造体のデータを取り出す。
root=root->next;とする。
flgの値を戻す。
ま、こんな感じでどうざんしょ。
0970デフォルトの名無しさん
2005/09/29(木) 22:00:26漏れならこうするよ。
メインスレッド
1. ジョブをキュー(FIFO)に登録。
2. ワーカスレッドを妥当な数だけ生成
3. pthread_cond_wait() か何かで待ち、ジョブのキューが空になっていたら完了。
ワーカスレッド
1. ジョブをキューから取り出して実行
2. 完了したら、その結果を利用した「次の仕事」を(もしあれば)ジョブキューに入れる。
無ければスレッド終了。
3. 1に戻る
0971デフォルトの名無しさん
2005/10/01(土) 13:03:580972デフォルトの名無しさん
2005/10/03(月) 13:56:54ダンディーな方、教えてくださいませ。
0973デフォルトの名無しさん
2005/10/03(月) 14:47:01オススメと言うか、その2つは使い分けるもの。
Win32の場合の話だけど、
プロセス内でのスレッドの同期程度ならクリティカルセクションを用いる。
複数のプロセスで排他を行いたいなら、ミューテックスの類を使う。
SMPで無ければ効率は同じ。SMPの場合にはInitializeCriticalSectionAndSpinCount の説明を参照。
0974デフォルトの名無しさん
2005/10/03(月) 18:16:26なるほど、納得しました!
どうもありがとうございました。
0975デフォルトの名無しさん
2005/10/03(月) 19:09:16まだあった・・
複数の同期オブジェクトを待ったり、待っている最中にWindowメッセージや
COMのLRPC(外部スレッド/プロセスからのCOM呼び出し)を処理する必要
があるなら Mutex。
0976デフォルトの名無しさん
2005/10/03(月) 19:28:00色々違いがあるんですね。
ご丁寧に有難うございましたm(_ _)m
0977デフォルトの名無しさん
2005/10/11(火) 23:14:030978デフォルトの名無しさん
2005/10/29(土) 03:13:14・データは木構造
・IOからメモリに展開するスレッドは複数
・そこにUI スレッドや、計算スレッドが頻繁にアクセスする。リーダーとライターが複数ずついる。
・ためしにクラスレベルロックみたいのでやったらUIスレッドでCPUが100%言ってないのにたまに固まる(1秒以下)ことがある。
こういう場合ってどんな風にするもんなんでしょう。粒度さげると書くのが('A`)マンドクさくなるしデッドロックの危険も出てくる。
一般解や俺ならこうしてるってのがあればよろ。
0979デフォルトの名無しさん
2005/10/29(土) 09:20:38UI(View)側にデータのコピーを持たせるしかないとオモウヨ
単一データでうまくいくのは、wordやexcelみたいに
UIイベントだけがDOCの更新トリガになる場合だけだとオモウ
おまいさんのはそうでないように見える
極端にいうとネットゲー。
0980978
2005/10/29(土) 10:18:45今度の場合、単一データに値するのがひとつのツリーノードなので・・・
ある画面で頻繁に処理する場合は特定のデータを大元から抜き出してしょりすればいいんだけど、今回はその範囲が特定できない。
その特定のデータを抜き出す作業自体が大元のデータにアクセスする作業であり、それが頻繁に発生する。
そうすると粒度をさげるしかないんだけれど・・・
オブジェクト内のデータを親ノードや子ノードへの連結ポインタ部分、そのノードのプロパティなどに分けてロックする方針を変えるとかも考えたけれど複雑になりそう・・・
0981デフォルトの名無しさん
2005/10/29(土) 10:43:11UIから更新操作が入るかどうかぐらいは答えろよ
0982デフォルトの名無しさん
2005/10/29(土) 12:11:40詳しく。
・ツリー上にのどが存在
・ノードには他のノードに対するポインタ情報(親ノード、子ノード)とそのノード自身のデータが存在する。
・ノードはスレッドにより随時更新される。
・更新内容はそのノード自身データの更新とノードに対するポインタの更新(親ノードの変更、子ノードの追加・削除)が存在
・ノードのデータを読み処理するスレッドあり。
・読み込み処理としてはそのノードのみのデータを処理するもの、下位ノードすべてのノードの合計など複数ノードのトラバースが必要なものがある。
・読み込み処理のスレッドから更新処理を行う可能性あり。例:条件にあるノードを探し、該当するものを更新
・UIスレッド以外にも読み込みスレッドが存在する。
・ノード数は十万単位でありクラスレベルロックなどでは不可。ただしすべてメモリ上に展開できるものとする。
こんなところです。
ポイントはノード自身のデータとポイントに関する処理の区分け。ノード間をトラバースしながらの処理でのデッドロック回避かと思ってます。
この辺で一般解などあれば参考にしたいです。
0983デフォルトの名無しさん
2005/10/30(日) 06:27:05低脳だな。あんな簡単なもの3日あればマスターだよ。問題なし。
0984デフォルトの名無しさん
2005/10/30(日) 08:17:19ツリーはOrderdTreeなの?
(Full)OrderdTreeは削除で上位ノードの変更も必要だから、
どうしても削除の並列度が下がるよね。
実装以前にそういう抽象的なレベルでの設計ができているの?
>>982には要件が書かれてないから、その辺疑問なんだけど。
Concurrent (ordered) treeあたりでググってみるとかね。
レス数が950を超えています。1000を超えると書き込みができなくなります。