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


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

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



1 名前:デフォルトの名無しさん mailto:sage [2005/11/03(木) 11:23:05 ]
マルチスレッドプログラミングについて語るスレ。
OS・言語・環境は問わないが、それゆえ明記すべし。

その1 pc3.2ch.net/test/read.cgi/tech/997345868/
その2 pc5.2ch.net/test/read.cgi/tech/1037636153/
その3 pc8.2ch.net/test/read.cgi/tech/1098268137/

620 名前:デフォルトの名無しさん mailto:sage [2006/07/09(日) 20:36:02 ]
selectで同時にパイプを待ったり
WSAEventSelectで同時にEventを待ったり
というやり方のこと。

621 名前:デフォルトの名無しさん mailto:sage [2006/07/09(日) 20:39:08 ]
selectでtimeout設定すればいいと思うけど
それとももっと高度な制御がしたいの?


622 名前:デフォルトの名無しさん mailto:sage [2006/07/10(月) 00:20:40 ]
>>621
timeout 値の設定がめんどい。

仕方なく >>620 の WSAEventSelect 使ってるけど、
これはこれでめんどい。

623 名前:デフォルトの名無しさん mailto:sage [2006/07/10(月) 03:56:03 ]
pselect

624 名前:593 [2006/07/10(月) 10:22:26 ]
>> 618
なるほど。
Linuxでは、読み込むものは全部ファイル(ファイルデスクリプタ)で、
中断など例外的な処理は全部シグナル。と思ってpselectで綺麗にい
けていたんだけれど、
Winにいったら、いろんな方法がありそうだけれど、どれもいまいちに見えて。。
WSAEventSelectは、socket以外にも汎用的に使ったりする?




625 名前:デフォルトの名無しさん mailto:sage [2006/07/10(月) 11:23:05 ]
>>617
スレッド(タスク)開始、実行状況(実行結果)の取得、完了待ち、中断のための関数を
それぞれ提供するのが一般的だと思います。
あと場合によっては先方のスレッドでコールバックされる実行状況の通知のための
コールバック関数なんかも設定できると UI 作るときには便利(プログレスバーとか)。

>>624
個人的な意見だけど、Windows では(ソケットなら WSAEventSelect等も使って)
(Msg)WaitForMultipleObjectExで待機、何かあれば処理するというのがマルチ
スレッドの場合の定石だと思います。
ソケットだけ相手にするなら単にclosesocketしてしまうというのもアリだと思うけど。

>WSAEventSelectは、socket以外にも汎用的に使ったりする?
ソケットを相手にしないのにWSA〜を使う局面は無いと思う。

626 名前:デフォルトの名無しさん mailto:sage [2006/07/11(火) 00:19:53 ]
>>624

Winでも sock をファイルとして扱えるよ。

627 名前:デフォルトの名無しさん mailto:sage [2006/07/18(火) 19:03:35 ]
Linux (Kernel 2.6.17) で、pthread_create() で複数スレッドを作り、
そのスレッド全てが同一の bind(), listen() されたソケットに対して
accept() を行うプログラムを作ったのですが(O_NONBLOCKなソケット
ですが)、クライアントプログラムから複数 connect() すると、
accept() が同じ値のファイルディスクリプタを返して来ます。処理を
単純に書くとこんな感じです。

for(;;) {
 int cs = accept(...); // ここで cs が別スレッドと同じ値になる。
 if (cs == -1) {
  if (errno == EAGAIN) {
   usleep(50000);
   continue;
  } else {
   break; // error
  }
 } else {
  proc(cs); // cs を使った処理。
  close(cs);
 }
}

accept() の前後に pthread_mutex_lock(), pthread_mutex_unlock() で
ロック、アンロックをしても同じでした。

これって Linux のバグなんでしょうか?
これを回避するにはやはり accept() をするスレッドを一つにしないと
駄目ですか?


628 名前:デフォルトの名無しさん [2006/07/18(火) 19:04:29 ]
すいません。質問なのに age 忘れました。age ておきます。よろしくお願いします。



629 名前:デフォルトの名無しさん mailto:sage [2006/07/18(火) 19:32:26 ]
わざわざageんなよ

630 名前:デフォルトの名無しさん mailto:sage [2006/07/18(火) 22:10:43 ]
コンパイル・リンク時のコマンドライン見せろ

631 名前:デフォルトの名無しさん mailto:sage [2006/07/19(水) 01:14:42 ]
>>627
> accept() の前後に pthread_mutex_lock(), pthread_mutex_unlock() で
> ロック、アンロックをしても同じでした。

この時点でプログラミングの問題じゃないことに気付け。

632 名前:デフォルトの名無しさん mailto:sage [2006/07/19(水) 01:56:34 ]
>>627
>これって Linux のバグなんでしょうか?
つかその前に、どこで習ったんだそんな阿呆な手順。

633 名前:デフォルトの名無しさん mailto:sage [2006/07/19(水) 02:07:07 ]
acceptしてからthreadおこせ

634 名前:デフォルトの名無しさん mailto:sage [2006/07/19(水) 03:17:38 ]
>>627
よく知らんけど、下記のApache のディレクティブの存在なんかを見ると
accept は直列化 (同時に1つのプロセス・スレッドからのみ呼ぶ)するのが
普通なんじゃないかと思うが・・・

httpd.apache.org/docs/2.2/ja/mod/mpm_common.html

635 名前:デフォルトの名無しさん mailto:sage [2006/07/19(水) 09:14:39 ]
>>630
gcc hoge.c -lpthread

>>631
どういう意味ですか? 同時に複数のスレッドが accept() しないように
しただけですが?

>>632
これは阿呆な手段ですか? 何故? その辺詳しく教えてもらえますか?
どこで習ったかは記憶にありません。ただ昔 Java で似たようなものを
作った時はちゃんと動いたと思いました。

>>633
それはつまり accept() は親(?)スレッド一つでやるということですね。


636 名前:デフォルトの名無しさん [2006/07/19(水) 10:02:36 ]
accept()を排他しても、
そのプログラムがまともにうごかん事に疑問はないのか?

他の部分がおかしいだけではないのか?

637 名前:デフォルトの名無しさん mailto:sage [2006/07/19(水) 11:14:26 ]
>>636
そこが疑問ですよ。なんで既に取得してオープンされているファイル
ディスクリプタと同じ値のファイルディスクリプタが返って来るのか
という点がね。

気になるのは Linux の場合スレッドは clone() システムコールで作った
特殊な別プロセスであるということです。別プロセスだから複数スレッドで
accept() した時に同一ファイルディスクリプタが取れてしまうんじゃない
かな、とは思ったんですが、確証がなかったので質問したんです。
(Linux板の方で質問した方がよかったかな? でも他のOSではこういうのは
できないのかも少し気になる)。

で、その後、accept() を一つのスレッドでだけやって、他のスレッドは
待機させておいて、accept() 成功後にファイルディスクリプタを待機
スレッドに渡すように作り替えたらちゃんと動くプログラムは作れました。
理由はどうあれこういう風にするか、あるいは accept() 成功後にスレッド
作るように書かないと駄目なようですね。


638 名前:デフォルトの名無しさん mailto:sage [2006/07/19(水) 11:25:03 ]
>>627
> int cs = accept(...); // ここで cs が別スレッドと同じ値になる。
本当にこれと同じ書き方だったんだな?
csが大域変数だったってオチがありそうだ。



639 名前:デフォルトの名無しさん mailto:sage [2006/07/19(水) 11:30:07 ]
>>638
いいえ。大域ではありません。autoです。


640 名前:デフォルトの名無しさん mailto:sage [2006/07/19(水) 12:26:13 ]
生半可な学習しないで、ファイルディスクリプタについてちゃんと勉強したら?

641 名前:デフォルトの名無しさん mailto:sage [2006/07/19(水) 13:35:02 ]
>>637
>スレッドは clone() システムコールで作った
ちょwwwwおまwwwww帰れwwwww

642 名前:デフォルトの名無しさん mailto:sage [2006/07/19(水) 13:56:58 ]
げ、pthread_createで作ってんじゃないのか・・・!!!

643 名前:デフォルトの名無しさん mailto:sage [2006/07/19(水) 14:24:08 ]
>>640
生半可? どの辺がですか?

>>641-642
pthread_create() で作ってますよ。clone() は内部動作の話です。


644 名前:デフォルトの名無しさん mailto:sage [2006/07/19(水) 14:29:47 ]
こいつむかつく〜☆

645 名前:デフォルトの名無しさん mailto:sage [2006/07/19(水) 14:36:37 ]
>>643
コンパイルオプションとかはどうだろう・・・ -pthread とか付け忘れありませんか?

646 名前:デフォルトの名無しさん mailto:sage [2006/07/19(水) 14:42:25 ]
>>645
>>635


647 名前:デフォルトの名無しさん mailto:sage [2006/07/19(水) 14:48:29 ]
>>643
続きは以下で。
ネットワークプログラミング相談室 Port17
pc8.2ch.net/test/read.cgi/tech/1148944560/

648 名前:デフォルトの名無しさん mailto:sage [2006/07/19(水) 14:59:44 ]
>>646
-lpthread だけ指定して -pthread を指定していないのではないか、といっているのだが。



649 名前:デフォルトの名無しさん mailto:sage [2006/07/19(水) 15:38:16 ]
>>648
-pthread は指定していませんでしたが、man ページや info 見ると
Linux では関係ないようですよ。

念のため指定してテストしてみましたが、同じ動作になりました。


650 名前:デフォルトの名無しさん mailto:sage [2006/07/19(水) 15:45:45 ]
いい加減、誰かファイルディスクリプタの説明してやれよw

651 名前:デフォルトの名無しさん mailto:sage [2006/07/19(水) 15:47:52 ]
>>647
そっちの方がいいですか?
スレッドとネットワークと Linux が混ざった疑問なのでどこがいいのか迷ったんですが。


652 名前:デフォルトの名無しさん mailto:sage [2006/07/19(水) 16:00:17 ]
>>640>>650
pthread_createで作ったスレッド間では、ファイルディスクプリタは共有されます。
すなわち、同じ数値=同じソケット端点。
何がいいたのか知らんがこれでいいか?

653 名前:デフォルトの名無しさん mailto:sage [2006/07/19(水) 16:06:07 ]
>>651
どっちがいいのかはわからんけど、このスレじゃ解決できなさそうじゃん。

654 名前:デフォルトの名無しさん mailto:sage [2006/07/19(水) 16:20:45 ]
Linuxのスレッドが特別なプロセスだったのは、2.4より前の話だよ。
# 例えばpidやsignalの扱いなど。
>>627は、2.6.17だから関係ない。

655 名前:デフォルトの名無しさん mailto:sage [2006/07/19(水) 16:21:59 ]
>>637
> accept() 成功後にスレッド作るように書かないと駄目なようですね。

そんなことはない。

656 名前:デフォルトの名無しさん mailto:sage [2006/07/19(水) 16:22:13 ]
>>652
それは知ってますよ。だからこそOSがおかしいんじゃないかと思ったんですから。

元々の質問を要約すると、まだ close() されていないファイル
ディスクリプタの値を accept() が返して来るのは何故かです。
一つのスレッドが accept() で 5 を受け取ったとして、それが
close() される前にもう一つのスレッドが行った accept() が
受け取ったファイルディスクリプタの値も 5 だったということです。
これ、accept() を一つのスレッドでしかやらなければ当然 6 などの
違う値が返って来ます。

>>653
今のところそんな感じしますね。


657 名前:デフォルトの名無しさん mailto:sage [2006/07/19(水) 16:24:17 ]
>>654-655
そうですか…。じゃあ何でだろう?


658 名前:デフォルトの名無しさん mailto:sage [2006/07/19(水) 16:26:01 ]
こっちの方がいいかも。
UNIX板 pthread地獄
pc8.2ch.net/test/read.cgi/unix/1010933537/
読んでる人はこの板と重複がかなりあるかもだけど。



659 名前:デフォルトの名無しさん mailto:sage [2006/07/19(水) 16:34:42 ]
>>658
そこはたしかに近いこと話し合われてたスレですね。
じゃあそこに移転します。

こちらのスレのみなさまありがとうございました。


660 名前:636 mailto:sage [2006/07/19(水) 23:13:46 ]
な?


661 名前:デフォルトの名無しさん mailto:sage [2006/07/20(木) 01:05:07 ]
うはwww
ボッコボコwww
しかも自分のミスwww

662 名前:デフォルトの名無しさん mailto:sage [2006/07/20(木) 12:50:33 ]
>>640>>650
お前等も黙ってないで「ファイルディスクリプタの説明」してくれよw

663 名前:デフォルトの名無しさん mailto:sage [2006/07/20(木) 13:12:28 ]
File Disk Riptor 略して FDR である

664 名前:デフォルトの名無しさん mailto:sage [2006/07/20(木) 14:35:46 ]
なんか車の駆動方式っぽい略称だな。

665 名前:627 mailto:sage [2006/07/20(木) 16:04:12 ]
申し訳ありません。私がバグっておりました。

accept() 後の処理を別関数でやっていたのですが、その中で
fdopen() を使って accept() で受け取ったファイルディスク
リプタから FILE * を作って fgets() や fprintf() を使って
いました。それでその関数から返る直前に fclose() をして
いますが、そうすると当然元となったソケットも close()
されます。

このことをすっかり忘れていたためこの別関数から戻って
来ても accept() で取ったファイルディスクリプタは
オープンしたままだと思い込み、別関数から帰って来てから
close() までの間に別スレッドで accept() した時の
ファイルディスクリプタと同じ値になることがあったため、
今回の疑問に繋がっていました。

ということでお騒がせしました。
Linux でも複数スレッドからの accept() は問題無くできます。

666 名前:デフォルトの名無しさん mailto:sage [2006/07/20(木) 16:25:36 ]
まあせいぜい地雷原を走り抜けてくれ

667 名前:デフォルトの名無しさん mailto:sage [2006/07/21(金) 20:41:07 ]
Javaだと複数のスレッドがacceptでブロックしてても動いたと思う。
ttp://www.amazon.co.jp/gp/product/4274065200/ の例の1つにあったと思う。

個人的にはとても気持ち悪いし、他の人にコードを見せると頭を抱えるし、
特にメリットも思いつかないので、
自分はJavaでもacceptは1つのスレッドで実行してる。

668 名前:デフォルトの名無しさん mailto:sage [2006/07/21(金) 20:54:45 ]
この人の場合、さらに non-blocking にしてあって、ブロックしないでポーリングしてるらしいよw



669 名前:デフォルトの名無しさん mailto:sage [2006/07/21(金) 21:16:04 ]
>>667
> 特にメリットも思いつかないので、

はあ


670 名前:デフォルトの名無しさん mailto:sage [2006/07/22(土) 00:47:01 ]
試したことはないが、
複数のThreadがServerSocket#accept()でブロックされてるとき、
ブロック解除で起こされるThreadはたぶん唯1つなのがメリットじゃないかな。
単一のThreadがaccept()待ち→ブロック解除→Queueに放り込んでWorker Threadを
たたき起こすパターンだと、Queueを監視する複数のWorker Threadがいったん
たたき起こされるから。


671 名前:デフォルトの名無しさん mailto:sage [2006/07/23(日) 09:39:44 ]
pThreadsについての書籍を探してるのですが、以下のもの読まれてる方
感想はどうですか?良書ですかね?

www.amazon.com/gp/product/1584503718/ref=pd_rvi_gw_1/103-0885486-2811001?%5Fencoding=UTF8&v=glance&n=283155

www.amazon.com/gp/product/0735710430/ref=pd_rvi_gw_2/103-0885486-2811001?%5Fencoding=UTF8&v=glance&n=283155

672 名前:デフォルトの名無しさん [2006/07/26(水) 17:24:59 ]
お世話になります。
識者のご意見ください。

以下のような状況です。(環境はVC6のWin32API)

メインスレッドAと、待機スレッドBがあります。
BはSuspend状態です。

あるタイミングでAがBに仕事を投げてResumeしました。
Bは仕事が終わったら自分でSuspend状態になりたいのです。

Bは自分のHANDLEをSuspendThreadしちゃってもいいものでしょうか?
AがBのフラグを見てSuspendしてやるというのはちょっと効率が
悪い気がします。

以前はBを待機スレッドではなく、その都度生成して自殺させていました。
が、この方法だとデバッグウインドウに生成と消滅のメッセージが
出まくるのと、やはりCreateThreadの負荷が気になります。

こういう場合の常套手段など、ご教示ください。
待機スレッドがCPUを食わないようにするために、Suspend状態に
しておく、という風に考えるのは変でしょうか?

よろしくお願い致します。

673 名前:デフォルトの名無しさん mailto:sage [2006/07/26(水) 17:36:12 ]
>>672
ただのワーカースレッドでええんちゃうかと
マイクロスレッドのようなものを考えてるなら、ファイバでも使えばいい


674 名前:デフォルトの名無しさん mailto:sage [2006/07/26(水) 17:36:23 ]
>>672
自分をSuspendするのは悪くない。というか、それが唯一のSuspendThreadの正しい使い方。
基本的には自スレッド以外をSuspendThreadしてはいけない。

ただし、普通はautoresetのイベントハンドルを用意して WaitForSingleObject で待たせておき、
SetEventで起こす。これはAがBをResumeThreadで起こすのが難しいから。

具体的には、SuspendThread/ResumeThreadで待機を実現しようとすると、
ResumeThreadするときに、ちょうどBが何かの仕事を終えてSuspendThreadする
直前だったりするとResumeしても即Suspendしてしまうので、これを避けるために
クリティカルセクションとフラグが1つ余分に必要になってしまって効率も悪いし
コードもムダに複雑になる。


675 名前:デフォルトの名無しさん mailto:sage [2006/07/26(水) 18:07:51 ]
みなさん、レス有難うございます。

>>674
>autoresetのイベントハンドルを用意して WaitForSingleObject で待たせておき

こんな感じでしょうか?

スレッドB{
while(1){
WaitForSingleObject(XXX);
何か仕事(B*)
}
}

スレッドA{
while(1){
何か仕事の準備(実行中のB*の部分を触らない配慮はしている)
SetEvent(XXX);
}
}

>直前だったりするとResumeしても即Suspendしてしまうので
なんとなく現象の心当たりがあります。



676 名前:デフォルトの名無しさん mailto:sage [2006/07/26(水) 18:21:59 ]
>>675
Bが待機するところはそんな感じです。

あとまぁよく使うパターンとしては
(1) AがBの仕事の完了を待たずににいくつもの仕事を投げておけるようにQueueに仕事を登録して SetEvent する。Bは起こされたら、Queueにある仕事を全て実行してからWaitする。
(2a) 「仕事終わったよイベント(初期値はON)」ってのも用意して、Bが仕事を終えたらSetEventする。Aは仕事終わったよイベントを待ってからBを起こす
(2b) CreateSemaphoreでMaxCount 1 のセマフォを作って、AはWait,→仕事の準備→ReleaseSemaphore、
  BはWait→仕事を取り出して実行→ReleaseSemaphore とする。

仕事が終わったかどうか知りたくなることも多いので、漏れは2aのパターンを多用します。
殆ど等価な 2b でもいいのかも知れない。

677 名前:デフォルトの名無しさん mailto:sage [2006/07/26(水) 19:36:15 ]
>>676
Suspend,Resumeでやってたところを待機オブジェクトにしました。
すっきりした感じがします。
>(2a)
なんとなくこれっぽいことはやっていました。
どうもありがとうございました。

678 名前:デフォルトの名無しさん mailto:sage [2006/07/26(水) 21:47:50 ]
lock-freeについて調べている内に
CAS(CompareAndSwap)という概念にたどりついたのですが
ちょっと教えてください。
/* 関数内の処理はatomicに処理されると仮定*/
bool CAS(void*addr,int expval,int newval){
if(*addr == expval){
*addr = newval;return true;
}
return false;
}
*addr=0;
while(!CAS(addr,0,*addr + 1)){
//※ここでコンテキストスイッチ
}
//アトミックにインクリメント成功?
例えば※の部分で別スレッドがaddrの値を5に変更→0に変更
という動きをした場合、*addr == expvalが成り立ってしまい、
インクリメント成功とみなされてしまう気がするのですが・・・
何か回避策等あるんでしょうか。それとも俺の理解不足なんでしょうか



679 名前:デフォルトの名無しさん mailto:sage [2006/07/26(水) 23:07:03 ]
>>678
「アトミックなインクリメント」というものを理解していないような気がする。
過去に5だったかどうかはさておき、他のスレッドで0にされたものが1に
なるのだから成功している。
というか5で放置されてて6になってもやはり成功。

*addr=0;
IntgerlockedIncrement(&addr); ←APIによるアトミックなインクリメント
などとしたところで、この2行の間に*addrが5になって0になることもある。

「アトミックなインクリメントに失敗」というのは、2つのスレッドで1度ずつ
アトミックなインクリメント操作が行われたにも関わらず2増えないことを言う。
これは正しい実装では決して起きない。

680 名前:デフォルトの名無しさん mailto:sage [2006/07/26(水) 23:07:59 ]
追記:
CASによるアトミックなインクリメントの実装は、正しくは↓

while (!CAS(addr, *addr, *addr+1) {}


681 名前:678 mailto:sage [2006/07/27(木) 21:49:17 ]
>>679
>>680
ありがとうございます。

addr=&val;
while(!CAS(addr,*addr,*addr + 1)){
//※ここでコンテキストスイッチ
}
でも問題が起きそうな気がするんですが・・

とここまで書いて
www-06.ibm.com/jp/developerworks/java/041203/j_j-jtp11234.html
に似たような事が書いてありました
ABA問題というらしいですが

もうちょっと勉強してでなおしてきます・・

682 名前:デフォルトの名無しさん mailto:sage [2006/07/27(木) 23:41:31 ]
とりあえず、CAS(xxx, *addr, *addr+1)
なんて書いている奴は氏んでいいよ。

atomic_inc(int *addr)は
do {
 int var = *addr;
} while (!CAS(addr, var, var+1));
にしないと。

まあ、複数のスレッドで勝手に値をセットするような変数を
特定の個所だけatomic_incを使っても意味は無いがね。

683 名前:デフォルトの名無しさん mailto:sage [2006/07/28(金) 00:03:12 ]
終わった話題についてなにを得意げに語ってるんだろう…。

684 名前:デフォルトの名無しさん mailto:sage [2006/07/28(金) 00:20:12 ]
>>682
それC言語的にやばいやん。

685 名前:デフォルトの名無しさん mailto:sage [2006/07/28(金) 00:31:47 ]
つまり、「ほんと、バカしかいないんだね」ってことか。

686 名前:デフォルトの名無しさん mailto:sage [2006/07/28(金) 00:43:19 ]
やーい
ばかー

687 名前:デフォルトの名無しさん mailto:sage [2006/07/28(金) 07:26:02 ]
volatileですべて解決!

688 名前:デフォルトの名無しさん mailto:sage [2006/07/28(金) 12:24:47 ]
>>682
バカは喪前のほうだと思うが・・・
なぜ自分がバカなのかが知りたかったら、
元のコードの問題点を書いてご覧よ。
書いてるうちにわかるだろ。



689 名前:デフォルトの名無しさん mailto:sage [2006/07/28(金) 17:51:17 ]
元のコードの問題点は関係なくて
*addrを2度読み出して同じ値が取れると思っているのがバカだって事だろ。

690 名前:デフォルトの名無しさん mailto:sage [2006/07/28(金) 17:53:25 ]
しかも、この手のバグは非常に表面化しにくく
再現性が低い(デバッグが難しい)。

691 名前:デフォルトの名無しさん mailto:sage [2006/07/29(土) 15:08:13 ]
volatileですべて解決するという忠告がみえないのか?

692 名前:デフォルトの名無しさん mailto:sage [2006/07/29(土) 16:14:19 ]
別CPUから発言が見えるようになるまでには時間がかかります

693 名前:デフォルトの名無しさん [2006/07/29(土) 18:15:53 ]
VC++とMFCでマルチスレッドなサーバープログラムを書いています。
サーバープログラムを終了する時、ソケットが走ってるスレッドを終了させないといけませんが、
スレッドに終了を通知する手段が分かりません。
どのように終了を通知するのか教えていただけないでしょうか。

よろしくお願いします。

694 名前:デフォルトの名無しさん mailto:sage [2006/07/29(土) 19:01:50 ]
ソケットをどういう風に使ってるかによると思うけど、イベントとか単なるフラグとか。

695 名前:デフォルトの名無しさん mailto:sage [2006/07/29(土) 19:36:20 ]
>>693
ExitProcessで自殺すればおk

696 名前:693 mailto:sage [2006/07/29(土) 19:49:37 ]
CAsyncSocketを継承して作ったUDPのソケットです。
クライアントからやってくるパケットをRecvFromで受けて、データに応じてSendToしているだけです。

現在、スレッドを閉じるのにdeleteでデストラクタを呼び、強制的に終了させているのですが
デバッガで追っかけていくとCAsyncSocketの中でエラーが発生します。
詳細は不明ですがおそらくソケットを閉じずに終了したためではないかと思います。

Win32APIでマルチスレッドなプログラムを組んだときはPostThreadMessageで終了メッセージを
送って、WaitForSingleObjectでスレッドが落ちるのを待っていたのですが、MFCで
そのような手順を踏んだ終了の仕方は(強制終了じゃないやり方)ないのでしょうか?

697 名前:デフォルトの名無しさん mailto:sage [2006/07/29(土) 20:28:56 ]
CAsyncSocketて使ったことないから知らないけど、
非同期に通信してるなら終わりにするかどうか判断する機会はあるんじゃないの?

698 名前:デフォルトの名無しさん mailto:sage [2006/07/29(土) 20:48:34 ]
CAsyncSocketのデストラクタが動けば万事OKみたいなことMSDNには書いてあるけど。
スレッドを強制終了するから、そのスタックにあるCAsyncSocketがリークしてるとか、
そういうこと?



699 名前:693 mailto:sage [2006/07/29(土) 21:12:35 ]
>>697
複数台の設備との通信をするサーバープログラムなのですが、設備のON/OFFとサーバーのON/OFFは
必ずしもリンクしていません。一応作業標準として順序だてることは可能ですが、予想外のトラブル(瞬停など)を
考えると何かのパケットが来たらソケットを閉じてもいいとはできません。
サーバープログラムを閉じる作業中にソケットが走っているスレッドに終了を通知できればいいのですが
その方法がわからないのです。

>>698
>そのスタックにあるCAsyncSocketがリークしてるとか
そのとおりです。

700 名前:デフォルトの名無しさん mailto:sage [2006/07/29(土) 21:18:08 ]
スレッドが終了する時のイベントハンドラで
CAsyncSocketをdeleteじゃダメって事?

701 名前:デフォルトの名無しさん mailto:sage [2006/07/29(土) 21:24:23 ]
>>700
今はスレッドのデストラクタでCAsyncSocketをdeleteしていますが、その中でエラーになります。

702 名前:デフォルトの名無しさん [2006/07/29(土) 21:38:00 ]
ねぇ。マルチスレッドって何?

703 名前:デフォルトの名無しさん mailto:sage [2006/07/29(土) 21:40:39 ]
multi 【名-1】 (複数{ふくすう}の色調{しきちょう}からなる)縞模様{しま もよう} 【名-2】 マルチビタミン(錠剤{じょうざい})
thread 【名-1】 (繊維を束ねた)糸、より糸 【名-2】 糸[繊維]状のもの、細い筋状のもの 【名-3】 (全体をつなぎ止める)筋、(話などの)脈絡{みゃくらく}


704 名前:デフォルトの名無しさん [2006/07/29(土) 21:53:15 ]
縞模様の筋ですか?

705 名前:デフォルトの名無しさん mailto:sage [2006/07/29(土) 21:55:30 ]
筋肉のことですか?

706 名前:デフォルトの名無しさん mailto:sage [2006/07/29(土) 22:29:03 ]
>>691
まさかとは思うけど、本気で言ってるわけじゃないよね?

707 名前:デフォルトの名無しさん [2006/07/30(日) 00:24:25 ]
>>689
だって別に同じ値じゃなくても問題ないんだよ。
単にその1度のCAS呼び出しがfalseになるだけ。


708 名前:デフォルトの名無しさん mailto:sage [2006/07/30(日) 00:32:23 ]
>>707
第3引数の *addr + 1 を評価した後に別スレッドによって *addr の値が変更され、
その後に第2引数の *addr が評価されるとアウト。



709 名前:デフォルトの名無しさん mailto:sage [2006/07/30(日) 09:43:28 ]
>>701
スレッドを強制終了させないで、外部から何かきっかけを与えて自分で終わるようにすればいいだけじゃん。

710 名前:デフォルトの名無しさん mailto:sage [2006/07/30(日) 15:36:23 ]
>>691>>707
>>708の言うように、
「CASの第2引数の値」と「CAS呼び出し時に*addrに入っている値」
これが違うのは問題ないが
「CASの第2引数と第3引数の値の差」が1でない場合に誤動作する。

コンパイラの最適化で読み出しが1回になるケースもあるだろうが
最適化オプションで動作が異なるのはデバッグを難しくするだけ。

volatileを使えば、読み出しが2回になることが保証されるだけ。

711 名前:デフォルトの名無しさん mailto:sage [2006/07/31(月) 13:37:43 ]
一般的な双方向リストをマルチスレッドで使うとまずいですか?

new -> next = next;
/* ここでスレッドが切り替わるとか? */
new -> prev = next -> prev;

みたいな事が起きるとうまく繋げないような気がします。
WinAPI を使ってオブジェクトかなにか?を作って排他制御する
必要があるのでしょうか?

712 名前:デフォルトの名無しさん [2006/07/31(月) 13:41:09 ]
問題ないw


713 名前:デフォルトの名無しさん mailto:sage [2006/07/31(月) 15:11:21 ]
>>711
まずい。複数スレッドからappendすると、ノードが行方不明になったりする。
ただ、スレッドセーフな双方向リストにするより、
外部の同期オブジェクトを使ってそのリストへのアクセスを同期化する方が
柔軟。

714 名前:デフォルトの名無しさん mailto:sage [2006/08/01(火) 06:53:40 ]
volatileですべて解決!!!

715 名前:デフォルトの名無しさん mailto:sage [2006/08/01(火) 10:44:44 ]
この話では無理w

716 名前:デフォルトの名無しさん [2006/08/01(火) 11:20:51 ]
>>711
問題ない
関数内ではスレッドの切り替えは起こらない

717 名前:デフォルトの名無しさん mailto:sage [2006/08/01(火) 11:51:13 ]
preemption はいつでも起こりうるでしょ

718 名前:716 [2006/08/01(火) 12:39:23 ]
起こらないでしょ




719 名前:デフォルトの名無しさん mailto:sage [2006/08/01(火) 12:43:33 ]
>>716
何を根拠に言ってんの?

720 名前:デフォルトの名無しさん mailto:sage [2006/08/01(火) 12:51:51 ]
ようやくWindowsのメッセージディスパッチのことを理解したばかりのヒトが
それをマルチスレッドだと思い込んでるんでしょう。

721 名前:デフォルトの名無しさん mailto:sage [2006/08/01(火) 13:19:11 ]
>>716 は、ユーザレベルスレッドしか使った事無い人なんでしょうかね。

722 名前:デフォルトの名無しさん mailto:sage [2006/08/01(火) 13:23:44 ]
>>716はWin3.1ユーザー

723 名前:デフォルトの名無しさん mailto:sage [2006/08/01(火) 13:24:48 ]
実装がユーザレベルかカーネルレベルかと、プリエンプティブかコ・オペレーティブかは関係ないだろ。

724 名前:デフォルトの名無しさん mailto:sage [2006/08/01(火) 13:33:14 ]
関数内では起こらないってのもすごいよな。
普通は全てmainの関数内なんだが。
まあWndProcはまた別だが、それもWinMain内ででGetMessageしてるわけだし。

725 名前:716 [2006/08/01(火) 14:35:50 ]
反省^^


726 名前:デフォルトの名無しさん mailto:sage [2006/08/01(火) 22:51:18 ]
>>723
そこに異論は無いけど、言いたい事は分かるでしょ。

727 名前:デフォルトの名無しさん mailto:sage [2006/08/02(水) 08:14:08 ]
まあ、あれだ。がんがりたまえ(笑)

728 名前:デフォルトの名無しさん [2006/08/02(水) 12:46:56 ]
一般的なのはミューティックスを作る方法なの?





729 名前:デフォルトの名無しさん mailto:sage [2006/08/02(水) 13:49:28 ]
ディスクトップでディスクリプタをミューティックスで保護することを考察

730 名前:デフォルトの名無しさん mailto:sage [2006/08/02(水) 14:34:13 ]
むてふ

731 名前:デフォルトの名無しさん mailto:sage [2006/08/02(水) 14:47:18 ]
ティキストエデタ

732 名前:デフォルトの名無しさん [2006/08/02(水) 15:05:17 ]
www

733 名前:デフォルトの名無しさん mailto:sage [2006/08/02(水) 23:11:34 ]
ヴォラタィル

734 名前:デフォルトの名無しさん mailto:sage [2006/08/03(木) 08:56:51 ]
コンピゥタァ


735 名前:デフォルトの名無しさん mailto:sage [2006/08/03(木) 12:30:55 ]
モシ NO=735 ナラバ トベ >>1000

736 名前:デフォルトの名無しさん [2006/08/03(木) 14:38:59 ]
static bool g;

if (!g && g = true) {}

この if ()の中でスレッド切り替えって起こります?
排他処理になりませんか?



737 名前:デフォルトの名無しさん mailto:sage [2006/08/03(木) 14:54:43 ]
>>736
その g = true というのは本当に g = grue なのか?
それとも g == true の書き間違い?


738 名前:デフォルトの名無しさん mailto:sage [2006/08/03(木) 14:56:56 ]
あ、俺も書き間違えた。すま。



739 名前:デフォルトの名無しさん mailto:sage [2006/08/03(木) 15:47:48 ]
>>736
> この if ()の中でスレッド切り替えって起こります?
起こる

> 排他処理になりませんか?
ならん

740 名前:デフォルトの名無しさん [2006/08/03(木) 18:52:39 ]
w

741 名前:デフォルトの名無しさん mailto:sage [2006/08/03(木) 21:56:53 ]
ちょっと待てよ。C言語だとするとショートサーキットだよな?
!g の結果が false なら g = true は実行されないよな。
true なら実行される。

排他になるんじゃないか?


742 名前:デフォルトの名無しさん mailto:sage [2006/08/03(木) 22:01:59 ]
ひょっとしたら
!g
がアトミックじゃない処理系もあるかも

743 名前:デフォルトの名無しさん mailto:sage [2006/08/03(木) 22:02:10 ]
ショートサーキットは関係ない。
!gの評価と、g=trueの間にスレッドが切り替わる可能性があれば、排他として役に立たない。

744 名前:デフォルトの名無しさん mailto:sage [2006/08/03(木) 22:31:23 ]
アセンブラレベルで考えるんだ

745 名前:デフォルトの名無しさん mailto:sage [2006/08/03(木) 22:49:20 ]
なんだろ? 書き込み見てると、CPU命令レベルでの挙動に思い至らないのが居るな。
ソースレベルの字面で捉えてコンパイルというのが何なのかまったく知らないよう
に思える。

こんなんで日本のプログラマーのレベルは大丈夫なのか? 小中学生だったら
知らなくても無理は無いのか。

746 名前:デフォルトの名無しさん mailto:sage [2006/08/03(木) 23:05:44 ]
アセンブラまで降りる必要は必ずしも無いとは思うが
メモリの読み込みと書き出しを同時(atomic)に行うことは
(普通は)出来ないということくらいは知っておく必要がある。

もちろん、プロセッサはそのための命令を(普通は)用意しているが
コストがかかるため、普通にソースを書いた場合
コンパイラはその命令を使ったコードは出力しない。

747 名前:デフォルトの名無しさん mailto:sage [2006/08/03(木) 23:16:40 ]
えらそうに講釈たれてても

> 同時(atomit)

この一言で台無しだな。

748 名前:デフォルトの名無しさん mailto:sage [2006/08/03(木) 23:25:35 ]
>>747
お前いらないから



749 名前:デフォルトの名無しさん mailto:sage [2006/08/03(木) 23:36:58 ]
必死な子がいるなぁ。

750 名前:デフォルトの名無しさん mailto:sage [2006/08/03(木) 23:39:29 ]
>>747
別のプロセッサに割り込まれないように
lock等で保護してからxchgしたりincしたりnegしたりするけど
それをatomicと言わないとでも?

例えばあるメモリの内容を+1する場合、
「+1する命令をメモリに対して発行する」ではなくて
「プロセッサがメモリを読んで、+1した値をメモリに書き込む」だし。

751 名前:デフォルトの名無しさん mailto:sage [2006/08/03(木) 23:58:41 ]
なに一生懸命説明してるの?

これスレでそんなこと知らない奴なんてあまりいないよ。

俺はただ「atomic」と「同時」って全然違うって言いたいだけなんだが。

まあ俺も atomit とか書いてるようじゃ人のことは言えないわな。(w

752 名前:デフォルトの名無しさん mailto:sage [2006/08/04(金) 00:03:37 ]
>>751
もう消えてね(^^)

753 名前:デフォルトの名無しさん mailto:sage [2006/08/04(金) 00:18:24 ]
>>751
ずいぶん必死ですね。

754 名前:デフォルトの名無しさん mailto:sage [2006/08/04(金) 00:20:13 ]
最近なりを潜めてる、某キティと文体が似てる・・・

755 名前:デフォルトの名無しさん mailto:sage [2006/08/04(金) 01:02:29 ]
読むのと同時に書かないと壊れるメモリもあるだぜ?

756 名前:デフォルトの名無しさん mailto:sage [2006/08/04(金) 01:19:47 ]
「atomic」は日本語で言ったら「不可分」ちうことですわ。

757 名前:デフォルトの名無しさん mailto:sage [2006/08/04(金) 01:23:06 ]
原子力って感じかと思ってた

758 名前:デフォルトの名無しさん mailto:sage [2006/08/04(金) 03:38:13 ]
分割不可能な最小単位つうことですょ



759 名前:デフォルトの名無しさん mailto:sage [2006/08/04(金) 03:51:04 ]
つまり、鉄腕アトムは分割不可能と言うことで宜しいか。

760 名前:デフォルトの名無しさん mailto:sage [2006/08/04(金) 04:08:01 ]
「atomic」には他に「原子の」みたいな意味もあるんですわ。
昔は原子(atom)は物質の不可分な最小単位と考えられていたので。
どっちの意味が先か知らんけどね。

761 名前:デフォルトの名無しさん mailto:sage [2006/08/04(金) 07:05:02 ]
で、何が言いたいんだ?

762 名前:デフォルトの名無しさん mailto:sage [2006/08/04(金) 07:11:33 ]
atomic bomb 分割不可能な爆弾

763 名前:デフォルトの名無しさん mailto:sage [2006/08/04(金) 07:12:41 ]
割ったら被爆しちゃうからね

764 名前:デフォルトの名無しさん mailto:sage [2006/08/04(金) 07:17:17 ]
>>761
誰でも知ってるような事をちょっと偉そうにしゃべくってみたかっただけですわ。

765 名前:デフォルトの名無しさん mailto:sage [2006/08/04(金) 07:18:59 ]
被爆と被曝

766 名前:デフォルトの名無しさん mailto:sage [2006/08/04(金) 07:55:02 ]
>>764
何のために?

767 名前:デフォルトの名無しさん mailto:sage [2006/08/04(金) 07:57:34 ]
>>760
なに一生懸命説明してるの?

これスレでそんなこと知らない奴なんてあまりいないよ。

768 名前:デフォルトの名無しさん mailto:sage [2006/08/04(金) 08:37:02 ]
「同時」って書いちゃうヤツ以外はね。



769 名前:デフォルトの名無しさん mailto:sage [2006/08/04(金) 08:45:15 ]
VRAM(昔のやつ)やWRAM(初代Milleniumが採用した奴)を思い出した。

770 名前:デフォルトの名無しさん mailto:sage [2006/08/04(金) 09:45:01 ]
>>768
どこが変なのか未だにわからんのだが?

「読み込みと書き込みが同時に出来ない」
だから
「読み込みと書き込みをatomicに出来ない」(バスロックしなければ)
という意味なんだけど?

771 名前:デフォルトの名無しさん mailto:sage [2006/08/04(金) 09:48:31 ]
>>764
俺は知らなかったからタメになりましたよ
一応ありがとう

772 名前:デフォルトの名無しさん mailto:sage [2006/08/04(金) 09:53:42 ]
この流れ見て、コンカレントとパラレルの違いが理解出来なかった当時を思い出した

773 名前:デフォルトの名無しさん mailto:sage [2006/08/04(金) 10:49:55 ]
既に「atom」という言葉があるからこそ、物質の探求の過程で原子にその言葉を当て嵌めたってことくらい
>758を理解していたら考えるまでもないだろ。

774 名前:デフォルトの名無しさん mailto:sage [2006/08/04(金) 11:02:32 ]
>>770
同時(simultaneous)と、不可分(atomic)の違い。


775 名前:デフォルトの名無しさん mailto:sage [2006/08/04(金) 11:03:28 ]
意味が分からねえ・・・

776 名前:デフォルトの名無しさん mailto:sage [2006/08/04(金) 11:10:09 ]
>>770
恥の上塗り


777 名前:デフォルトの名無しさん mailto:sage [2006/08/04(金) 12:38:57 ]
ガキ共の言葉遊びここまで

778 名前:デフォルトの名無しさん mailto:sage [2006/08/04(金) 12:49:23 ]
じゃあ今から大人の言葉遊びか・・・エロス



779 名前:736 [2006/08/04(金) 13:14:37 ]
if (g = g ? false : true)

この場合でも排他にならない??
アホですまん

780 名前:デフォルトの名無しさん mailto:sage [2006/08/04(金) 13:19:58 ]
C言語のレベルでどの式がアトミックになるかという事に依存するのが間違いだと思う。
現存する全ての環境でアトミックに実行されるような式でも、それは処理系依存。

781 名前:デフォルトの名無しさん mailto:sage [2006/08/04(金) 13:21:37 ]
その後、原子は分割可能であることが判明してしまいました。

782 名前:デフォルトの名無しさん mailto:sage [2006/08/04(金) 13:25:55 ]
陽子と電子に分割できるんだっけ?

783 名前:デフォルトの名無しさん mailto:sage [2006/08/04(金) 13:27:46 ]
あと中間子

784 名前:デフォルトの名無しさん mailto:sage [2006/08/04(金) 13:40:08 ]
それらの素粒子も実は更に……
つーのはやめておこうか。

785 名前:デフォルトの名無しさん mailto:sage [2006/08/04(金) 14:05:25 ]
>>779
そもそもどう排他したいの?

786 名前:デフォルトの名無しさん mailto:sage [2006/08/04(金) 14:21:49 ]
mkdir() は atomic らしい

787 名前:779 mailto:sage [2006/08/04(金) 14:38:19 ]
リスト処理でつなげるときに排他したいけど
WinAPI使うしかないみたいですね


788 名前:デフォルトの名無しさん mailto:sage [2006/08/04(金) 14:39:02 ]
デッドロックになってしまった場合に
一定時間後に解除するような作りにしたいとき

mkdir() だと unlink() すると atomic では
なくなってしまう危険があるので

rename() の方が良いそうです

www.din.or.jp/~ohzaki/perl.htm




789 名前:デフォルトの名無しさん mailto:sage [2006/08/04(金) 15:16:39 ]
>>779
もう諦めて、素直に同期オブジェクト使いなさい。

790 名前:デフォルトの名無しさん mailto:sage [2006/08/04(金) 15:28:11 ]
mutex使わないのはなぜですか

791 名前:デフォルトの名無しさん mailto:sage [2006/08/04(金) 17:00:56 ]
Windowsでプロセス内だけでいいならCriticalSectionのほうが速いんじゃなかったっけ

792 名前:デフォルトの名無しさん mailto:sage [2006/08/04(金) 18:32:01 ]
>>787
それならCriticalSectionで十分

793 名前:デフォルトの名無しさん mailto:sage [2006/08/04(金) 18:35:59 ]
>>787
これもAPIになるけど、InterlockedCompareExchangeとかでも自分でロックを作れる。
ただ、CriticalSection使うほうが簡単でおすすめ

794 名前:デフォルトの名無しさん mailto:sage [2006/08/04(金) 22:35:03 ]
>>755
> 読むのと同時に書かないと壊れるメモリもあるだぜ?

kwsk

795 名前:デフォルトの名無しさん mailto:sage [2006/08/04(金) 22:42:15 ]
それはリフレッシュのことかね。

796 名前:デフォルトの名無しさん mailto:sage [2006/08/04(金) 22:56:05 ]
「メモリなどの外部デバイスに対して複数の入出力をatomicに行うには同時にやるしかない。ロックしないならば」
という文章があったとします。

この文章の最後を無視して
『メモリなどの外部デバイスに対して複数の入出力をatomicに行うには同時にやるしかない』
だけを引用して
「ロックすればいいじゃん。バカじゃねーの?」
と書き込むのは、とても恥ずかしいですね。


では、前半部も無視して
『atomicに行うには同時にやるしかない』
だけを引用し、
「同時とatomicは違うだろ。バカじゃねーの?」
と書き込むのは、どのくらい恥ずかしいことなんでしょうかね。

まあ夏休みだから、「こくご」の能力がちょっと不足している人が現れるのも
仕方ないかもしれませんが。

797 名前:デフォルトの名無しさん mailto:sage [2006/08/04(金) 23:29:16 ]
746 名前:デフォルトの名無しさん:2006/08/03(木) 23:05:44
アセンブラまで降りる必要は必ずしも無いとは思うが
メモリの読み込みと書き出しを同時(atomic)に行うことは
(普通は)出来ないということくらいは知っておく必要がある。


798 名前:デフォルトの名無しさん mailto:sage [2006/08/04(金) 23:34:11 ]
>>797
ロックすれば、読み込みと書き出しを同時に行わなくてもatomicに実行できるよ



799 名前:デフォルトの名無しさん mailto:sage [2006/08/04(金) 23:43:27 ]
>>795
D-RAM は、読んだらデータが壊れるから再書き込みするけど、
あれは読んだデータを後から書き込んでるから同時じゃない。

正解を教えてくれ >>755

>>796
> という文章があったとします。

どこに? 君の脳内?

ちょっと頭冷やせよ。

800 名前:デフォルトの名無しさん mailto:sage [2006/08/04(金) 23:45:22 ]
そんなの基礎知識でしょ

801 名前:デフォルトの名無しさん mailto:sage [2006/08/04(金) 23:47:39 ]
文脈や前提を無視して言葉尻をとらえるのが大好きな方がいらっしゃるようで。

802 名前:デフォルトの名無しさん mailto:sage [2006/08/04(金) 23:48:16 ]
で、そういう人には揶揄や皮肉は通用しませんね。

803 名前:デフォルトの名無しさん mailto:sage [2006/08/05(土) 00:15:01 ]
746 名前:デフォルトの名無しさん:2006/08/03(木) 23:05:44
アセンブラまで降りる必要は必ずしも無いとは思うが
メモリの読み込みと書き出しを同時(atomic)に行うことは
(普通は)出来ないということくらいは知っておく必要がある。

804 名前:デフォルトの名無しさん mailto:sage [2006/08/05(土) 00:28:38 ]
>>787
排他だけなら、アセンブラとか、asm文とか使えばいいけど、
CPUを離すのは、API使わないと無理。
# というか使った方がいい。
# ユーザランドだけで実装されたマルチスレッドライブラリもあるけどさ。

805 名前:デフォルトの名無しさん mailto:sage [2006/08/05(土) 00:31:32 ]
破壊読み出しなのは、コアメモリもそう

806 名前:デフォルトの名無しさん mailto:sage [2006/08/05(土) 01:45:45 ]
>>803

もちろん、プロセッサはそのための命令を(普通は)用意しているが
コストがかかるため、普通にソースを書いた場合
コンパイラはその命令を使ったコードは出力しない。

807 名前:デフォルトの名無しさん mailto:sage [2006/08/05(土) 02:10:07 ]
( ゚д゚)ポカーン

808 名前:デフォルトの名無しさん mailto:sage [2006/08/05(土) 02:18:37 ]
急に暑くなったからな。

そっとしておいてやれ。



809 名前:デフォルトの名無しさん mailto:sage [2006/08/05(土) 02:23:40 ]
最近近くに引っ越してきたvolatile asmというものですが何か?

810 名前:デフォルトの名無しさん mailto:sage [2006/08/05(土) 02:31:33 ]
>>746

811 名前:デフォルトの名無しさん mailto:sage [2006/08/05(土) 09:44:05 ]
volatile最高!!!

無駄にmutexしてる奴、馬鹿杉www

sizeof(int)以下ならlockなんて不要www

812 名前:デフォルトの名無しさん mailto:sage [2006/08/05(土) 09:54:47 ]
本気で言ってんの?

だからvolatileと排他のロック概念は関係ないっつーの。

volatileは他のコンテキストや割り込みで変更される可能性
があることをコンパイラに知らせて最適化を抑制するだけ。

>sizeof(int)以下ならlockなんて不要www
大抵はうまく行くだろうが、時たま失敗するだろう。

以下を沢山のスレッドつくって呼び出しまくってみな。

volatile int a,b;
void foo(){
a++;
InterlockedIncrement(&b);
}

しばらく走らせていたらaとbが一緒になるか?

813 名前:デフォルトの名無しさん mailto:sage [2006/08/05(土) 10:14:01 ]
>>811

本気で言っているとしたら
知らない人が知らないところで働いていることを理解できないようですね


814 名前:デフォルトの名無しさん mailto:sage [2006/08/05(土) 10:18:41 ]
>>812
この人なんかずれてる…

815 名前:デフォルトの名無しさん mailto:sage [2006/08/05(土) 10:30:47 ]
どの辺がすれてるのかkwsk

816 名前:デフォルトの名無しさん mailto:sage [2006/08/05(土) 10:33:19 ]
字下げが

817 名前:デフォルトの名無しさん mailto:sage [2006/08/05(土) 12:49:28 ]
オチがよろしいようで

818 名前:デフォルトの名無しさん mailto:sage [2006/08/05(土) 14:56:34 ]
>>815
>>811は書き込みの話はしていない、ってことじゃ?
データバスサイズのリードの話に限定するなら、
普通はバスレベルでも割り込まれることはないから
わざわざバスロックする必要はないと。

「無駄にmutex」がツボだと思うんだけど、ちとエスパーすぎるかな。



819 名前:デフォルトの名無しさん mailto:sage [2006/08/05(土) 15:16:29 ]
やさしすぎだと思う。

820 名前:デフォルトの名無しさん mailto:sage [2006/08/05(土) 16:42:27 ]
そもそもCではvolatile参照の意味は処理系定義だ。
参照時にlock/unlockする処理系もありうるし、volatile参照を最適化で
削除してしまう処理系もある(マニュアルに書かれている)。

Javaのvolatileはまた違う意味を持っているし。

821 名前:デフォルトの名無しさん mailto:sage [2006/08/05(土) 19:31:21 ]
ここ読め。
1.8 Program execution [intro.execution]

822 名前:デフォルトの名無しさん mailto:sage [2006/08/05(土) 21:02:19 ]
>820でFA?

823 名前:デフォルトの名無しさん mailto:sage [2006/08/05(土) 22:17:01 ]
>>820
volatile 参照の削除はできないだろ。

824 名前:デフォルトの名無しさん mailto:sage [2006/08/05(土) 22:25:56 ]
>>823
820が言うとおりvolatile参照は処理系定義。
某組み込み向けコンパイラでは、マニュアルに「sequence pointを含まない
式中のvolatile参照は削除されうる」と定義されていたりする。

825 名前:デフォルトの名無しさん mailto:sage [2006/08/05(土) 22:47:47 ]
>>824
それって、ふたつのシーケンスポイントの間で同じ volatile オブジェクトを複数回
参照する場合、1回にまとめられることがある、ってことだよね?

826 名前:デフォルトの名無しさん mailto:sage [2006/08/05(土) 23:07:40 ]
>>825
yes

827 名前:デフォルトの名無しさん mailto:sage [2006/08/06(日) 10:53:58 ]
sequence pointウンヌンが書いてないから、

>820でFA?

はありえない。>>821の示しているものには詳しく書いてある。
そこのところをそのまま理解するのがFA。

828 名前:デフォルトの名無しさん mailto:sage [2006/08/06(日) 11:14:29 ]
要はvolatileでokかngかは言語及び処理系依存ってこと。

それを無視して擁護する奴も批判する奴も間違っている。



829 名前:デフォルトの名無しさん mailto:sage [2006/08/06(日) 11:17:05 ]
処理系定義の範囲は?
volatile参照に対してハードディスクをフォーマットするコードを出すのもありなのか?

830 名前:デフォルトの名無しさん mailto:sage [2006/08/06(日) 11:23:23 ]
>>828
「volatileでokかngか」

こういういい加減な設問の立て方はやめれ

831 名前:デフォルトの名無しさん mailto:sage [2006/08/06(日) 11:24:07 ]
>>829
それを処理系定義動作として明記していれば、それはANSI準拠なコンパイラとして正しい。

そんなコンパイラは売れないだろうが。

832 名前:デフォルトの名無しさん mailto:sage [2006/08/06(日) 11:30:01 ]
じゃあvolatile参照の前後でlock/unlockするANSI Cコンパイラ作ったら売れるかな?

833 名前:デフォルトの名無しさん mailto:sage [2006/08/06(日) 11:56:47 ]
>>832
自分で lock/unlock すればいい。そんな奇怪な動作をするコンパイラは要らない。

834 名前:デフォルトの名無しさん mailto:sage [2006/08/06(日) 16:58:08 ]
じゃあvolatile参照の前後でミサイル発射するANSI Cコンパイラ作ったら売れるかな?

835 名前:デフォルトの名無しさん mailto:sage [2006/08/06(日) 17:09:29 ]
自分で面白いと思って書いてるんだったら相当やばい。

836 名前:デフォルトの名無しさん mailto:sage [2006/08/06(日) 17:11:32 ]
>>834
自分で発射すればいい。そんな奇怪な動作をするコンパイラは要らない。

837 名前:デフォルトの名無しさん mailto:sage [2006/08/06(日) 17:15:21 ]
ていうかコンパイラだけでミサイル発射できるならしてみろw

838 名前:デフォルトの名無しさん mailto:sage [2006/08/06(日) 17:23:34 ]
はいはい
続きはここでやれな
pc8.2ch.net/test/read.cgi/tech/1147746792/



839 名前:デフォルトの名無しさん [2006/08/09(水) 00:24:50 ]
突然ですが非同期をするメリットって何でしょうか?

840 名前:デフォルトの名無しさん mailto:sage [2006/08/09(水) 00:38:57 ]
シャンプー

841 名前:デフォルトの名無しさん mailto:sage [2006/08/09(水) 00:51:16 ]
いや、メリットは同期してると思うが

842 名前:デフォルトの名無しさん mailto:sage [2006/08/09(水) 01:07:53 ]
>>839
スレッド、プロセス、タスクはただ待たせとくには、
もったいなさ過ぎるリソースなんじゃ!

スレッドプールでぐぐれ!

843 名前:デフォルトの名無しさん mailto:sage [2006/08/09(水) 01:08:25 ]
リンスも利いてるし?

844 名前:デフォルトの名無しさん mailto:sage [2006/08/09(水) 07:28:17 ]
ZPt

845 名前:デフォルトの名無しさん mailto:sage [2006/08/09(水) 10:19:08 ]
ちゃん・りん・しゃん、という選択肢

846 名前:デフォルトの名無しさん mailto:sage [2006/08/09(水) 10:23:33 ]
>>842
スレッドプールの中のスレッドはほとんど待ってるだけだぞw

847 名前:842 mailto:sage [2006/08/09(水) 11:11:59 ]
>>846
プールとか書いたんは、俺なりの「サプライズ」や。
色んな意見があるのはわかっとるし、好きに言うたらええ。
俺はまた覚えたての言葉使って、レスしていくだけや。


848 名前:デフォルトの名無しさん mailto:sage [2006/08/09(水) 11:54:36 ]
んまあ、I/Oとか凍り付いて待ってる間に他の仕事が出来るのがメリットだわね。
多くの場合、他の仕事っていうのは、ユーザに対して「やってますよ、生きてますよ」っていう
アピールをすることだったりするけどw



849 名前:デフォルトの名無しさん mailto:sage [2006/08/09(水) 12:49:31 ]
>>846
馬鹿?

850 名前:デフォルトの名無しさん mailto:sage [2006/08/09(水) 13:14:16 ]
だっておまい、単純なスレッドプールなら、
例えばプールにスレッドが10個あってタスクが2個だったら8つは待ってるだけじゃんか。
まあ、忙しさに合わせてスレッド数を適当に増減させるような実装も可能だけど。

851 名前:デフォルトの名無しさん mailto:sage [2006/08/09(水) 13:17:55 ]
スレッドプールの利点
・タスクが200個あるけど、同時に動くのは最大10個
・スレッド生成が頻発な場合、生成のボトルネックを消す


852 名前:デフォルトの名無しさん mailto:sage [2006/08/09(水) 13:24:35 ]
スレッド数の上限を制御したいときも使うわね

ていうかすみませんでしたよ。
軽い気持ちで書いただけなんですよごめんなさい。

853 名前:デフォルトの名無しさん mailto:sage [2006/08/09(水) 15:55:01 ]
大したテクニックじゃない気がするんだが…。


854 名前:デフォルトの名無しさん mailto:sage [2006/08/09(水) 19:20:00 ]
大したテクニックじゃないといけないのか?

855 名前:デフォルトの名無しさん mailto:sage [2006/08/09(水) 20:09:24 ]
>>850
そんなの実装に依存。
議論するだけ無駄だなw

pool状態のthreadはqueueに入れないから、待つことはないって場合もあるだろうし。

856 名前:デフォルトの名無しさん mailto:sage [2006/08/09(水) 22:11:11 ]
>>855
スレッド、プロセス、タスクはただ待たせとくには、
もったいなさ過ぎるリソースなんじゃ!

スレッドプールでぐぐれ!

857 名前:デフォルトの名無しさん mailto:sage [2006/08/09(水) 22:46:54 ]
非同期のメリットは何かと聞かれてスレッドプールでググれって言われてもアレだな

858 名前:デフォルトの名無しさん [2006/08/10(木) 00:56:12 ]
このエディタは非同期でテキスト入力してるっていわれたんだけど
じゃあ入力以外に何か処理やってるのかな?



859 名前:デフォルトの名無しさん mailto:sage [2006/08/10(木) 00:57:44 ]
個人情報の流出

860 名前:デフォルトの名無しさん mailto:sage [2006/08/10(木) 07:40:47 ]
仁義無きエディタ

861 名前:デフォルトの名無しさん mailto:sage [2006/08/10(木) 08:46:31 ]
キー入力拾うのと、バッファに突っ込むのが非同期なんじゃね?

862 名前:デフォルトの名無しさん mailto:sage [2006/08/10(木) 09:39:08 ]
>>858
GUIのエディタだと、
ウィンドウサイズ変えられるのに対応したり、
マウスで指定された範囲を反転表示したり。

863 名前:デフォルトの名無しさん mailto:sage [2006/08/10(木) 10:35:09 ]
しながら同時にテキスト入力できるのか!

864 名前:デフォルトの名無しさん mailto:sage [2006/08/10(木) 10:39:46 ]
>>858
画面出力とか。

865 名前:デフォルトの名無しさん [2006/08/11(金) 22:57:19 ]
どこまでがマジレスなのか…

866 名前:デフォルトの名無しさん [2006/08/14(月) 21:40:21 ]
みんなスレッドプールって最大数超えた場合どうしてる?

867 名前:デフォルトの名無しさん mailto:sage [2006/08/16(水) 01:06:17 ]
再起動

868 名前:デフォルトの名無しさん mailto:sage [2006/08/16(水) 08:42:10 ]
海に行く



869 名前:デフォルトの名無しさん mailto:sage [2006/08/16(水) 18:56:59 ]
オレは泳がないから

870 名前:デフォルトの名無しさん mailto:sage [2006/08/18(金) 00:26:11 ]
眺めてるだけでも心和むじゃまいか

871 名前:デフォルトの名無しさん mailto:sage [2006/08/18(金) 07:41:37 ]
潜りてー
あの不要な音が聞こえない感覚が良いんじゃー

872 名前:デフォルトの名無しさん [2006/08/18(金) 14:51:42 ]
>>866
@IT:連載:.NETマルチスレッド・プログラミング入門 第4回
www.atmarkit.co.jp/fdotnet/mthread/mthread04/mthread04_01.html - 53k - キャッシュ - 関連ページ


スレッドプールのカスタマイズ
www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=27266&forum=12&3 - 26k - キャッシュ - 関連ページ
[ 他、www.atmarkit.co.jp内のページ ]



スレッドプール 最大数 の検索結果 約 1,440 件中 1 - 50 件目 (0.59 秒)


873 名前:デフォルトの名無しさん mailto:sage [2006/08/18(金) 19:28:16 ]
大阪には株式会社モータープールがあり、東京には株式会社月極がある。


874 名前:デフォルトの名無しさん mailto:sage [2006/08/26(土) 09:06:17 ]
MFCでマルチスレッドのプログラムを作成していますが、引数の受け渡しのところで悩んでいます

struct ThreadParams{
  int a;
  int b;
  int c;
};

BOOL MyApplicationDlg::OnInitDialog()
{
  …
  struct ThreadParams tParams;
  tParams.a = 1; tParams.b = 2; tParams.c = 3;
  AfxBeginThread(MyThread, (LPVOID)&tParams, THREAD_PRIORITY_NORMAL);
  return TRUE;
}

UINT MyApplicationDlg::MyThread(void * param)
{
  struct ThreadParams tParams = (struct ThreadParams)(*param); ←ここで既に呼び出し元のtParamsが消えているかも?
  /* tParamsを使っていろいろ処理 */
  return 0;
}

上のようなコードを書いたのですが、OnInitDialog中のtParams変数のスコープは関数内だけなので
MyThread関数でtParamsを受け取ろうとしたときには既に消えている可能性があるのではないかと思いました。
こういう場合には呼び出し元で new してスレッドの方で delete するとかで対処するのでしょうか?
他に何かよい方法があればアドバイスをお願いします。

875 名前:デフォルトの名無しさん mailto:sage [2006/08/26(土) 09:33:15 ]
MyThread()とダイアログクラスの結びつきが強いのなら、クラスメンバにしておけばいいんでない?
要は、スレッドよりも長寿命ならいいわけだから。
#ダイアログクラスよりもスレッドの方が長寿ならこの手は使えないのは当然だけど。

876 名前:874 mailto:sage [2006/08/26(土) 10:20:36 ]
そうですね。ぐぐって探してみましたがクラスメンバにしているサンプルがありました
とりあえずこの方法でやってみます。ありがとうございました

877 名前:デフォルトの名無しさん mailto:sage [2006/08/26(土) 10:26:12 ]
>>874
あんたの心配は正しい。

領域を渡して後はスレッド側でよろしことする以外にも...

・スレッド側で (コピーしておくとして) そのパラメータを
 使わなくなるまで親を待たせる。

・領域を静的に確保する。

・スレッドが起動してからパイプとかでパラメータをもらう。

等等。個人的には new / delete を使うことが多い。

878 名前:デフォルトの名無しさん mailto:sage [2006/08/26(土) 19:08:33 ]
volatileですべて解決します。

グローバル変数にvolatile属性を付けて置く。

これ最強。




879 名前:デフォルトの名無しさん mailto:sage [2006/08/26(土) 19:17:49 ]
>>878
 >>877
 >・領域を静的に確保する。

880 名前:デフォルトの名無しさん mailto:sage [2006/08/26(土) 20:26:54 ]
何でvolatileネタって流行ってるの?
とくに引っ張って面白いネタとも思えないけど

881 名前:デフォルトの名無しさん mailto:sage [2006/08/26(土) 21:25:02 ]
sizeof(int)以下ならvolatileでいいですよね?
排他は重いからやりたくないんですが・・・

という馬鹿が一時期沸いた

882 名前:デフォルトの名無しさん mailto:sage [2006/08/26(土) 21:28:54 ]
すごいな
全く意味のわからん質問だ

883 名前:デフォルトの名無しさん mailto:sage [2006/08/27(日) 16:59:50 ]
マルチスレッドなんか使わなければ解決

884 名前:デフォルトの名無しさん mailto:sage [2006/08/27(日) 19:58:38 ]
>>877
スレッドを越えてのnew / deleteは止めとけ。
つーか、調べると分かるが、状況によって手痛いしっぺ返しを喰らうぞ。


885 名前:デフォルトの名無しさん mailto:sage [2006/08/27(日) 21:05:30 ]
アホ発見 >>884

状況を具体的に説明してみろよ

886 名前:デフォルトの名無しさん mailto:sage [2006/08/27(日) 21:34:42 ]
>>884
それは874に宛てるべき内容だ。

呼ぶ側がdeleteするか、呼ばれた側がdeleteするかは統一するべきだとは思う。
呼ばれた側がdeleteする場合は、浅いコピーをして使い回す場合に対応できないからオススメできない。

887 名前:デフォルトの名無しさん mailto:sage [2006/08/27(日) 23:06:55 ]
>>886
> 呼ばれた側がdeleteする場合は、浅いコピーをして使い回す場合に
> 対応できないからオススメできない。

kwsk

888 名前:デフォルトの名無しさん mailto:sage [2006/08/28(月) 00:21:30 ]
シャローコピーで参照を共用してる場合
データレースが起きるよヤバイよって事じゃないの?

そんなもん別スレッドに渡すなよと思うけど



889 名前:888 mailto:sage [2006/08/28(月) 00:23:33 ]
なんか違うな
忘れてくれ

890 名前:デフォルトの名無しさん mailto:sage [2006/08/28(月) 00:41:46 ]
しったかぶりっこ

891 名前:デフォルトの名無しさん mailto:sage [2006/08/28(月) 01:49:18 ]
参照ってもスレッドに渡す前に参照カウント1アゲるだろ

892 名前:デフォルトの名無しさん mailto:sage [2006/08/28(月) 01:50:45 ]
ぶるぶるぶりっこ

893 名前:デフォルトの名無しさん mailto:sage [2006/08/28(月) 02:58:49 ]
一体何の話をしてるのだろう?

894 名前:デフォルトの名無しさん mailto:sage [2006/08/28(月) 05:08:03 ]
ぶりっ子ロックンロール / 紅麗威甦

895 名前:デフォルトの名無しさん mailto:sage [2006/08/28(月) 20:39:11 ]
環境はWindowsです。
メインスレッドで生成されたWindowから、別スレッドを起動します。
このスレッドは、ファイルを1行づつ読み、
vector<string>に50件溜まったら、Windowへ通知します。
とりあえず下のような感じで組んだのですが、
Windowsが閉じられた場合、このスレッドを破棄しないといけません。
もしスレッドを破棄したらNetFileReaderのオブジェクトって、
解放されないのですよね。
こういうプログラムって、どうやって組むのが良いでしょう?

static vector<string> text;

void NetwordThread::execute(void* pData) {
 MyWindow* win = (MyWindow*)pData;

 NetFileReader* reader = new NetFileReader("hoge.txt");
 string* line;
 while ((line = reader->readLine()) != NULL) {
  text.push_back(*line);
  if (text.size() > 50) {
   SendMessage(win->m_hWnd, WM_MY_MESSAGE, NULL, (LPARAM)&text);
   text.clear();
   Sleep(10);
 }
 SendMessage(win->m_hWnd, WM_MY_MESSAGE, NULL, (LPARAM)&text);
text.clear();

 _endthread();
}


896 名前:デフォルトの名無しさん mailto:sage [2006/08/28(月) 21:25:26 ]
中断フラグを作って、メイン側で Window を閉じる時に
フラグを On にする。

スレッド側は中断フラグを一行毎にチェックしてて、
On になったら、速やかに終了する。

通常のディスクファイル相手ならこれでいいと思う。

ネットワークファイルとかで一行の読み出しにすごく時
間がかかる場合があるならその読み出し処理自体を中断
する必要があると思う。

897 名前:デフォルトの名無しさん mailto:sage [2006/08/28(月) 21:52:15 ]
ていうか、「Windowが閉じられたら」とか「スレッドを破棄」とか書いてるけど
普通は、閉じるボタンが押されたら、フラグなりイベントなりでスレッドに対して終了を通知して
ワーカースレッドは自分で後始末をしてから終了する、
GUIスレッドはワーカースレッドが終了するまで待機する
っていうふうに作るのが普通だろ。

898 名前:895 mailto:sage [2006/08/28(月) 21:54:13 ]
どもです。
中断フラグをONするメソッド作って、中はMutexで排他処理、
スレッドのexecute()の方はSendMessage()をMutexで排他処理
しておけば、1行ごとにチェックまではしなくてよいかな?
あと、スレッドの中でSleep()呼ばないと、このスレッドに完全に制御が移ってしまい、
スレッドが終了するまでWindowが固まってしまいます。
これはそういうもんでしょうか?
マルチスレッドって、どこで処理が割り込むかわからないものだと思っていたのですが。



899 名前:895 mailto:sage [2006/08/28(月) 21:55:29 ]
>>897
書き込み中にレスが。
ええ、その「普通はこうだ」ってのが聞きたかったんです。
なにぶん素人なのもので・・・

900 名前:デフォルトの名無しさん mailto:sage [2006/08/28(月) 22:05:09 ]
固まらなねーよ。
プライオリティとかいじってなきゃな。

901 名前:895 mailto:sage [2006/08/28(月) 22:25:55 ]
_beginthread()呼んでるだけで、プライオリティはいじってないですね。
ActiveX内で、やってるからかなぁ。

902 名前:デフォルトの名無しさん mailto:sage [2006/08/28(月) 23:06:40 ]
>>895
>解放されないのですよね。
そもそも、なんで new で割り当ててんの?

903 名前:デフォルトの名無しさん mailto:sage [2006/08/29(火) 04:29:53 ]
>>898
> あと、スレッドの中でSleep()呼ばないと、このスレッドに完全に制御が移ってしまい、
> スレッドが終了するまでWindowが固まってしまいます。

SendMessage()のせいじゃね?

904 名前:895 mailto:sage [2006/08/29(火) 14:19:52 ]
>>903
その通りでした。SendMessageは使わない方がよさそうですね。
スレッドがデータ格納するバッファは、Window側でタイマーで定期的に監視。
スレッドがバッファに格納するときと、Windowがバッファから取得するときは、
mutexで排他処理かましておくと良いかな。

905 名前:デフォルトの名無しさん mailto:sage [2006/08/29(火) 16:46:22 ]
PostMessage()使ってみたら?

906 名前:デフォルトの名無しさん mailto:sage [2006/08/29(火) 20:26:56 ]
タイマーで監視しなくても、PostMessage()で合図送ればいんじゃね?

907 名前:895 mailto:sage [2006/08/29(火) 21:41:10 ]
PostMessageだと、ちょっと不安があってやめたんです。
たとえば、スレッドからPostMessageを呼んだ直後に、
Windowのスレッドがアクティブになって、Windowを閉じる処理をした場合、
Windowのハンドルが無効になった後に、メッセージを飛んできて、
死亡したりしませんかね?

908 名前:デフォルトの名無しさん mailto:sage [2006/08/29(火) 21:42:23 ]
誰が死亡するの?



909 名前:895 mailto:sage [2006/08/29(火) 21:50:03 ]
オサーンのプログラム。無効なウィンドウハンドルに投げようとして
ハングしたりしないかなと。

910 名前:デフォルトの名無しさん mailto:sage [2006/08/29(火) 21:51:47 ]
       ,、‐ " ̄:::゙:丶、
    ,r::::l3゙::::::::/ハヽ:ヽ::::、:ヽ
    {::://:::::::// ヽ\ト、:::::::!
    ヾ l:::::::/ 丶   `ヾ ィ、:::|
     |;:r::|  O`  'O ゙ハ|   < ないない
      ヽハ :.:.    :.: レ
        ´\ r‐--‐、,ノ
 r、     r、/ヾ ̄下ヘ
 ヽヾ 三 |:l1、_ヽ/__ .ィヽ
  \>ヽ/ |` }    n_n| |
   ヘ lノ `'ソ     l゚ω゚| |
    /´  /      ̄|. |
    \. ィ   ___ |  |
        | ノ     l |  |
      | |      i:|  |

911 名前:デフォルトの名無しさん mailto:sage [2006/08/29(火) 22:29:31 ]
>>907
> メッセージを飛んできて、
> 死亡したりしませんかね?

メッセージを割り込みみたいなもんと勘違いしてないか?

912 名前:895 mailto:sage [2006/08/29(火) 22:58:03 ]
いや、それはないです。
PostMessageも当然、中でいろいろやってますよね。
PostMessageで実際にキューにメッセージ入れる直前に、
Windowのスレッドに切り替わることってないんですかね?


913 名前:デフォルトの名無しさん mailto:sage [2006/08/29(火) 23:09:22 ]
そろそろスレ違い

914 名前:デフォルトの名無しさん mailto:sage [2006/08/30(水) 00:04:27 ]
>>909
無効なハンドル次第では、デスクトップの再描画とか起こるかも。

915 名前:デフォルトの名無しさん mailto:sage [2006/08/30(水) 00:26:29 ]
>>914
909じゃないけど詳しく教えてください

916 名前:デフォルトの名無しさん mailto:sage [2006/09/05(火) 22:30:07 ]
そりゃロックしたままSendMessageしたらデッドロックだろうよ

917 名前:デフォルトの名無しさん [2006/09/06(水) 21:28:12 ]
居なくなった人のプログラムを押し付けられたんだけど、
CreateThread()した後、即CloseHandle()している。
どうして即CloseHandle()するのか、
Thread関数内のExitThread()直前に呼べばいいんじゃないのか、
そもそもCloseHandle()しなくてもExitThread()するんだから要らないんじゃないのか
と思うんですが、誰も(??)
そのままにしておけばいいんでしょうか。

918 名前:デフォルトの名無しさん mailto:sage [2006/09/06(水) 21:53:38 ]
>>917
MSDN の CreateThread あたりに理由は書いてあると思ったけど、
調べてみた? 推測はほどほどにして、ちゃんと確認したほうがいいよ。




919 名前:デフォルトの名無しさん mailto:sage [2006/09/07(木) 01:04:39 ]
>>917
> Thread関数内のExitThread()直前に呼べばいいんじゃないのか、

ハンドルの話じゃないけど…

マルチスレッドプログラミングにおいて、「〜の直前だから大丈夫」
なんてこと考えてたらはまるよ。

920 名前:デフォルトの名無しさん mailto:sage [2006/09/07(木) 13:24:51 ]
>>917
CreateThread - ExitThread - CloseHandleするのがここでのならわし。
盲目的にこうしてればいいよ。

921 名前:デフォルトの名無しさん mailto:sage [2006/09/07(木) 15:03:17 ]
ぉぃぉぃ

922 名前:デフォルトの名無しさん mailto:sage [2006/09/08(金) 00:47:23 ]
いやmmapしないとダメ

923 名前:デフォルトの名無しさん [2006/09/08(金) 12:38:24 ]
ロックしないでグローバル変数に(intなど機械語1命令で読み書き可能な
サイズという条件で)アクセスするケースを考えます。

int a;
void thread1(){
 while(1)a=0x0000ffff;
}
void thread2(){
 while(1)a=0xffff0000;
}
void thread3(){
 while(1)printf("%08x\n",a);
}

このとき、thread3で0x0000ffffか0xffff0000以外の数字が
表示される可能性はありますか?


924 名前:923 mailto:sage [2006/09/08(金) 12:40:49 ]
補足ですが、シングルプロセッサとマルチプロセッサ両方の
ケースでどうなのか知りたいです。環境はWindows2000以降の
x86アーキテクチャを想定しています。

925 名前:デフォルトの名無しさん mailto:sage [2006/09/08(金) 13:17:47 ]
aの初期値が延々と表示される可能性すらあるな

926 名前:デフォルトの名無しさん mailto:sage [2006/09/08(金) 22:28:47 ]
volatile厨臭いな
釣りか?
釣られたのか?

927 名前:デフォルトの名無しさん mailto:sage [2006/09/08(金) 23:08:48 ]
>>923
メモリーバスが CPU のバストランザクションをソフトの都合に会わせて
実行する保証はどこにもないんだから

バスサイズ 8 bit のシステムで
1 on cpu0
2 on cpu1
3 on cpu2
ってシチュエーション考えれば何でもありじゃん


928 名前:デフォルトの名無しさん mailto:sage [2006/09/08(金) 23:34:45 ]
あっそう




929 名前:923 mailto:sage [2006/09/09(土) 02:25:04 ]
>>925>>926
すみません。初期値の部分は、

volatile int a = 0xffff0000;

とさせてください。後付申し訳ないです。この辺はあまり捻らないで(^^;)

>>927
>ってシチュエーション考えれば何でもありじゃん

実際問題として、Windowsのマルチプロセッサ環境で失敗する
例を容易に確認できますでしょうか? ハード環境を簡単に
用意するわけにも行かないので、いろんな人が見ているここに
尋ねてみました。

シングルプロセッサでは失敗するケースはこれまでの経験上無い
ものと思われますが…(こちらは失敗するケースを見たことないです)


930 名前:デフォルトの名無しさん mailto:sage [2006/09/09(土) 04:21:21 ]
前スレでまったく同じ議論があったよ
保証されるかどうかはアーキテクチャに強く依存する
それこそIntelとAMD、Intel内でもその世代により異なる

>シングルプロセッサ

マルチコア時代にそういう括りはやめたがいい
HTもキャッシュ絡みでerattaがあった

ひとつ聞いとこう、趣味?仕事?

931 名前:デフォルトの名無しさん mailto:sage [2006/09/09(土) 05:04:16 ]
386SX以外の32bitx86は
メモリバス(システムバスでもHTバスでも)は32bit同時に読み書きするだろ。
キャッシュが反映されないとか関係ない。
全部(全bit)書き込まれるか、全部書き込まれないかどちらか。

932 名前:デフォルトの名無しさん mailto:sage [2006/09/09(土) 05:06:02 ]
あ、ちゃんとアラインされている場合の話ね。

933 名前:仕様書無しさん mailto:sage [2006/09/09(土) 08:41:48 ]
>931-932
マルチプロセッサ環境で、あるCPUが内部キャッシュ内に保持しているDWORD
値の一部バイトを書き換えて、ライトバックする前に、ほかのCPUがDWORDの
一部バイトを書き換えるという状態になったらどう動作すんの?


934 名前:923 mailto:sage [2006/09/09(土) 09:07:35 ]
>>932
Interlock系のAPIがマルチプロセッサ環境では32bitアラインを要求しますね。
関連があるのでしょうかね?

>>933
こちらへのレスではありませんが、おっしゃるケース
(一部書き換え)は考えてません。問題にしたいのは
全ビット書き換えた時読み出し時に一部しか書き変わ
っていない状況があるかどうか、なので。

ちょっと動作検証と、ロック有り無しの場合で性能的に
どれほど差が出るのかプログラムを作って試してみたいと思います。

935 名前:デフォルトの名無しさん [2006/09/09(土) 09:21:18 ]
volatile最強!!!

936 名前:デフォルトの名無しさん mailto:sage [2006/09/09(土) 09:41:14 ]
Interlockとか_MemoryBarrier使わない必要性あるの?
速度が必要ならアルゴリズムとか排他制御の範囲とか無待機アルゴリズムとか
から高速化できないの?
スレッドの優先順位とか、他のプロセスの稼動状況とかでも状況変わるから
動作検証を完全にやることは無理でしょ。
CPUやMBの仕様書をNDA結んで手に入れて調べるぐらいしないと。

937 名前:デフォルトの名無しさん mailto:sage [2006/09/09(土) 09:45:06 ]
>>933
それは「起こらない」でしょ。
なぜならば、キャッシュ間のコヒーレンシを保つための仕組みを持っているのが
マルチプロセッサシステムだから。

938 名前:デフォルトの名無しさん mailto:sage [2006/09/09(土) 09:51:15 ]
>>934
特定少数の chip setに限定するとかなら話は別だろうけど,
C コンパイラが LOCK prefix つけて load/store するコードを
吐き出すわけではないし, ハードウェアの作り次第だと思われ...




939 名前:デフォルトの名無しさん mailto:sage [2006/09/09(土) 09:53:31 ]
>>937の仕組みが外部バス接続のために遅くなり、糞CPUと呼ばれたのがPenD。

940 名前:デフォルトの名無しさん [2006/09/09(土) 10:30:49 ]
ついにvolatileの最強さが証明されるわけだ

>>811

おめでとう

941 名前:デフォルトの名無しさん mailto:sage [2006/09/09(土) 12:02:27 ]
>>937
何が「起こらない」っと言ってるのか...。

942 名前:923 mailto:sage [2006/09/09(土) 12:45:41 ]
>>936>>938
ロックしないと明らかにまずい状況はもちろんロックしますが、
単純な場合はロック無しでできたらいいという場面もありそうです。

皆さん、スレッド間で共有されるグローバル変数全て、万一の場合に
備えてくまなくロック系API使ってアクセスしてますか?

「書いて」「読んで」その状況において不都合がない場合は、
API通さずに普通のCの文法で書ければ言うことはないじゃないですか。

スレッド系の解説してる本にも、単純なカウンターとかロック系の
API無しでアクセスしてます。ここで問題にしているのはそういう
ごく単純なプリミティブなアクセスの話です。

NDAや「ハードウェアの作り次第」とか、そういう話まで持ち出されるのは
個人や小さい事業所でどうこうするのは不可能ですし、現実的なアクション
とは到底言えないと思います。

要は世に出回っている大抵のWindowsマシンでおかしくならない線を
探せばいいのだと思います。パッケージには全てのマシンで動作保障
するものではありませんとか書いてるソフトもありますし、試せる
範囲でおかしくならなければ(試して失敗が一つも無ければ)、
完全な厳密性までは得られなくても、こちらのスタンスとしてはOKです。


943 名前:923 mailto:sage [2006/09/09(土) 12:46:30 ]

厳密性を完璧にするなら世の中のマシン全部で試さないといけない
じゃないという話にもなりますし、それはやはり現実味の無い話と
しては上に書いてあることと大差ありません。理論にも実装にも
ミスが無くてもおかしくなる環境は必ずあります。

一応持ってるマシンで検証プログラムを走らせましたがエラーする
ケースは一度も起きませんでした。

性能に関しては、ロック無しを1とした場合、Interlocked系で読み書き
すると5倍、CriticalSectionで排他すると200倍近い速度低下が起きます。
(テストプログラムは極端な例でしょう)

実際の使用状況は置いておき、5倍の負荷は精神的に嫌な感じです。
この辺気にしない人もいるでしょうが、気にしない人は他の場合でも
気にしないでしょうし、積み重なるともっさりしたソフトが出来そう
なので、検証不可能な厳密性よりもこういうほうに労力や気を払いた
いですね。

一応ソース貼っときますので、もし失敗例が実際に観測された人が居たら
教えてください。Windowsシステム上で一つでも反例があれば納得せざる
を得ません。逆にある程度のサンプルで試して一度もエラーが無ければ
それはOKというのが世の中というものでしょう。



944 名前:923 mailto:sage [2006/09/09(土) 12:50:44 ]
#include "stdafx.h"
#include "windows.h"
#include "winbase.h"
#include "process.h"
#include "mmsystem.h"
#pragma comment(lib, "winmm.lib")

#if 1 //ロック無し
#define set_a(n) a = n
#define get_a(v) v = a
#elif 0 //Interlocked系で読み書き
#define set_a(n) InterlockedExchange((long*)&a,n)
#define get_a(v) v = InterlockedExchangeAdd((long*)&a,0)
#else //CRITICAL_SECTION排他
#define _CS
CRITICAL_SECTION cs;
#define set_a(n) {EnterCriticalSection(&cs); a=n; LeaveCriticalSection(&cs);}
#define get_a(v) {EnterCriticalSection(&cs); v=a; LeaveCriticalSection(&cs);}
#endif
続く

945 名前:923 mailto:sage [2006/09/09(土) 12:51:29 ]
volatile int a = 0x00001111;
volatile int t1_ct,t2_ct;
void __cdecl thread1(void *param){
while(1){
set_a(0x00001111);
t1_ct++;
}
}
void __cdecl thread2(void *param){
while(1){
set_a(0x22220000);
t2_ct++;
}
}
続く

946 名前:923 mailto:sage [2006/09/09(土) 12:52:50 ]
int main(int argc, char* argv[])
{
#ifdef _CS
InitializeCriticalSection(&cs);
#endif
unsigned int id1;
HANDLE h1 = (HANDLE)_beginthread(thread1, 0, &id1);
unsigned int id2;
HANDLE h2 = (HANDLE)_beginthread(thread2, 0, &id2);
#if 0
while(1)printf("%08x\n",a);
#else
printf("実行中……\n");
int loop = 0;
int false_ct = 0;
DWORD time = timeGetTime();
while(loop++ < 100000000){
int t; get_a(t);
if(t != 0x00001111 && t != 0x22220000)
printf("不整合発見(%d):%08x\n",++false_ct,t);
if((loop & 0x7fffff) == 0)
printf("loop:%d……\n",loop);
}
続く

947 名前:923 mailto:sage [2006/09/09(土) 12:53:28 ]
time = timeGetTime() - time;
TerminateThread(h1,0);
TerminateThread(h2,0);
printf("ループ%d回、失敗%d回、実行時間%.3f秒\n",loop-1,false_ct,(double)time / 1000);
printf("スレッド1実行回数%d回\n",t1_ct);
printf("スレッド2実行回数%d回\n",t2_ct);
#ifdef _CS
DeleteCriticalSection(&cs);
#endif
#endif
return 0;
}



948 名前:デフォルトの名無しさん mailto:sage [2006/09/09(土) 12:55:06 ]
どうせなら、レスの最後を
/* 続く
として、次のレスの頭を
>xxxから */
とでもしてくれたらコピペの(後処理の)手間が減るのだが。



949 名前:923 mailto:sage [2006/09/09(土) 12:58:46 ]
済みません。あと、TerminateThreadしてるのはご愛嬌ということで。

950 名前:デフォルトの名無しさん mailto:sage [2006/09/09(土) 13:31:06 ]
>>943
> 一応持ってるマシンで検証プログラムを走らせましたがエラーする
> ケースは一度も起きませんでした。

じゃ、あなた的には、それでいいんじゃないでしょうか?

> 実際の使用状況は置いておき、5倍の負荷は精神的に嫌な感じです。
> この辺気にしない人もいるでしょうが、気にしない人は他の場合でも
> 気にしないでしょうし、積み重なるともっさりしたソフトが出来そう
> なので、検証不可能な厳密性よりもこういうほうに労力や気を払いた
> いですね。

「いかにして、ロックするべき部分を局所化して、ロックコンディションの
テストする回数を減らすか」
を考えるべきであって、
「ここで動くんだから大丈夫じゃないか、きっとよそでも動く!」
ってな発想はしてはならないと思いますけど。

じっさいに、4CPU程度のマシンで動いていたけど、16CPU程度の NUMA
アーキテクチャのターゲットマシンの持っていった場合、動作しなかった
って前例は何度もみてます。


951 名前:923 mailto:sage [2006/09/09(土) 13:50:37 ]
>>950
ソースを出してるので、失敗した出力を貼って
いただけないでしょうか? 動作させた環境も
出来たらお願いします。

952 名前:デフォルトの名無しさん mailto:sage [2006/09/09(土) 13:52:15 ]
もちろん、手持ちのマシンで動けば問題ないし、
たまにクラッシュしてもビジネス上問題ないならそれでいいんじゃ?

950も言ってるが、スレッドで共有する情報の塊に対してロックをかけるべきであって、
1足すとか状態を読んでそれに対する処理を行いさらに書くことはできないと思っておいたほうがいい。

それとソースだが、何でintrinsic命令使わないの?関数呼び出しコスト余計にかかってるよ。
printfのコストが多すぎだと思うが、計測間違ってない?
あと、そこまで考えるならtimeGetTimeはつかえないでしょ。
精度の設定もしてないし、明らかに少しかじった初心者がやりそうなソースだ。


953 名前:デフォルトの名無しさん mailto:sage [2006/09/09(土) 14:02:55 ]
だからホビーなんじゃないの?と

954 名前:923 mailto:sage [2006/09/09(土) 14:05:31 ]
>>952
>1足すとか状態を読んでそれに対する処理を行いさらに書くことはできないと思っておいたほうがいい。
もちろんです。

>printfのコストが多すぎだと思うが


全て成功するケースでは、1億回のうちprintfは11回だけです。
無視しても問題ないと思いますが。
(途中経過のprintfが無しでも、ストップウオッチ計測で
十分優位な差が得られるほど負荷が変化するのはわかりますし、
なんなら途中経過のprintfは取ってください)

計測ループの中ではロック系のAPI以外の呼び出しは上記の
途中経過表示の微々たるprintf以外無いですよ。

>timeGetTimeはつかえないでしょ。
動作が秒単位に対してtimeGetTimeは10msオーダーです。
精度としては十分じゃないのですか? もし不足だと感じたら、
パフォーマンスカウンターでも使って書きなおしてください。


955 名前:923 mailto:sage [2006/09/09(土) 14:07:51 ]
補足、
>十分優位な差が得られるほど負荷が変化する
ロックするしないを切り替えたときの負荷の変化です。

956 名前:923 mailto:sage [2006/09/09(土) 14:13:30 ]
後、今回の趣旨は、読み出し失敗があるかどうかなので、
そちらに関してお話ください。

レスを見ていると相当な環境の方もいるようですし、
ロック無しでの書き込みや読み出しがそれほど使用に
耐えないほどの不具合があるものなら、簡単に失敗の
ケースが出ると思います。

失敗した状況が貼られれば何より説得力がありますので、
よろしくお願い致します。

957 名前:923 mailto:sage [2006/09/09(土) 14:15:05 ]
あと、失敗しない限り発言しないでください。

失敗しなければ問題ありませんので。

958 名前:デフォルトの名無しさん mailto:sage [2006/09/09(土) 14:19:42 ]
>>942
> 要は世に出回っている大抵のWindowsマシンでおかしくならない線を
> 探せばいいのだと思います。

最近の風潮か?
製品事故が多くなった理由が垣間見えるようだ...。

>>943
> 理論にも実装にもミスが無くてもおかしくなる環境は必ずあります。

技術屋として見過ごせないんだけど、「ある」と言い切れる理由は?

>>957
> あと、失敗しない限り発言しないでください。

ここは、お前の検証スレじゃない。
そういう発言したいなら、自前の掲示板でも作れ。



959 名前:デフォルトの名無しさん mailto:sage [2006/09/09(土) 14:23:05 ]
intrinsicはスルーか。ソースまともに読むわけ無いだろ金ももらってないのに。
失敗する環境探したいなら、自分でマシン買ってやってろ。

960 名前:923 mailto:sage [2006/09/09(土) 14:27:21 ]
>>958
>製品事故が多くなった理由が垣間見えるようだ...。
どうもすみません(^^;)

>技術屋として見過ごせないんだけど、「ある」と言い切れる理由は?
話がそれたかもしれません。済みません。ユーザー環境の
不具合などです。完全な検証が出来ない以上、分る範囲で
調べることしか出来ないと思うので、完全完全を言われると
身動き取れなくなってしまうといいたかったのです。

後、>>957は悪戯じゃないですか?

961 名前:デフォルトの名無しさん mailto:sage [2006/09/09(土) 14:30:24 ]
>>923
うぜえ、消えろ('A`)

962 名前:デフォルトの名無しさん mailto:sage [2006/09/09(土) 15:23:18 ]
>>960
> ユーザー環境の不具合などです。

そのユーザー環境に「理論か実装」の不具合があるんでしょ。

「全ての環境で試験なんかやってられねー」と言うのは当然至極なんだけど、
理論的な裏づけもなく1万回やったから大丈夫と言うのはちょっと違う気が
する。

もちろん現実的には取りきれないバグをタイミングとかで逃げて1万回テス
トしたから多分大丈夫だよねーと言って出すケースはないわけじゃないけど、
技術屋としてはもやもやが残ってる。

そもそもこの話は「検証不可能な厳密性」じゃないよ。いくつもの論文があ
るし、このスレでも議論されてる。 (まともな意見のみを取り出すのは難しい
が)

> 後、>>957は悪戯じゃないですか?
いたずらなら、2行目は >>957 へのレスだ。
でも、いたずらかどうかにかかわらず1行目はあんたへのレスだよ。

963 名前:デフォルトの名無しさん mailto:sage [2006/09/09(土) 15:34:23 ]
>>923
提示されたソース読んでないけどさ、
同じ環境で何度ループしようがあまり意味ないんじゃね?

ゲーム開発では、3日3晩デモループさせて検証することだってあるんだよ?
それくらいのレアケースだって見逃せないっていうのは
技術者の自己満足じゃなくて、正しい姿勢なんじゃないか?

少なくとも「オレのマシンで動いてるからOKでしょ」って言う人とは
一緒に仕事したくないね。


964 名前:923 mailto:sage [2006/09/09(土) 17:02:17 ]
うざいとか言われつつ書き込んで済みません。

>>963
>同じ環境で何度ループしようがあまり意味ないんじゃね?
集中的に問題が起きるようなサンプルになってるとは思いますが。

たとえば似たようなケースで、あのサンプルの変数を代入じゃなくて
a++ とかにすれば値が順次増加せずに書き戻されたりするケースは
すぐに出ますので、検証手法としてあながち外れてるとも思えないです。

話はそれますがゲームの検証に関しては良く存じてます。
リリース前は2週間電源入れっぱなしで落ちないかどうか
とかやりますよね。(昔の話です)

>オレのマシンで動いてるからOKでしょ
オレのマシンだけというより、動かせる限りにおいてエラーに
ならなければ、というふうに考えてます。それ以上はやりよう
が無いですし。

こちらも手持ちの環境で複数台のマシンでチェックしても
エラーになるケースは無いので、もし他の方でエラーが実際
出るなら教えてもらえるとありがたいなと思ったしだいです。



965 名前:923 mailto:sage [2006/09/09(土) 17:20:22 ]
>>962
>このスレでも議論されてる
結論はどうだったのでしょう? 以下、各行が別スレッドで動くとして、

a=0x00001111;
a=0x22220000;
b=a;

で、bが0x22221111になるケースがあったのでしょうか?あまり対象を
広げても大変ですし、身近なWindows環境で。

たとえば68000CPUとかでアライメントを知らない人が、奇数アドレスに
byteより大きな単位でアクセスして落ちたりすると面食らうじゃ
ないですか。

PC互換機上で0x22221111のケースって、アライメント違反ほどに顕著な
現象じゃないですよね? で、実際のアプリでも、検証プログラムでも
不具合を(少なくとも当方は)見たことが無いとなると、Windowsアプリでは
「汎用レジスタから奇数アドレスへのアクセスが(遅いけど)許可されて」
いるように0x22221111のようなことは起こりえないものとしてプログラムを書いて
もいいんじゃないかと思ったのです。Windows依存だといわれればその通りです。

PC互換機の設計図やWindowsアプリの構築方法にやったらイカン
と明示してあれば従うのにやぶさかじゃないですけどそういうソースって
このスレで議論されたという中で、もし出てきたのならお教えください。

もしくは、現象が簡単に再現するプログラムの書き方があれば反例
として文句をつける余地はありません。

>理論的な裏づけもなく
もし検証プログラムに理論的なミスがあれば指摘してください。


966 名前:デフォルトの名無しさん mailto:sage [2006/09/09(土) 17:29:33 ]
>>923
>int a;
>void thread1(){
> while(1)a=0x0000ffff;
>}
>void thread2(){
> while(1)a=0xffff0000;
>}
>void thread3(){
> while(1)printf("%08x\n",a);
>}
>
>このとき、thread3で0x0000ffffか0xffff0000以外の数字が
>表示される可能性はありますか?

概出だと思いますが
CPU/ハードウェア(メモリの実装方法とか)/OSによって違うでしょう。
それ以上でもそれ以下でもありません。

967 名前:923 mailto:sage [2006/09/09(土) 17:29:41 ]
>>959
>intrinsicはスルーか。
済みません、仰りたいことの意味が良く分りませんでした。
このプログラムの要点は、

volatile long a = 0x00001111;
void thread1(){
 while(1)a=0x00001111;
}
void thread2(){
 while(1)a=0x22220000;
}
void main(){
_beginthread(thread1);
_beginthread(thread2);
 while(1)if(a != 0x00001111 && a != 0x22220000)エラー;
}

です。組み込み命令云々の余地があるのでしょうか?


968 名前:923 mailto:sage [2006/09/09(土) 17:41:20 ]
>>966
>CPU/ハードウェア(メモリの実装方法とか)/OSによって違うでしょう。
どうも。

Windowsでどうなのかが知りたいのです。
こちらとしてはWindowsアプリで問題ないという裏が取れればOKです。

このマザーボードだと駄目だ、とか言うのがあれば使えないですよね。



969 名前:デフォルトの名無しさん mailto:sage [2006/09/09(土) 17:50:27 ]
>>965
> 結論はどうだったのでしょう?

自分で読もうと言う気はないのか?

> もしくは、現象が簡単に再現するプログラムの書き方があれば反例
> として文句をつける余地はありません。

そんなもんがあったら苦労はしない。

> もし検証プログラムに理論的なミスがあれば指摘してください。

検証プログラムで現象が出ないからと言ってプログラムが正しいと考える
お前の思考。


970 名前:デフォルトの名無しさん mailto:sage [2006/09/09(土) 18:15:35 ]
>>923
とりあえず4CPUのマシンでも異常なしで動きましたのでご報告します。

971 名前:デフォルトの名無しさん mailto:sage [2006/09/09(土) 18:29:14 ]
>>969
>検証プログラムで現象が出ないからと言ってプログラムが正しいと考える

>>923 さんはそんなこと言ってないと思いますよ。

少なくとも検証プログラムですぐに問題が出るなら使い物にならない
と考えてるだけでは?

972 名前:923 mailto:sage [2006/09/09(土) 18:57:46 ]
>>970
ありがとうございます。
こちらは1億回を10億回にしても問題出ませんでした。
Pen4の1CPU-HT環境と、Pen3の1CPUです。

ちなみに、類似のプログラムとしてaに加算するケースを
動作させてしっかりエラーになりました。マルチスレッド
でのコンテキスト切り替えとアクセスを検証するプログラム
として動作がある程度的を得ているからだと思います。

また、加算だとPen3ではぜんぜんエラーにならないのも面白いですね。
1CPUなのである程度予想してましたが、コンテキスト切り替えの状況
がHTと違うようです。

>>971
擁護どうもです。970の人?

↓ちなみに加算テストへの変更点ですが、

973 名前:デフォルトの名無しさん mailto:sage [2006/09/09(土) 18:59:32 ]
 *     +    巛 ヽ
            〒 !   +    。     +    。     *     。
      +    。  |  |
   *     +   / /   イヤッッホォォォオオォオウ!
       ∧_∧ / /
      (´∀` / / +    。     +    。   *     。
      ,-     f
      / ュヘ    | *     +    。     +   。 +
     〈_} )   |                        
        /    ! +    。     +    +     * 
       ./  ,ヘ  |
 ガタン ||| j  / |  | |||
――――――――――――


974 名前:923 mailto:sage [2006/09/09(土) 18:59:57 ]
#elif 1 //インクリメントテスト
#define _INC
#define set_a(n) a++
#define get_a(v) v = a
int max = 0; //これはmain内のローカル変数でも良い
#elif 0 //Interlockedでインクリメントテスト
#define _INC
#define set_a(n) InterlockedExchangeAdd((long*)&a,1)
#define get_a(v) v = InterlockedExchangeAdd((long*)&a,0)
int max = 0;
:
:
と、以下がループ内抜粋
int t; get_a(t);
#ifndef _INC
if(t != 0x00001111 && t != 0x22220000)
printf("不整合発見(%d):%08x\n",++false_ct,t);
#else
if(max < t){
max = t;
}
if(max > t){
printf("不整合発見(%d)%d,max:%d\n",++false_ct,t,max);
}
#endif

です。HTマシンではInterlockedしないと一瞬でエラー続発です。


975 名前:デフォルトの名無しさん mailto:sage [2006/09/09(土) 19:25:16 ]
面倒なので代入と加算とそれぞれのロックありなしの場合を
すべて同時にテストできるプログラムにしていただけませんか?
あと、レポートも不具合ありなしだけじゃなくて、使用CPU構成や
OSバージョンなども表示されると素敵ですね。
それから、ソースはここの数レス消費する貼り方せずに
ttp://kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/joyful.htm
あたりのうpろだを使っていただくのが
協力者以外のひとに迷惑かからなくてよろしいかと思います。


976 名前:デフォルトの名無しさん mailto:sage [2006/09/09(土) 19:27:00 ]
お前用の検証スレじゃないんだけど。

もう言いたいことは言ったろ

うざいからwikiでも立ててそっちでやってくんね?

977 名前:デフォルトの名無しさん mailto:sage [2006/09/09(土) 19:39:54 ]
どうしても書き込みたいならコテハンかトリップたのむ。

978 名前:デフォルトの名無しさん mailto:sage [2006/09/09(土) 19:49:57 ]
>>976 みたいな馬鹿はおいといて
2chの住民に検証協力してくれというなら
>>975 くらいの準備はしても良いと思う



979 名前:デフォルトの名無しさん mailto:sage [2006/09/09(土) 20:15:39 ]
結果報告なんかをここでやらないならいいよ
正直つまんないのでウンザリしてる

980 名前:デフォルトの名無しさん mailto:sage [2006/09/09(土) 20:27:34 ]
>978

>975 は遠回しに断ってるんじゃないかな。

981 名前:デフォルトの名無しさん mailto:sage [2006/09/09(土) 22:33:50 ]
>>943
根本的なところが馬鹿っぽいのに、
とても流暢に(内容的に脱力な)文章を書ける才能に感嘆する。


982 名前:デフォルトの名無しさん mailto:sage [2006/09/09(土) 22:49:03 ]
>>975
どうせならワームとして世界中のPCにばら撒いて
宿主PC上の実行結果を自分宛てにレポートさせるように
実行させれば良いのでは?


983 名前:デフォルトの名無しさん mailto:sage [2006/09/09(土) 22:56:43 ]
前々スレくらいでvolatile厨を繁殖させた者です。

この話題って、あの時のフラグ変化の検出の話題と凄く似ていると思う。
あの時は単なるフラグで、1ビットでも変化している事を検出できれば
良かったから、不必要にややこしくしそうで触れなかったんだけど。

前の時のポイントは、

1. メモリから読み込んだ値を利用(計算)した結果を書き込むのではなく、
  完全に新規な値をメモリに書き込む。
2. 更新前の古い値を他のプロセッサがキャッシュの関係で読み込んでも、
  伝搬されて更新された値を近いうちに読み込めればよい。

という前提において、

必ずしも同期を取らなくても動作に支障はないが、最適化による
レジスタへの張り付きを防止するためにvolatileは必要となる。

今回も似たようなもので、更新前のメモリの内容に依存しないので、
ワード境界に整列されたワード単位のメモリ転送命令がアトミックに
行われるかどうかを確認するだけで解決できるんじゃないの?

984 名前:983 mailto:sage [2006/09/09(土) 22:57:37 ]
ついでに、OS依存、アーキテクチャ依存だって言う必要もないのでは?
C言語から見たら、スレッドの存在そのものが環境依存なわけだし。

>IA-32 Intel® Architecture Software Developer's Manual,
>Volume 3A: System Programming Guide
>7.1.1 Guaranteed Atomic Operations

これを見ると、
>basic memory operations will always be carried out atomically
なわけで、少なくともワード境界に整列されたワード転送なら
アトミックに行われる事が保証されているように読めるのだが。

985 名前:デフォルトの名無しさん mailto:sage [2006/09/09(土) 23:17:13 ]
次スレ立ってる?

986 名前:デフォルトの名無しさん mailto:sage [2006/09/10(日) 00:10:02 ]
立てるわ

987 名前:デフォルトの名無しさん mailto:sage [2006/09/10(日) 00:20:09 ]
立てた

pc8.2ch.net/test/read.cgi/tech/1157814833/l50

988 名前:デフォルトの名無しさん mailto:sage [2006/09/10(日) 00:29:26 ]
>>983
> という前提において、

そういう前提かどうかは明らかにされていない

>>984
> ついでに、OS依存、アーキテクチャ依存だって言う必要もないのでは?

「世に出回っている大抵のWindowsマシンでおかしくならない線」
というあいまいな線引きしかなされていない

つーかさ、
spec等から確認できることもせずに、いきなり検証コード持ち出して
「ホラ、動いてるから問題ないじゃん」
なんて言われてもさ、そのコード・やり方を信用する人っているのかね。

仮に確認できても、前提を考えれば、いかに狭い範囲でしか使えないかが
すぐに分かると思うんだが、それをしない理由はなんだろうね。

もう少しアタマ使えないかな。



989 名前:デフォルトの名無しさん mailto:sage [2006/09/10(日) 00:36:28 ]
>>988
>spec等から確認できることもせずに、いきなり検証コード持ち出して
>「ホラ、動いてるから問題ないじゃん」
>なんて言われてもさ、そのコード・やり方を信用する人っているのかね。

悲しいけど現実にはかなり沢山いると思う
実際事故は多発してるでしょ?


990 名前:983 mailto:sage [2006/09/10(日) 01:08:03 ]
>>988

>「世に出回っている大抵のWindowsマシンでおかしくならない線」
>というあいまいな線引きしかなされていない

これが微妙な線引きだと言いたいのもわかるけど、
世の中のPC〜WSクラスでSMP/Multi Coreが可能なCPUの
大半はIA-32なアーキテクチャなんじゃないの?

>そういう前提かどうかは明らかにされていない

まず、>>923のコードではaから読み出した結果を利用して
aに再代入しているわけではないので、1.の前提は成り立つ。

で、「0x0000ffffか0xffff0000以外の数字が表示されるか」から、
aの更新が他のプロセッサに即時に伝搬される必要もないし、
どちらかの値になれば良くて、読み出し結果が0xffffffffの
ように混ざり合わなければいいだけなので、2.も成り立つ。

#とりあえず、初期値が延々表示される、、ってのは置いといて…。

少なくとも、今のところはこの考え方がまずい、
って証拠も誰も示していないんだよね。

991 名前:983 mailto:sage [2006/09/10(日) 01:23:24 ]
この辺のところはDCLみたいに覆されることもあるかもしれない。

で、DCLにも気になっているところがあって、

Singletonを保証するためのDCLは危険なのは解るんだけど、
100%のSingletonであることに依存しているわけではなくて、
運悪く初期化時に複数インスタンスが生成されてしまっても
許容できる状況でもDCLは使っちゃいけないのかな?

生成にそれなりに時間かかるからキャッシュ目的でSingletonに
してるけど、複数回生成されて違うオブジェクトを返そうが、
単なるキャッシュだから実害はないっていうような場合とかで。

992 名前:デフォルトの名無しさん mailto:sage [2006/09/10(日) 01:26:06 ]
マルチスレッドを扱い続けて30年の漏れが断言するが、
>>923 のコードでは絶対に「0x0000ffff か 0xffff0000 以外の数字」は表示されない!












これで勘弁してもらえないか?

993 名前:デフォルトの名無しさん mailto:sage [2006/09/10(日) 02:50:37 ]
CPUによる

994 名前:デフォルトの名無しさん mailto:sage [2006/09/10(日) 03:03:58 ]
俺なんかマルチスレッドと暮らし始めて60年だぜ



995 名前:デフォルトの名無しさん mailto:sage [2006/09/10(日) 03:56:28 ]
うめようよ

996 名前:デフォルトの名無しさん mailto:sage [2006/09/10(日) 09:01:19 ]
2chを見続けて10年の俺が断言するが、
>>992の言うことに間違いはない!

997 名前:デフォルトの名無しさん mailto:sage [2006/09/10(日) 09:06:40 ]
>>988
>なんて言われてもさ、そのコード・やり方を信用する人っているのかね。
顔が見えないのをいいことに、著しく礼儀を欠いた発言をする人間も信用できないが

998 名前:デフォルトの名無しさん mailto:sage [2006/09/10(日) 09:16:58 ]
ヒント:2ch



999 名前:デフォルトの名無しさん mailto:sage [2006/09/10(日) 09:57:14 ]
>>997
いるよ。
うちの新人はWebで調べたコードは絶対間違いないって言い張る。
そういえば、去年までいた中国人も同じ事いってたよ。

1000 名前:デフォルトの名無しさん mailto:sage [2006/09/10(日) 10:14:33 ]
pthread_join( pc8.2ch.net/test/read.cgi/tech/1157814833/ , NULL);

1001 名前:1001 [Over 1000 Thread]
このスレッドは1000を超えました。
もう書けないので、新しいスレッドを立ててくださいです。。。






[ 新着レスの取得/表示 (agate) ] / [ 携帯版 ]

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

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