[表示 : 全て 最新50 1-99 101- 201- 301- 401- 501- 601- 701- 2chのread.cgiへ]
Update time : 05/09 09:53 / Filesize : 193 KB / Number-of Response : 799
[このスレッドの書き込みを削除する]
[+板 最近立ったスレ&熱いスレ一覧 : +板 最近立ったスレ/記者別一覧] [類似スレッド一覧]


↑キャッシュ検索、類似スレ動作を修正しました、ご迷惑をお掛けしました

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



1 名前:デフォルトの名無しさん mailto:sage [2007/08/13(月) 21:35:32 ]
マルチスレッドプログラミングについて語るスレ。

その1 pc3.2ch.net/tech/kako/997/997345868.html
その2 pc5.2ch.net/test/read.cgi/tech/1037636153/
その3 pc8.2ch.net/test/read.cgi/tech/1098268137/
その4 pc8.2ch.net/test/read.cgi/tech/1130984585/
その5 pc11.2ch.net/test/read.cgi/tech/1157814833/

OS・言語・環境は問わないが、それゆえ明記すべし。
テンプレ

【OS】

【言語】

【実行環境】

【その他突起する事項】

513 名前:デフォルトの名無しさん mailto:sage [2008/02/03(日) 11:18:51 ]
ExitProcess

514 名前:デフォルトの名無しさん mailto:sage [2008/02/03(日) 11:33:51 ]
>>512
WaitoForSingleObjectとSetEventを使う。


515 名前:デフォルトの名無しさん mailto:sage [2008/02/03(日) 12:06:49 ]
assert(0)

516 名前:デフォルトの名無しさん mailto:sage [2008/02/03(日) 17:58:20 ]
>>514
Waito ?

517 名前:デフォルトの名無しさん mailto:sage [2008/02/03(日) 18:28:11 ]
WaitoSinguruObujecuto と SinguruIvento

518 名前:SettoIvento ならわかるが... mailto:sage [2008/02/03(日) 21:12:20 ]
SinguruIvento ?

519 名前:514 mailto:sage [2008/02/03(日) 21:19:11 ]
ゆるしてっ!!


520 名前:デフォルトの名無しさん mailto:sage [2008/02/04(月) 19:47:15 ]
>>512
俺を使え。全力でとめてやるぜ

521 名前:デフォルトの名無しさん mailto:sage [2008/02/08(金) 14:49:26 ]
生成したスレッドから、
ウィンドウハンドルを使用するマクロを使うためにはどうすればいいですかね?



522 名前:デフォルトの名無しさん mailto:sage [2008/02/08(金) 14:54:37 ]
わかりやすい日本語でお願いします。

523 名前:デフォルトの名無しさん mailto:sage [2008/02/08(金) 18:17:55 ]
>>521
ウインドウハンドルが欲しいのかな?


524 名前:デフォルトの名無しさん [2008/02/11(月) 23:34:04 ]
Visual Studio.NET 2003で、Win32API、C++のプログラムをしてるんですが、
複数スレッド同時に、クラスのオブジェクトをnewしまくると、

・HEAP[aaa.exe]: HEAP: Free Heap block 3c04d0 modified at 3c04e0 after it was freed
・0xC0000005: 場所 0xfeeefeee に書き込み中にアクセス違反が発生しました。 。
・0xC0000005: 場所 0xfeeefeee を読み込み中にアクセス違反が発生しました。 。

などのエラーがでます。
何か回避方法はないでしょうか?

newしてるのは同じクラスのオブジェクトですが、
static変数は持っておらず、グローバル変数も共用してません。
共用のものとしてはstatic関数を持ってますが、使ってはいません。

525 名前:デフォルトの名無しさん mailto:sage [2008/02/12(火) 00:22:37 ]
> 何か回避方法はないでしょうか?

バグを直す。

526 名前:デフォルトの名無しさん mailto:sage [2008/02/12(火) 00:41:03 ]
ランタイムがシングルスレッド用になってんじゃね?

527 名前:524 mailto:sage [2008/02/12(火) 00:58:26 ]
>>525
シンプルな以下のクラスでテストしてみたんですが、
やっぱり同じエラーが出ます。

class TestClass{
public:
TestClass();
virtual ~TestClass();
};
TestClass::TestClass(){}
TestClass::~TestClass(){}

>>526
ランタイムってなんでしょうか?
VCで設定するものですか?それとも実行する環境に依存するもの?

528 名前:デフォルトの名無しさん mailto:sage [2008/02/12(火) 01:01:02 ]
クラスの定義よりも寧ろ、「newしまくる」方を晒せよ。

529 名前:524 mailto:sage [2008/02/12(火) 01:06:18 ]
>>526
ありがとうございます!

VCの設定で、
プロジェクトのプロパティ→C/C++→ランタイムライブラリを、
マルチスレッドデバッグにしたらエラーが出なくなりました。

530 名前:デフォルトの名無しさん mailto:sage [2008/02/12(火) 01:11:48 ]
ヤレヤレ

531 名前:デフォルトの名無しさん mailto:sage [2008/02/12(火) 12:34:51 ]
>>529
シングルスレッド用でコンパイルが通ったてことはCreatThreadを使ってるのかな?_beginthreadExを使ったほうがいいよ。




532 名前:524 mailto:sage [2008/02/13(水) 02:11:46 ]
>>531
_beginthreadExは知りませんでした。
調べてみます。ありがとう。

533 名前:デフォルトの名無しさん mailto:sage [2008/02/13(水) 10:20:00 ]
グローバル変数使う標準Cライブラリ(strtokとか)を使う場合、_beginthreadExじゃないとまずいことになる。
そうじゃないならCreateThreadでも特に問題なかったと思う。

534 名前:デフォルトの名無しさん mailto:sage [2008/02/13(水) 23:11:17 ]
>>533
mallocやnewとか、VCランタイムのいろんなものがやばい。
コンパイラベンダでも無い限り、CreateThread使う必要なし。


535 名前:デフォルトの名無しさん mailto:sage [2008/02/14(木) 00:54:08 ]
マルチプロセッサ環境でストアバッファのデータを反映させたい場合
pthreadだとmutex使えばいいんでしょうか?

536 名前:デフォルトの名無しさん mailto:sage [2008/02/14(木) 01:38:26 ]
>>535
同期プリミティブの使用でフラッシュしてくれなかったら、どうにもならない。


537 名前:デフォルトの名無しさん [2008/02/14(木) 02:08:24 ]
>>535
んー、volatileかな。

538 名前:デフォルトの名無しさん mailto:sage [2008/02/14(木) 13:03:57 ]
メモリバリア

539 名前:535 mailto:sage [2008/02/14(木) 23:26:30 ]
恥のかきついでに。。。
フラッシュされるということはmutexのアンロック後に
他のスレッドから同期プリミティブを使用せずにメモリを参照しても
mutexがアンロックされた時点までの操作は完了してると見なしていい
この解釈は合ってるのかな

540 名前:デフォルトの名無しさん mailto:sage [2008/02/15(金) 01:55:14 ]
posixがそれを要求してる、って
d.hatena.ne.jp/yupo5656/20040618/p2
ここらへんに書いてあった。

541 名前:535 mailto:sage [2008/02/15(金) 02:19:14 ]
なるほど。
www.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap04.html#tag_04
ここにある関数を呼び出した時点でメモリが同期されるわけですね
ありがとうございました



542 名前:デフォルトの名無しさん mailto:sage [2008/02/15(金) 11:02:56 ]
>>539
mutexのアンロックで書き込み側プロセッサのキャッシュがメモリと同期されても、
それだけでは読み込み側プロセッサのキャッシュはメモリと同期されないのでは?
読み込み側にも同期プリミティブ(具体的にはmutexのロック)が必要なはず

543 名前:535 mailto:sage [2008/02/16(土) 15:34:51 ]
>>540の"同時アクセスさえ防いでおけばすべてうまく行く"
というのを信用したんですが・・・どっちが正しい?

544 名前:デフォルトの名無しさん mailto:sage [2008/02/16(土) 16:21:03 ]
キャッシュと同期オブジェクトは別じゃないのか。

545 名前:デフォルトの名無しさん mailto:sage [2008/02/16(土) 16:21:28 ]
同時アクセスを防ぐ=読み側もmutexなりでロックしにいく

でも読み込みだけならロックいらないよね。volatile最強!

546 名前:デフォルトの名無しさん mailto:sage [2008/02/16(土) 16:39:51 ]
>>545
一応マジレスしておくと、volatileでは確実に読めることが保証されない。安全を期するならロックした方が楽。
# 理由については割愛。

547 名前:デフォルトの名無しさん mailto:sage [2008/02/16(土) 17:41:24 ]
CPUのマニュアル読むのが一番

548 名前:デフォルトの名無しさん mailto:sage [2008/02/16(土) 17:42:24 ]
>>543
読み込み側もmutexをロックしないと、同時アクセスを防げないじゃないか。
まだ書き込み側がmutexをアンロックする前かもしれないのに。

549 名前:デフォルトの名無しさん mailto:sage [2008/02/17(日) 15:13:07 ]
pthreadの、pthread_join()とsleep()の関係について質問します。

主系スレッドZにて、子スレッドa, b, cをpthread_create()により作成します。子スレッドa, b, cは一定時間経過後に処理を行います。一定時間経過するのを待機する場合、sleep()を使っています。

主系スレッドZでは、子スレッドa, b, cが終了するのを待つために、pthread_join()を使っています。しかし、子スレッドa, b, cがsleep()で待機しているときを、子スレッドが終了した時と勘違いしているようです。

現在では、子スレッドa, b, cが終了する前に、それぞれが主系スレッドZにsignalを送るようにしています。主系スレッドZでは、signalが来るまで待機としています。

最初にやっていた、pthread_join(), sleep()の組合せの方がスマートだと思うのですが、こちらの方法でうまくやるのは無理なのでしょうか?

550 名前:549【言語】【実行環境】【その他突起する事項】 mailto:sage [2008/02/17(日) 15:18:17 ]
環境を書き忘れていました。

【OS】debian/etch

【言語】C(pthread/posix)

【実行環境】
glibc2.3.6
gcc4.1.2
kernel 2.6.18-6-486
libpthread NPTL2.3.6

551 名前:デフォルトの名無しさん mailto:sage [2008/02/17(日) 15:21:59 ]
突起フイタ



552 名前:デフォルトの名無しさん mailto:sage [2008/02/17(日) 15:50:00 ]
>主系スレッドZでは、子スレッドa, b, cが終了するのを待つために、
>pthread_join()を使っています。しかし、子スレッドa, b, cがsleep()で待機しているときを、子スレッドが終了した時と勘違いしているようです。

コード晒してみてくれ

553 名前:549 mailto:sage [2008/02/17(日) 16:23:25 ]
どうやら勘違いだったようです。

真の原因は、Zでログファイル用に
fp_glb=fopen("Z.log","w");
として、fpを持っているのですが、子スレッドが、
fprintf(fp_glb, "log write thread name [a]\n");
として、共通のログファイルに書き込みを行おうすると、死んでいるようでした。子スレッドでは、書き込む前に排他ロックを行っているのですが、主系スレッドでは行っていないことが原因だと思っています。

554 名前:デフォルトの名無しさん mailto:sage [2008/02/17(日) 16:24:12 ]
無茶苦茶だな。

555 名前:デフォルトの名無しさん [2008/02/19(火) 09:12:29 ]
VC++にpthreadはないのでしょうか?

556 名前:デフォルトの名無しさん mailto:sage [2008/02/19(火) 11:47:28 ]
>>555
>>494

557 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 19:33:15 ]
自分から終了することもあるし、外部から終了通知を受け取ることもある
ようなスレッド関数について質問です。
こういう場合、(スレッド関数はすでに終了してるぞ!)フラグや
(外部から終了通知が出されたぞ!)的な何かはいったいどうやって実装していますか?
自分はいつも

bool isActive = false;
bool IsThreadActive() { lock {return isActive} }
void SetThreadActive(bool flag) { lock {isActive = flag; } }
void ThreadFunc() {
 SetThreadActive(true);
 try {
  while (IsThreadActive()) {
   ... いろんな処理
  }
 } catch(...) {
  SetThreadActive(false);
  throw;
 }
}

的なやり方でやってしまっているのですが、
これって正しいのでしょうか?
また、もしあればもっといい方法を教えていただけると助かります。

558 名前:557 mailto:sage [2008/02/20(水) 19:36:19 ]
書き忘れました
while (IsThreadActive()) {
 ... いろんな処理
}
の内部から breakで抜けることもあります。
(SetThreadActive(false)も付け足してください)

559 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 19:41:56 ]
終了要求フラグとすでに終了してるぞフラグは別にした方がいいんじゃないかな
すでに終了してるぞフラグが要るかどうか(何に使うのか)にもよるような

560 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 20:03:24 ]
スレッドでいくつかの処理を行いたいのですが、
その処理の内容が
1、実はまったくスレッドが必要にならない場合がある
2、処理の行われる間隔が長いので、
  続く処理が無いようならとりあえずスレッドを終了させたい
というもので、ある処理のリクエストが入ったとき、

*スレッドが稼動していればそのままリクエストを追加
*稼動していなければ新たにスレッドを起動して処理を開始
*終了要求が入ったらすべてのリクエストを破棄&スレッドを終了

ということがしたいのです。

561 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 20:13:33 ]
スレッドを終了する要因がメイン側からの要求だけなら、
スレッドが生きてるかどうかはメイン側が完全に把握してるはずなので、
子スレッド側から「すでに終了してるぞ」フラグを操作する必要はないはず



562 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 20:23:14 ]
>>561
スレッドを終了させる要因には、メイン側からの通知もそうですが、
子スレッド内での例外や、自殺も含まれます。
結局、これはフラグで操作するしかないのでしょうか?
というのも、「スレッドをフラグで操るなんて危なすぎ」みたいな話を聞いたことがあるので・・・
それにconditionとか、なんとなくかっちょいい機能を使いたいような気もします

563 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 20:30:57 ]
>>561
すいません。分かりにくかったですね。これも追加してください
*リクエストが無ければ、とりあえずスレッドを終了(再びリクエストが来たら再度起動)

564 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 20:55:19 ]
例外で死ぬなら、残ったリクエストを誰かが引き継がなきゃいけないような・・・
キャッチできるなら再開して残りのリクエストを処理する方がいいんじゃないかな
リクエストキューとスレッド生存フラグは単一のロックで操作しないとまずいことになると思う
終了要求フラグは別のロックでも構わないけど、一緒にしとくのが無難かと

親側
lock {
リクエスト投入
if (スレッド生存==false) { 子スレッド起動; スレッド生存=true }
}
子側
loop {
lock {
if (終了要求) { スレッド生存=false; return }
リクエスト取り出し
if (もうリクエストないよ) { スレッド生存=false; return }
}
try { リクエスト処理 } catch { エラーメッセージを吐くとか }
}
たぶんこんな感じ?

565 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 20:57:14 ]
終了してるかどうかはそのためのもの(WinならWaitForSingleObjectとか)で調べるでしょう。

566 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 21:08:10 ]
>>565
スレッドが例外とかで突然死した場合はメイン側でWaitFor〜なりで捕まえて再起動するしかないけど、
リクエスト投入時の新スレッド起動判断をそれでやると、
その直前にリクエストがキューにないと判断したため自発的に終了しつつあるスレッドと入れ違いになる可能性が・・

567 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 21:25:45 ]
>>564
おお、なるほど。そういう風にやればいいんですね。
>>557だと、「いろいろな処理」中にisActiveがfalse、
かつリクエスト追加でフラグがtrueになるとスレッド二つになりますし、
タイミング的にスレッド消える危険もありますね。
それをテンプレにしていろいろ試してみたいと思います。
ありがとうございました。

568 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 22:14:25 ]
俺ならこんな構造にする。
・リクエストを出すスレッドはイベントループを持つ。
・作業スレッドはリクエストキューと終了要求フラグを見ながら愚直に仕事をする。
・作業スレッドが処理を1つ済ませたり終了したりしたら、
1回だけ呼ばれるコールバックを要求元スレッドのイベントループに登録する。
・コールバックは要求元スレッドで走り、処理結果やエラーを通知する。
問題は、イベント待ちで寝ているときに目を覚まさせる方法が
既成のイベントループに必ずしも用意されていないこと。

569 名前:デフォルトの名無しさん mailto:sage [2008/02/21(木) 09:40:13 ]
毒を投げればいいだろ

570 名前:デフォルトの名無しさん mailto:sage [2008/02/21(木) 09:48:43 ]
基本的にスレッドはブロッキング操作があるようなものを非同期で行わせるために俺は使ってるから,
イベントループとか使えないんだよね

571 名前:デフォルトの名無しさん mailto:sage [2008/02/21(木) 12:56:56 ]
一方、漏れは匙を投げた。



572 名前:デフォルトの名無しさん mailto:sage [2008/02/21(木) 19:03:51 ]
double pi=3.14159265358979823846;
if((fp=fopen("PI.bin","wb"))==NULL)
printf("\aファイルをオープンできません。\n");
else{
fwrite(&pi,sizeof(double),1,fp);
fclose(fp);
}

C言語で↑のようにpiをバイナリファイルに書き込んで、
BZというバイナリエディタで開いたのですが”$-DT・ @”(文字部)と表示されました。
その後にfread関数でPI.binの内容をプログラム上で出力すると3.1415926……とさきほどの数字に限りなく近い数字できちんと表示されたのですが
バイナリエディタで見ると変な文字に変わってしまうのは、何が原因なのでしょうか?これをバイナリファイルとして正しく見れる方法はあるのでしょうか。

573 名前:デフォルトの名無しさん mailto:sage [2008/02/21(木) 19:04:04 ]
ブルータス!お前もか!

574 名前:デフォルトの名無しさん mailto:sage [2008/02/21(木) 19:07:45 ]
>>572
スレタイと何か関係あった?

575 名前:デフォルトの名無しさん mailto:sage [2008/02/21(木) 19:10:06 ]
>>574
完全に誤爆です
すいませんでしt

576 名前:デフォルトの名無しさん [2008/02/26(火) 01:43:14 ]
>>572
原因はお前の頭が悪いこと。
そもそもスレ違い。

577 名前:デフォルトの名無しさん mailto:sage [2008/02/26(火) 04:30:54 ]
5日も前に誤爆だったと謝罪済みのレスに文句言う馬鹿って一体何考えてるの?

578 名前:デフォルトの名無しさん mailto:sage [2008/02/26(火) 10:36:12 ]
脊髄で書いてるのだろう

579 名前:デフォルトの名無しさん mailto:sage [2008/02/27(水) 17:15:56 ]
脊髄電脳化w

580 名前:デフォルトの名無しさん mailto:sage [2008/02/28(木) 00:56:57 ]
マルチスレッド対応の
ハッシュリストのソースコードとかある?

581 名前:デフォルトの名無しさん mailto:sage [2008/02/28(木) 12:32:38 ]
ハッシュは速いのが売りなんだから、まるごとクリティカルセクションで包んでおけ



582 名前:デフォルトの名無しさん mailto:sage [2008/02/28(木) 12:51:50 ]
>>580
Javaのjava.util.concurrent.ConcurrentHashMap

583 名前:デフォルトの名無しさん mailto:sage [2008/02/28(木) 13:19:30 ]
javaならHighly Scalable JavaのNonBlockingHashMap等
ttp://sourceforge.net/projects/high-scale-lib

584 名前:デフォルトの名無しさん mailto:sage [2008/02/28(木) 16:02:03 ]
>>581
意味ねーw

585 名前:デフォルトの名無しさん mailto:sage [2008/02/29(金) 23:39:30 ]
同期処理なんてしなくてよし。
すべては運任せ。
マルチスレッドの邪神様に任せておきなさい。

586 名前:デフォルトの名無しさん mailto:sage [2008/03/03(月) 11:34:48 ]
コア1個ならなんとかなるさ、きっと

587 名前:デフォルトの名無しさん mailto:sage [2008/03/03(月) 21:36:55 ]
●5 コアは一個だが、HTだった

588 名前:デフォルトの名無しさん mailto:sage [2008/03/03(月) 23:09:15 ]
HTといえば、マルチコアの場合は異なるコア同士が同じキャッシュラインに
アクセスしない方がいいけど、HTの場合は逆になるの?

589 名前:デフォルトの名無しさん mailto:sage [2008/03/03(月) 23:49:44 ]
マルチプロセッサ・マルチコア・HTで論理CPUが8個とかってどこのXEONだっけ?

590 名前:デフォルトの名無しさん mailto:sage [2008/03/04(火) 16:41:04 ]
AMDのです

591 名前:デフォルトの名無しさん mailto:sage [2008/03/04(火) 22:30:10 ]
>>588
キャッシュが共有の場合は、キャッシュラインが同じでもOK。そのほうが効率よい。
キャッシュが分かれている場合は、同じキャッシュラインへの書き込みは最悪になる。MESIプロトコルで具具ってみよう。



592 名前:デフォルトの名無しさん mailto:sage [2008/03/05(水) 13:50:16 ]
journal.mycom.co.jp/articles/2008/03/02/isscc3/003.html
HTMって性能出るのかな。。

593 名前:デフォルトの名無しさん mailto:sage [2008/03/05(水) 14:19:28 ]
トランザクションメモリって、
JavaのAtomicReference#compareAndSetみたいなのじゃだめなの?

594 名前:デフォルトの名無しさん mailto:sage [2008/03/05(水) 16:58:48 ]
失敗したとき、その中でやったことは全部無しにしてくれるんだろうか?
>>593 良い場合もあるけど、例えば、複数のHashMapとかをatomicに操作したい場合は面倒じゃない?

595 名前:デフォルトの名無しさん mailto:sage [2008/03/05(水) 23:18:48 ]
マルチスレッドなくなってしまう。
今までがずっとCPUだと思っていたものは、実はスレッドなんで、。

596 名前:デフォルトの名無しさん [2008/03/06(木) 02:46:25 ]
Windowsでの条件変数実装の話題蒸し返したいので、俺の調査結果を晒してみる。

apr -> 再帰mutex非サポートぽい?簡潔過ぎるし、他にもバグあるだろ絶対。
yaneSDK3rd::LockObject -> すごく分かりやすい実装。再帰ロックしてのwaitにバグあり。修正は簡単。
boost::condition -> 複雑。完璧なのか?タイムアウト監視にシステム時刻使ってるのが嫌。

自前のC++ライブラリ構築して使ってるが、
yaneSDK3rdベースの実装からboostベースに交換してみようと思って
とりあえず、boost::xtime使ってる部分はGetTickCountに変えた。
システム時刻は某通信プロトコルでいつでも変更されてしまうので。
っつーか、clock()とかにもFILETIME使ってるのってどうなのよ・・・
boost実装に>>473のような問題が無いか検証しようとしてるが、
こいつのアルゴリズムは結構複雑で手強そうだ・・・
肝心のACEのソースはまだ読んでない。

597 名前:デフォルトの名無しさん mailto:sage [2008/03/07(金) 02:19:24 ]
条件変数の用途って
生産者/消費者的な使い方がかなりの部分を占めると思うんだけど、違うかな?
そういう用途のみに限れば、IOCP使えば充分なんじゃないのかね。
キューにデータがあるときはカーネルに行かないって言明されてるし。

598 名前:デフォルトの名無しさん mailto:sage [2008/03/08(土) 02:15:16 ]
無知を承知で聞くけど、ユーザーモードに限って言えば
普通はCriticalSection一択じゃないの?
CriticalSection自体がSpinCountの設定次第でカーネルモードにいかないようになってるから
そのチューニングで大体の用途には間に合うと思うんだが。

VistaだとRead/Writeロックが実装されたから、そっち使ったほうが早いかもしれんけど。


599 名前:デフォルトの名無しさん mailto:sage [2008/03/08(土) 18:32:59 ]
Windowsはあまり知らないんだけど、Enter/Leaveしか出来ないの?

600 名前:デフォルトの名無しさん mailto:sage [2008/03/08(土) 19:25:08 ]
TryLock もバージョンが↓でなければできる

601 名前:デフォルトの名無しさん mailto:sage [2008/03/16(日) 09:31:31 ]
VC++Windowsアプリの質問です。
メッセージループを1つのスレッドに隔離しようと思うのですが、
PostQuitMessage(0)を別スレッドから単純に呼び出しても安全でしょうか?

HWND g_hWnd
BOOL g_Active;

// g_Activeをクリティカルセクション内でやり取り
BOOL fGetActive();
VOID fSetActive(BOOL isActive);

INT WINAPI WinMain(...){
fSetActive(TRUE);
g_hWnd = (ウインドウハンドル作成);
メッセージループ用スレッド生成
while( fGetActive() ){
if(...) PostQuitMessage(0);
}
メッセージループ用スレッド後処理
return 0;
}
UINT WINAPI MessageLoop(...){
MSG msg;
msg.hwnd = g_hWnd;
while (GetMessage(&msg, NULL, 0, 0) > 0){
...
}
fSetActive(FALSE);
return 0;
}



602 名前:デフォルトの名無しさん mailto:sage [2008/03/16(日) 11:40:27 ]
サブスレッドからアプリケーションを直接終了させる設計は変じゃないか。
メインスレッドに何らかのメッセージを送って、メインスレッドからアプリケーションを終了すればよいじゃない。
面倒なら、少々強引だが、PostThreadMessageでメインスレッドに
直接WM_QUITを送りつけるのも。あまりお勧めしないが。

603 名前:デフォルトの名無しさん mailto:sage [2008/03/16(日) 12:57:27 ]
ウィンドウはそれを作ったスレッドに結びついているよ

604 名前:デフォルトの名無しさん mailto:sage [2008/03/16(日) 13:10:12 ]
>>601
PostQuitMessageを別スレッドから呼び出すことは問題ないけど、
メッセージは、ウィンドウの作成元のスレッドにしか来ないよ
別スレッドでGetMessageしたかったら、そっち側でCreateWindowしないとだめ

605 名前:604 mailto:sage [2008/03/16(日) 13:11:34 ]
>PostQuitMessageを別スレッドから呼び出すことは問題ないけど、
って、ウソでした、カレントスレッドにWM_QUITを送るだけか
PostThreadMessageで相手スレッドにWM_QUITを送ればいいかも

606 名前:デフォルトの名無しさん mailto:sage [2008/03/16(日) 14:31:10 ]
>>602-605
ありがとうございます。
MSG構造体へメッセージを送る際のデッドロックが心配でした。
>>602
>サブスレッドからアプリケーションを直接終了させる設計は変じゃないか。
ウインドウモードだと×からも終了させる場合があるのと、
メインスレッドのID取得が難しそうなので変えられなそうです。

607 名前:デフォルトの名無しさん mailto:sage [2008/03/16(日) 22:42:23 ]
>メインスレッドのID取得
プログラム開始時にメインスレッドから GetCurrentThreadId を呼んで、
メインスレッドのIDが取得して、それをグローバル変数にでも入れておけば良いかも。

それがいやなら、メインスレッドにくくりついている非表示ウィンドウを一つ作っておいて、
そこに向かって PostMessage して、メインスレッドにメッセージをポストするのも手。
windowsではよくある話。

608 名前:601、606 mailto:sage [2008/03/17(月) 15:08:05 ]
もう一つ質問させてください。
メインスレッドがウィンドウを持ち、GetMessageのループをしていてかつ、
サブスレッドがメインスレッドのウィンドウにDirect3Dで描画している場合、
GetMessageとDirect3DがHWNDへのアクセス権をもめてクラッシュしますか?

609 名前:デフォルトの名無しさん mailto:sage [2008/03/17(月) 16:22:56 ]
swapchainでググれ

610 名前:デフォルトの名無しさん mailto:sage [2008/03/17(月) 17:00:28 ]
サブスレッドでバックバッファに書き込んだ後、
メインスレッドにバッファを転送するべきという意味ですか?
うーん……

611 名前:デフォルトの名無しさん mailto:sage [2008/03/17(月) 21:18:56 ]
>>608
クラッシュしませんよ。
ただ、例外があって、ディバイスをリセットするときだけはディバイスを作成したスレッドからリセットを
コールしてあげないといけないからその点は注意。
メインスレッドでディバイスを作成した場合は、サブスレッドからはリセットは出来ない。

なので、もし、サブスレッドからディバイスをリセットする場合は、
まず、適当な自作ウィンドウメッセージをサブスレッドからメインスレッドのウィンドウに投げて、
メインスレッドのウィンドウがそれを拾ったらメインスレッド側から
ディバイスをリセットする。




612 名前:デフォルトの名無しさん mailto:sage [2008/03/18(火) 21:47:01 ]
Linux 2.6.21です
sigwait()しているスレッドに他のスレッドからpthread_cancel()を実行してもスレッドがキャンセルされません
sigwait()はキャンセルポイントのはずなのになぜ、と困惑しています
うちの環境のみなんでしょうか
もしくはLinuxの仕様?

613 名前:612 mailto:sage [2008/03/19(水) 07:24:50 ]
すいません、自分の勘違いでした






[ 続きを読む ] / [ 携帯版 ]

前100 次100 最新50 [ このスレをブックマーク! 携帯に送る ] 2chのread.cgiへ
[+板 最近立ったスレ&熱いスレ一覧 : +板 最近立ったスレ/記者別一覧]( ´∀`)<193KB

read.cgi ver5.27 [feat.BBS2 +1.6] / e.0.2 (02/09/03) / eucaly.net products.
担当:undef