マルチスレッドプログ ..
[2ch|▼Menu]
655:デフォルトの名無しさん
06/07/19 16:21:59
>>637
> accept() 成功後にスレッド作るように書かないと駄目なようですね。

そんなことはない。

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

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

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


657:デフォルトの名無しさん
06/07/19 16:24:17
>>654-655
そうですか…。じゃあ何でだろう?


658:デフォルトの名無しさん
06/07/19 16:26:01
こっちの方がいいかも。
UNIX板 pthread地獄
スレリンク(unix板)
読んでる人はこの板と重複がかなりあるかもだけど。

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

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


660:636
06/07/19 23:13:46
な?


661:デフォルトの名無しさん
06/07/20 01:05:07
うはwww
ボッコボコwww
しかも自分のミスwww

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

663:デフォルトの名無しさん
06/07/20 13:12:28
File Disk Riptor 略して FDR である

664:デフォルトの名無しさん
06/07/20 14:35:46
なんか車の駆動方式っぽい略称だな。

665:627
06/07/20 16:04:12
申し訳ありません。私がバグっておりました。

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

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

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

666:デフォルトの名無しさん
06/07/20 16:25:36
まあせいぜい地雷原を走り抜けてくれ

667:デフォルトの名無しさん
06/07/21 20:41:07
Javaだと複数のスレッドがacceptでブロックしてても動いたと思う。
URLリンク(www.amazon.co.jp) の例の1つにあったと思う。

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

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

669:デフォルトの名無しさん
06/07/21 21:16:04
>>667
> 特にメリットも思いつかないので、

はあ


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


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

URLリンク(www.amazon.com)

URLリンク(www.amazon.com)

672:デフォルトの名無しさん
06/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:デフォルトの名無しさん
06/07/26 17:36:12
>>672
ただのワーカースレッドでええんちゃうかと
マイクロスレッドのようなものを考えてるなら、ファイバでも使えばいい


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

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

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


675:デフォルトの名無しさん
06/07/26 18:07:51
みなさん、レス有難うございます。

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

こんな感じでしょうか?

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

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

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



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

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

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

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

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

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


681:678
06/07/27 21:49:17
>>679
>>680
ありがとうございます。

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

とここまで書いて
URLリンク(www-06.ibm.com)
に似たような事が書いてありました
ABA問題というらしいですが

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

682:デフォルトの名無しさん
06/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:デフォルトの名無しさん
06/07/28 00:03:12
終わった話題についてなにを得意げに語ってるんだろう…。

684:デフォルトの名無しさん
06/07/28 00:20:12
>>682
それC言語的にやばいやん。

685:デフォルトの名無しさん
06/07/28 00:31:47
つまり、「ほんと、バカしかいないんだね」ってことか。

686:デフォルトの名無しさん
06/07/28 00:43:19
やーい
ばかー

687:デフォルトの名無しさん
06/07/28 07:26:02
volatileですべて解決!

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

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

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

691:デフォルトの名無しさん
06/07/29 15:08:13
volatileですべて解決するという忠告がみえないのか?

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

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

よろしくお願いします。

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

695:デフォルトの名無しさん
06/07/29 19:36:20
>>693
ExitProcessで自殺すればおk

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

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

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

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

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

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

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

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

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

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

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


704:デフォルトの名無しさん
06/07/29 21:53:15
縞模様の筋ですか?

705:デフォルトの名無しさん
06/07/29 21:55:30
筋肉のことですか?

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

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


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

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

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

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

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

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

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

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

712:デフォルトの名無しさん
06/07/31 13:41:09
問題ないw


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

714:デフォルトの名無しさん
06/08/01 06:53:40
volatileですべて解決!!!

715:デフォルトの名無しさん
06/08/01 10:44:44
この話では無理w

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

717:デフォルトの名無しさん
06/08/01 11:51:13
preemption はいつでも起こりうるでしょ

718:716
06/08/01 12:39:23
起こらないでしょ


719:デフォルトの名無しさん
06/08/01 12:43:33
>>716
何を根拠に言ってんの?

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

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

722:デフォルトの名無しさん
06/08/01 13:23:44
>>716はWin3.1ユーザー

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

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

725:716
06/08/01 14:35:50
反省^^


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

727:デフォルトの名無しさん
06/08/02 08:14:08
まあ、あれだ。がんがりたまえ(笑)

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



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

730:デフォルトの名無しさん
06/08/02 14:34:13
むてふ

731:デフォルトの名無しさん
06/08/02 14:47:18
ティキストエデタ

732:デフォルトの名無しさん
06/08/02 15:05:17
www

733:デフォルトの名無しさん
06/08/02 23:11:34
ヴォラタィル

734:デフォルトの名無しさん
06/08/03 08:56:51
コンピゥタァ


735:デフォルトの名無しさん
06/08/03 12:30:55
モシ NO=735 ナラバ トベ >>1000

736:デフォルトの名無しさん
06/08/03 14:38:59
static bool g;

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

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



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


738:デフォルトの名無しさん
06/08/03 14:56:56
あ、俺も書き間違えた。すま。

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

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

740:デフォルトの名無しさん
06/08/03 18:52:39
w

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

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


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

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

744:デフォルトの名無しさん
06/08/03 22:31:23
アセンブラレベルで考えるんだ

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

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

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

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

747:デフォルトの名無しさん
06/08/03 23:16:40
えらそうに講釈たれてても

> 同時(atomit)

この一言で台無しだな。

748:デフォルトの名無しさん
06/08/03 23:25:35
>>747
お前いらないから

749:デフォルトの名無しさん
06/08/03 23:36:58
必死な子がいるなぁ。

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

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

751:デフォルトの名無しさん
06/08/03 23:58:41
なに一生懸命説明してるの?

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

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

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

752:デフォルトの名無しさん
06/08/04 00:03:37
>>751
もう消えてね(^^)

753:デフォルトの名無しさん
06/08/04 00:18:24
>>751
ずいぶん必死ですね。

754:デフォルトの名無しさん
06/08/04 00:20:13
最近なりを潜めてる、某キティと文体が似てる・・・

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

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

757:デフォルトの名無しさん
06/08/04 01:23:06
原子力って感じかと思ってた

758:デフォルトの名無しさん
06/08/04 03:38:13
分割不可能な最小単位つうことですょ

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

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

761:デフォルトの名無しさん
06/08/04 07:05:02
で、何が言いたいんだ?

762:デフォルトの名無しさん
06/08/04 07:11:33
atomic bomb 分割不可能な爆弾

763:デフォルトの名無しさん
06/08/04 07:12:41
割ったら被爆しちゃうからね

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

765:デフォルトの名無しさん
06/08/04 07:18:59
被爆と被曝

766:デフォルトの名無しさん
06/08/04 07:55:02
>>764
何のために?

767:デフォルトの名無しさん
06/08/04 07:57:34
>>760
なに一生懸命説明してるの?

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

768:デフォルトの名無しさん
06/08/04 08:37:02
「同時」って書いちゃうヤツ以外はね。

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

770:デフォルトの名無しさん
06/08/04 09:45:01
>>768
どこが変なのか未だにわからんのだが?

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

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

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

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

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


775:デフォルトの名無しさん
06/08/04 11:03:28
意味が分からねえ・・・

776:デフォルトの名無しさん
06/08/04 11:10:09
>>770
恥の上塗り


777:デフォルトの名無しさん
06/08/04 12:38:57
ガキ共の言葉遊びここまで

778:デフォルトの名無しさん
06/08/04 12:49:23
じゃあ今から大人の言葉遊びか・・・エロス

779:736
06/08/04 13:14:37
if (g = g ? false : true)

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

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

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

782:デフォルトの名無しさん
06/08/04 13:25:55
陽子と電子に分割できるんだっけ?

783:デフォルトの名無しさん
06/08/04 13:27:46
あと中間子

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

785:デフォルトの名無しさん
06/08/04 14:05:25
>>779
そもそもどう排他したいの?

786:デフォルトの名無しさん
06/08/04 14:21:49
mkdir() は atomic らしい

787:779
06/08/04 14:38:19
リスト処理でつなげるときに排他したいけど
WinAPI使うしかないみたいですね


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

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

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

URLリンク(www.din.or.jp)


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

790:デフォルトの名無しさん
06/08/04 15:28:11
mutex使わないのはなぜですか

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

792:デフォルトの名無しさん
06/08/04 18:32:01
>>787
それならCriticalSectionで十分

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

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

kwsk

795:デフォルトの名無しさん
06/08/04 22:42:15
それはリフレッシュのことかね。

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

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


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

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

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


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

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

正解を教えてくれ >>755

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

どこに? 君の脳内?

ちょっと頭冷やせよ。

800:デフォルトの名無しさん
06/08/04 23:45:22
そんなの基礎知識でしょ

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

802:デフォルトの名無しさん
06/08/04 23:48:16
で、そういう人には揶揄や皮肉は通用しませんね。

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

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

805:デフォルトの名無しさん
06/08/05 00:31:32
破壊読み出しなのは、コアメモリもそう

806:デフォルトの名無しさん
06/08/05 01:45:45
>>803

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

807:デフォルトの名無しさん
06/08/05 02:10:07
( ゚д゚)ポカーン

808:デフォルトの名無しさん
06/08/05 02:18:37
急に暑くなったからな。

そっとしておいてやれ。

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

810:デフォルトの名無しさん
06/08/05 02:31:33
>>746

811:デフォルトの名無しさん
06/08/05 09:44:05
volatile最高!!!

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

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

812:デフォルトの名無しさん
06/08/05 09:54:47
本気で言ってんの?

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

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

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

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

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

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

813:デフォルトの名無しさん
06/08/05 10:14:01
>>811

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


814:デフォルトの名無しさん
06/08/05 10:18:41
>>812
この人なんかずれてる…

815:デフォルトの名無しさん
06/08/05 10:30:47
どの辺がすれてるのかkwsk

816:デフォルトの名無しさん
06/08/05 10:33:19
字下げが

817:デフォルトの名無しさん
06/08/05 12:49:28
オチがよろしいようで

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

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

819:デフォルトの名無しさん
06/08/05 15:16:29
やさしすぎだと思う。

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

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

821:デフォルトの名無しさん
06/08/05 19:31:21
ここ読め。
1.8 Program execution [intro.execution]

822:デフォルトの名無しさん
06/08/05 21:02:19
>820でFA?

823:デフォルトの名無しさん
06/08/05 22:17:01
>>820
volatile 参照の削除はできないだろ。

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

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

826:デフォルトの名無しさん
06/08/05 23:07:40
>>825
yes

827:デフォルトの名無しさん
06/08/06 10:53:58
sequence pointウンヌンが書いてないから、

>820でFA?

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

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

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

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

830:デフォルトの名無しさん
06/08/06 11:23:23
>>828
「volatileでokかngか」

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

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

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

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

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

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

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

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

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

838:デフォルトの名無しさん
06/08/06 17:23:34
はいはい
続きはここでやれな
スレリンク(tech板)

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

840:デフォルトの名無しさん
06/08/09 00:38:57
シャンプー

841:デフォルトの名無しさん
06/08/09 00:51:16
いや、メリットは同期してると思うが

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

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

843:デフォルトの名無しさん
06/08/09 01:08:25
リンスも利いてるし?

844:デフォルトの名無しさん
06/08/09 07:28:17
ZPt

845:デフォルトの名無しさん
06/08/09 10:19:08
ちゃん・りん・しゃん、という選択肢

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

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


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

849:デフォルトの名無しさん
06/08/09 12:49:31
>>846
馬鹿?

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

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


852:デフォルトの名無しさん
06/08/09 13:24:35
スレッド数の上限を制御したいときも使うわね

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

853:デフォルトの名無しさん
06/08/09 15:55:01
大したテクニックじゃない気がするんだが…。


854:デフォルトの名無しさん
06/08/09 19:20:00
大したテクニックじゃないといけないのか?

855:デフォルトの名無しさん
06/08/09 20:09:24
>>850
そんなの実装に依存。
議論するだけ無駄だなw

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

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

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

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

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

859:デフォルトの名無しさん
06/08/10 00:57:44
個人情報の流出

860:デフォルトの名無しさん
06/08/10 07:40:47
仁義無きエディタ

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

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

863:デフォルトの名無しさん
06/08/10 10:35:09
しながら同時にテキスト入力できるのか!

864:デフォルトの名無しさん
06/08/10 10:39:46
>>858
画面出力とか。

865:デフォルトの名無しさん
06/08/11 22:57:19
どこまでがマジレスなのか…

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

867:デフォルトの名無しさん
06/08/16 01:06:17
再起動

868:デフォルトの名無しさん
06/08/16 08:42:10
海に行く

869:デフォルトの名無しさん
06/08/16 18:56:59
オレは泳がないから

870:デフォルトの名無しさん
06/08/18 00:26:11
眺めてるだけでも心和むじゃまいか

871:デフォルトの名無しさん
06/08/18 07:41:37
潜りてー
あの不要な音が聞こえない感覚が良いんじゃー

872:デフォルトの名無しさん
06/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:デフォルトの名無しさん
06/08/18 19:28:16
大阪には株式会社モータープールがあり、東京には株式会社月極がある。


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

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

877:デフォルトの名無しさん
06/08/26 10:26:12
>>874
あんたの心配は正しい。

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

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

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

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

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

878:デフォルトの名無しさん
06/08/26 19:08:33
volatileですべて解決します。

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

これ最強。


879:デフォルトの名無しさん
06/08/26 19:17:49
>>878
 >>877
 >・領域を静的に確保する。

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

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

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

882:デフォルトの名無しさん
06/08/26 21:28:54
すごいな
全く意味のわからん質問だ

883:デフォルトの名無しさん
06/08/27 16:59:50
マルチスレッドなんか使わなければ解決

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


885:デフォルトの名無しさん
06/08/27 21:05:30
アホ発見 >>884

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

886:デフォルトの名無しさん
06/08/27 21:34:42
>>884
それは874に宛てるべき内容だ。

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

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

kwsk

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

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

889:888
06/08/28 00:23:33
なんか違うな
忘れてくれ

890:デフォルトの名無しさん
06/08/28 00:41:46
しったかぶりっこ

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

892:デフォルトの名無しさん
06/08/28 01:50:45
ぶるぶるぶりっこ

893:デフォルトの名無しさん
06/08/28 02:58:49
一体何の話をしてるのだろう?

894:デフォルトの名無しさん
06/08/28 05:08:03
ぶりっ子ロックンロール / 紅麗威甦

895:デフォルトの名無しさん
06/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();
}



次ページ
最新レス表示
スレッドの検索
類似スレ一覧
話題のニュース
おまかせリスト
▼オプションを表示
暇つぶし2ch

5353日前に更新/278 KB
担当:undef