5ちゃんねる ★スマホ版★ ■掲示板に戻る■ 全部 1- 最新50  

■ このスレッドは過去ログ倉庫に格納されています

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

1 :デフォルトの名無しさん:2008/07/05(土) 19:26:16
マルチスレッドプログラミングについて語るスレ

■前スレ
マルチスレッドプログラミング相談室 その6
ttp://pc11.2ch.net/test/read.cgi/tech/1187008532/

■過去スレ
その1 ttp://pc3.2ch.net/tech/kako/997/997345868.html
その2 ttp://pc5.2ch.net/test/read.cgi/tech/1037636153/
その3 ttp://pc8.2ch.net/test/read.cgi/tech/1098268137/
その4 ttp://pc8.2ch.net/test/read.cgi/tech/1130984585/
その5 ttp://pc11.2ch.net/test/read.cgi/tech/1157814833/

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

【OS】

【言語】

【実行環境】

【その他突起する事項】

2 :デフォルトの名無しさん:2008/07/05(土) 19:31:40
■関連スレ・関連性の高いスレ

【マルチコア】並列化について語る【使いこなせ】
ttp://pc11.2ch.net/test/read.cgi/tech/1137540671/

pthread地獄 part 2
ttp://pc11.2ch.net/test/read.cgi/unix/1166620307/

ネットワークプログラミング相談室 Port21
ttp://pc11.2ch.net/test/read.cgi/tech/1204287577/

3 :デフォルトの名無しさん:2008/07/05(土) 19:32:51
>>1-2



4 :デフォルトの名無しさん:2008/07/07(月) 12:40:51
これは関連スレじゃ無し?

OpenMPプログラミング
http://pc11.2ch.net/test/read.cgi/tech/1102483474/


5 :デフォルトの名無しさん:2008/07/07(月) 12:50:44
じゃこれも

Message Passing Interface (MPI) 統合スレ
http://pc11.2ch.net/test/read.cgi/tech/1099819556/

6 :デフォルトの名無しさん:2008/07/09(水) 20:28:14
boost::threadを使っていて質問があります。
スレッドオブジェクトをスレッド処理完了後に自動消去したいのですが、
以下のやり方だとまずい気がします。定石みたいなものはないでしょうか?

struct ThreadManager {
 boost::shared_ptr<Thread> th_; // 管理するスレッド
 bool thread_is_running(void) const { return th_!=0; }
 void start_thread(void) { if (thread_is_running()) return; th_.reset(new Thread(this)); boost::thread(boost::ref(*th_.get())); }
 // ※スレッド処理が終わったらth_を空にしたい
 void delete_thread(void) { thread.reset(); }
};

struct Thread {
 ThreadManager* p_;
 Thread(ThreadManager* p) : p_(p) {}
 void operator()(void) { /* ... スレッド処理 ... */ p_->delete_thread(); }
 // スレッド処理終了後、ThreadManagerを通じて自分を消去
};


7 :デフォルトの名無しさん:2008/07/09(水) 21:11:24
boost::shared_ptr<Thread> th(new Thread);
boost::thread(boost::bind(&Thread::operator(), th));

8 :6:2008/07/09(水) 22:44:08
7が動くのは理解したのですが、ありがたみがいまいちわかりません。
この場合thはスレッド処理が完了したこと(つまりth.reset()を呼ぶタイミング)を
どうやって知るのでしょうか。

9 :デフォルトの名無しさん:2008/07/09(水) 23:01:53
いや…、どうやっても何もThreadのデストラクタが呼ばれるだろ。
ていうか何がしたいのさ?
スレッド作ってあとは関知せずという無責任なマネをしたいのか、
メインスレッドと同期して何かをしたいのか。

10 :6:2008/07/09(水) 23:11:20
処理の種類に応じてThreadA、ThreadB、...(単一のThreadクラスを継承)を用意しています。
で、本体はThread*を1つ管理していて(p_とします)、
処理が必要になった時点でp_.reset(new ThreadA) のようにします。
その際に他のスレッドが処理中かどうかをp_!=0のように判定したいなと。




11 :6:2008/07/09(水) 23:14:32
ありゃ、なんか>>10>>6の単なる繰り返しですね…。
何をしたいかというと、いくつかのマルチスレッド処理を
排他でとっかえひっかえ行いたいという感じでしょうか。

12 :デフォルトの名無しさん:2008/07/09(水) 23:23:24
まあ、普通に thread pool 使えばいいんじゃね。

13 :13:2008/07/09(水) 23:36:47
教えてください。

A.cというファイルにグローバル定義で定義した
volatile変数をB.cというファイルで参照したい場合、

volatile extern int hoge;

とかでいいのでしょうか?


14 :デフォルトの名無しさん:2008/07/09(水) 23:44:57
>>11
実行中のワーカスレッドが存在する場合にどういう選択肢があるのか
(終了を待ってから新しいスレッドを起動する/途中でも終わらせて新しいスレッドを起動する etc..)
によっても実装の仕方は変わってくると思うんだけど、どうだろう。

15 :6:2008/07/10(木) 04:26:36
>>14
今のところ、実行中のワーカスレッドが存在する場合には、
「別のスレッドを実行中だからスレッド終了まで待ってね」
と表示して何もせずにreturnという仕様です。
>>6の方法で動いてたのですが、たまたま運が良かっただけですね)


16 :デフォルトの名無しさん:2008/07/10(木) 07:19:10
>>13
B.cでその前にstatic volatile int hoge;と書いてなければOK

>>7
これって、スレッド終了より早くthがスコープ抜けても問題ないの?
>>6がやりたいことはMFCのCWinThreadのbAutoDeleteでしょ。

17 :デフォルトの名無しさん:2008/07/10(木) 23:17:00
>>16
shared_ptrでラップされてて、それを保持した
functorがスレッド終了時に破棄される。
そのタイミングでthの指すインスタンスも破棄される・・・・多分。


18 :デフォルトの名無しさん:2008/07/10(木) 23:17:19
MFCは平気でdelete thisしてる。
ThreadManagerまで作ったのなら、()を直接呼び出すのでなくて
()を呼び出した後でメモリ解放するラッパーをサブスレッドで実行すればいい。
ついでにshared_ptrの操作前後で排他制御が必要。

19 :デフォルトの名無しさん:2008/07/12(土) 00:29:11
タイムアウト監視中にシステム時刻が変更される可能性について
意識してない人が大杉な気がする。そういう脆弱なコードをいっぱい見てきた。
現実的な例として、ホストとの接続時に時刻の同期が要求される某FA分野プロトコルを
使ったシステムで、同時にハードとの通信のタイムアウトを監視してたら
とても愉快なことが起こり得るわけだ。
つまり、pthread_cond_timedwaitの仕様は困るってこと。
非標準の相対時間によるwaitをサポートしないPthread環境で
この問題を解決する方法が分からない、というかできないでFA?


20 :デフォルトの名無しさん:2008/07/12(土) 01:17:00
放置!

21 :デフォルトの名無しさん:2008/07/12(土) 03:25:52
ホスト時刻と端末時刻の差を管理すればいいだけじゃない

22 :デフォルトの名無しさん:2008/07/12(土) 03:43:50
・時刻同期してから絶対時間に依存する処理を開始する
・時刻同期を徐々に(ntpd的に)行う

23 :デフォルトの名無しさん:2008/07/12(土) 04:31:24
>>21>>22
もしかしたら、俺がどうしてもUnixでシステムを動かす必要に迫られてると思って、
一生懸命解決策を考えてくれたんだろうか?だったらごめん。
Windows使ってます。

俺が知りたいのは、特定の仕様のシステムを実現する方法じゃなくて、
他のプログラムが何していようが、
ユーザが好き勝手に時刻を変更しようが、
現在からN秒以内に条件が成立しなければ、アウトという監視は本当にできないのかってこと。
Pthread標準の枠内で。
時刻をいじってるプログラムと密に連携したり同期とれるとか、
そんなこと当てにできないし、したくもない。


24 :デフォルトの名無しさん:2008/07/12(土) 05:43:29
windowsでpthreadなの?よくわからんがTickCountじゃだめなのかな。

25 :デフォルトの名無しさん:2008/07/12(土) 05:51:01
普通はハートビートを刻む液晶系のクロックと、カレンダ時計があって、
sleepだのwaitのタイムアウトの監視は前者、
カレンダ時計はcronのようなもっとスパンの長いスケジューラで使っていると思ったのだが、
pthread_cond_timedwaitはカレンダ時計を使ってるのかな。

26 :デフォルトの名無しさん:2008/07/12(土) 06:50:42
pthread_cond_timedwaitは困ったことに絶対時間指定なんだ。
利用者にも実装者にも不評で
pthread以外の同種のAPIで待機時間でなく絶対時間を
使っているのは見たことがない。

27 :デフォルトの名無しさん:2008/07/12(土) 09:49:47
まあAPI仕様に無い以上無理なんだろう。勉強になりますた。
苦しい対処だが1秒タイムアウトをN回繰り返せば誤差1秒でタイムアウトできる、かな。
あとWindowsならスレッド生成だけpthread使って、同期はWin32 APIでするとか

28 :デフォルトの名無しさん:2008/07/12(土) 10:48:39
情報小出し君にはレスしても無駄だと分かった


29 :デフォルトの名無しさん:2008/07/12(土) 10:57:06
>>27
Windows で pthread ?

なんでそんなことしたいのかを書かないと、単なるバカにしか見えないよ。

あと、pthread_cond_timedwait がダメダメなら、setitimer でシグナル
もらうとかすればいいんじゃないのか?

30 :デフォルトの名無しさん:2008/07/12(土) 11:09:52
ttp://sourceware.org/pthreads-win32/ のソースを確認したのだが、
絶対時間をすぐさま待機時間(ミリ秒)に変換。
最終的にWaitForMultiObjectのtimeout指定で使ってた。


31 :デフォルトの名無しさん:2008/07/12(土) 11:12:15
Win32と言ったりpthreadと言ったり、答えようがない。
Win32には延長付のタイムアウトのAPIや時刻に影響しない経過時間を計測できるAPIがあるのに残念だったな。


32 :27:2008/07/12(土) 11:18:17
>>29
俺は>>27だが、>>19=>>23とは別人だ。
もともとの>>19がWindowsでpthreadのようだけど、企業でそういう指定があるから
だと推測した。それで「使ってるフリして回避する方法」として、同期だけWin32したら?
と言ってみた。

33 :19:2008/07/12(土) 13:00:21
>>19=>>23だが、なんか混乱させてるな。
俺が現実に直面してる仕事なんかに関係なく、
このpthread_timedwaitの仕様どうなの?って話がしたかっただけ。
俺でも分かるような欠陥が本当にメジャーな標準規格にあるのか
疑問だったので、もしかしたら、今のPthreadの枠内で簡単に解決する方法があるのかと思った。
それも聞きたかったことの一つ。
Pthread本を見ると、絶対時刻が使われていることのメリットしか書かれてないけど、
俺としては、相対時刻でタイムアウト監視できるAPIの方がよほど必須のように思えたので。


34 :デフォルトの名無しさん:2008/07/12(土) 14:15:09
tasksetの使い方教えてください。オプションとか…。
 スレッド1→コア1
     …
 スレッド4→コア4
みたいに割り当てたいのですが、
tasksetじゃできないですかね…?
ちなみにlinuxでopenmpでやろうかと思っています

35 :デフォルトの名無しさん:2008/07/12(土) 14:21:58
で、このスレとしてはPthreadではできないという結論になると。
>>26 C++ boostも絶対時間だったような。

36 :デフォルトの名無しさん:2008/07/12(土) 14:36:44
>>34
そうしたい理由を先に言ったほうがいいよ
まさか
「割り当てられないとしたらその仕様どうなの?って話がしたかっただけ」
じゃないよな

37 :デフォルトの名無しさん:2008/07/12(土) 14:51:09
>>35
最新版ではabstimeとreltime向けに別々の時間クラスが定義されて
timedwaitはオーバーロードされてる。
例によって、実装はテキトーに変換してるだけなので、
ネイティブに近い方のオーバーロードだけは信頼できるってかんじかな。

38 :デフォルトの名無しさん:2008/07/12(土) 15:29:11
>>37
信頼できるかどうかはOS次第だと思う。
どんなラッパー仕様だろうと最終的にはOSのAPIを呼び出すことになるので
>>30は当然のこと。もしPthreadのプログラムインターフェースしか提供されて
いないOSなら信頼はできない。

39 :デフォルトの名無しさん:2008/07/13(日) 02:16:06
http://pc11.2ch.net/test/read.cgi/unix/1166620307/69

笑った

40 :デフォルトの名無しさん:2008/07/13(日) 03:48:14
>>19はPthreadの絶対時間指定によるデメリットを仕様欠陥と(あちこちで)指摘してるだけだろ。
一貫してるからいいんじゃね?
例がアレなので相手にされてないようだけど「システム時刻を修正されるとまずい」ってのは
事実で、時間が巻き戻らない前提ってのは無茶苦茶だ。SIベンダがBtoBで構築するシステムなら
ともかくフリーソフト作れねーぞ。

しかも理由が「絶対-相対の変換の足し算中にプリエンプションが発生すると待ち時間がずれる
から」ってのは納得できねー。タイムアウト時間にごく僅かな誤差が出ることに問題あるとは
思えないし、責任をアプリに押しつけただけなのは基盤として問題だろ

41 :デフォルトの名無しさん:2008/07/13(日) 05:49:24
>>19>>23の書き込みが余計だったな、誤解を招いた。
続けるなら>>39のUNIX板のがいいじゃないか。


42 :デフォルトの名無しさん:2008/07/13(日) 15:02:30
>>40
え〜っと、本人乙でいいかな。

43 :デフォルトの名無しさん:2008/07/13(日) 23:27:07
マルチスレッド対応にしたら
デュアルコアのCPUを両方とも使って処理してくれるの?

44 :デフォルトの名無しさん:2008/07/13(日) 23:33:38
>>43
普通はOSまかせ。
OSはコアをまんべんなく使おうとするから普通は両方使ってくれるが、
他のプログラムが1つのコアをめいいっぱい使ってたら、
同じコアに振られることもある。

45 :デフォルトの名無しさん:2008/07/15(火) 08:20:00
サンクス

46 :デフォルトの名無しさん:2008/07/17(木) 01:20:09
自演乙

47 :デフォルトの名無しさん:2008/07/17(木) 02:11:04
自演乙厨w

48 :デフォルトの名無しさん:2008/07/18(金) 00:32:11
void f()
{
static struct Hoge hoge;

pthread_mutex_lock();
///hogeにアクセス
pthread_mutex_unlock();
}

こんな感じのコードあってstaticだから安全だって譲らない
K主任って糞がいます助けてください

49 :デフォルトの名無しさん:2008/07/18(金) 01:00:04
Hogeがコンストラクタを持つの?

50 :デフォルトの名無しさん:2008/07/18(金) 01:01:55
>>49
C99ですC++じゃないです

51 :デフォルトの名無しさん:2008/07/18(金) 01:11:21
K主任も災難だな

52 :デフォルトの名無しさん:2008/07/18(金) 01:17:01
>>48
どういう危険があると思うの?


53 :デフォルトの名無しさん:2008/07/18(金) 02:50:08
>>48
少なくともそこで示されている記述だけじゃ
問題のあるソースだとは思えん。

pthread_mutex_lock()とかの引数に渡されているmutexが
非staticなauto変数とかだったらダメだけど。

54 :デフォルトの名無しさん:2008/07/18(金) 14:39:31
hogeのアドレスを外部に漏らして、そっちはmutexなしでアクセスとか?

55 :デフォルトの名無しさん:2008/07/19(土) 17:07:42
安全って理由が staticだから でmutexはあってもなくても関係ないって
K主任が主張してあるのであれば、これはもうどうしようもない

56 :デフォルトの名無しさん:2008/07/19(土) 17:19:44
ワロタ

57 :デフォルトの名無しさん:2008/07/19(土) 18:39:06
つまりこういうこと?

>>48って糞が粘着しています助けてください  K主任



58 :デフォルトの名無しさん:2008/07/19(土) 20:42:06
>>48
どんな危険があると考えてるのな?
hogeのポインタを外に出さない限りmutexはいらないと思うけど。

59 :デフォルトの名無しさん:2008/07/19(土) 21:04:23
>>58
fが複数スレッドから呼ばれるとしたら、hogeをどうするのかによるね。

60 :デフォルトの名無しさん:2008/07/19(土) 21:11:22
>>59
複数スレッドで呼ぶとどうなるのでつか?

61 :デフォルトの名無しさん:2008/07/19(土) 22:46:35
K主任が見てるようなので退散します・・・

62 :デフォルトの名無しさん:2008/07/20(日) 02:19:01
strtokとstrtok_rの違いを考えろ

63 :デフォルトの名無しさん:2008/07/20(日) 03:51:23
ネタを振った責任として>>48は、何が問題があると思うのかくらいは
説明して欲しいな。

64 :デフォルトの名無しさん:2008/07/20(日) 08:50:23
>>63
K主任の糞っぷりです

65 :デフォルトの名無しさん:2008/07/20(日) 16:35:37
>>60
hoge がstaticだから、hogeのコンストラクタが(あれば)起動時
一度だけ動くのみ。
だから排他部分の外で宣言されていても安全、ってことだろう。

とはいえstaticじゃ無かったとしても何か危険があるかというと
よくわからんから、staticだから安全ってのはなんか変な主張
という気がしなくもないな。

66 :デフォルトの名無しさん:2008/07/20(日) 16:54:53
アドレスを外部に漏らしてなければ、この関数からしか
アクセスできない。そこに排他がちゃんとかかってるか
ら大丈夫だろ? って言うことだと思うが。

67 :デフォルトの名無しさん:2008/07/20(日) 17:24:19
C99って言ってるから(>>50)コンストラクタはないんだが、
仮にc++だとすると

>>65
>hoge がstaticだから、hogeのコンストラクタが(あれば)起動時
>一度だけ動くのみ。

違うぞ。
static struct Hoge hoge; の行に到達したときに、
一度だけ実行される。
その「一度だけ」のフラグが排他されていないことがあるだろう、
というのが起こりうる問題。

68 :デフォルトの名無しさん:2008/07/20(日) 17:59:36
仮にC++だとするとこうするべきってことですか?
pthread_mutex_lock(); 
static struct Hoge hoge; 
///hogeにアクセス 
pthread_mutex_unlock(); 


69 :デフォルトの名無しさん:2008/07/20(日) 18:08:21
前スレ850くらいからその話題が出てるわけで

70 :デフォルトの名無しさん:2008/07/20(日) 19:39:41
DCLでいいよ。

71 :デフォルトの名無しさん:2008/07/20(日) 22:49:34
そこで-fthreadsafe-statics

72 :デフォルトの名無しさん:2008/07/20(日) 23:29:57
そんな実装依存じゃK主任に笑われるぞ

73 :デフォルトの名無しさん:2008/07/29(火) 08:24:43
ハードのことはよく分からないのですが、同じメモリアドレスに複数のコアが同時アクセスすると
なにか問題が起こることはあるのでしょうか?

例えば整数型のグローバル変数aを作り、
スレッド1ではそれを読みこみ加算します。スレッド2ではそれを読み込み減算します。
シングルコアでは物理的に、本当の意味での同時アクセスはありえないので
意図した結果が得られないとしても、ハード的に不具合はないですよね。
仮にスレッド1ではreadのみ、スレッド2ではwriteのみだと何の問題もないはずです。

これがマルチコア環境だと、スレッド1がread, スレッド2がwriteのみだとしても
同メモリアドレスに各コアが本当の意味で同時アクセスしますよね。
こういうことはやってはいけないのでしょうか?

74 :デフォルトの名無しさん:2008/07/29(火) 08:44:31
いや、同時アクセスしてもハード的な問題は起きない
writeの結果がreadに反映されるかされないかの問題でしかない

75 :デフォルトの名無しさん:2008/07/29(火) 11:26:02
>>73
それが同じCPU内の別のコアなら、キャッシュ管理かどっかで調停するから問題ない。
それが違うCPUのコアなら、メモリ管理かどっかで調停(ry

76 :デフォルトの名無しさん:2008/07/29(火) 11:35:00
コア毎のキャッシュにヒットしなかったと仮定すると、
最終的に、競合するバスアクセスが発生するわけだが、
その時にはバスのアービタが調停する。


77 :デフォルトの名無しさん:2008/07/29(火) 16:34:22
>>74-76
ありがとうございます。
調停(アービトレーション?)というのは調べても詳しくは分からなかったのですが、
同時アクセスするような状況で排他処理をしてくれるということでしょうか

78 :デフォルトの名無しさん:2008/07/29(火) 16:38:24
ハード的な話なのでソフト的な排他処理とはちょっと違う希ガス。

79 :デフォルトの名無しさん:2008/07/31(木) 02:06:51
ハード屋の無知はおいておくとして、信用するなよ。

マルチコアとシングルコアの違いは、スケジューラを動かす数が
違うのが一番大きい。あるスレッド(プロセス)は、基本的に1つの
CPU上で動作する。

当然、複数のスレッド(プロセス)間の排他は必要だが、アプリ上
はたいして変わらない。マルチコアでは、アトミックな操作のための
バスを占有するような命令が追加されているだけ。

80 :デフォルトの名無しさん:2008/08/01(金) 12:45:08
>マルチコアとシングルコアの違いは、スケジューラを動かす数が 違うのが一番大きい。
誰もそんな話してないしw
>あるスレッド(プロセス)は、基本的に1つの CPU上で動作する。
間違ってるし

ロードバランスとか考え出すと頭が痛くなるが,まぁ
Read-Write-lock みたいなことをやってると思っとけば

81 :デフォルトの名無しさん:2008/08/02(土) 14:33:08
基本的にって言ってるから何でもあり。

82 :デフォルトの名無しさん:2008/08/02(土) 18:46:05
て言うかある一瞬を言ってるのか、スレッドの一生を言ってるのかわからんから
間違ってるか判断できない。

83 :デフォルトの名無しさん:2008/08/03(日) 00:19:01
突っ込み所が違うだろ。
>>73に対して>>74>>76が問題ないって言ってるのにそれを否定してるんだぞ。
メモリの同時アクセスは複数プロセスでも起こるので、すべてのメモリアクセスは
明示的にバスの排他命令を使用する必要があるな。

84 :デフォルトの名無しさん:2008/08/03(日) 00:39:01
>77はこれでも読んでみれ
ttp://ja.wikipedia.org/wiki/%E3%82%AD%E3%83%A3%E3%83%83%E3%82%B7%E3%83%A5%E3%83%A1%E3%83%A2%E3%83%AA

85 :デフォルトの名無しさん:2008/08/03(日) 00:49:09
>>79 の書き込みは、肝心なところがちゃんと書いてないから
正しいとか間違ってるとか言うことはできない。

まあ、>83 の書き込みも似たようなものだが。

86 :デフォルトの名無しさん:2008/08/24(日) 23:25:42
RT-Linuxでマルチスレッドで組んでいます。
スケジューリングポリシーはSCHED_FIFOです。

pthread_condを使った排他を考えているのですが、
pthrad_cond_wait()を複数スレッドで呼び出した後に
pthrad_cond_broadcast()を呼び出した時の動き出すスレッドの
順番がスレッドの優先度順になっていません。
(ちなみにsunのページにはブロック解除の順番は不定と書いてありました。)

そもそもやりたい事が
ttp://www.hanecci.com/pukiwiki/index.php?Programming%2FMultiThreading
の「リードライトロック」のような事なのですが、
優先度順に動き出させるようにするにはどうしたらいいですか?

よろしくおねがいします。

87 :デフォルトの名無しさん:2008/08/24(日) 23:59:16
写生してえ。

88 :デフォルトの名無しさん:2008/08/25(月) 01:57:04
だから、スケジューラの実装依存になるようなプログラムを組むなと
なんど言ったらわかるのだ・・・。マイナーバージョンが変わっても、
挙動かわるぞ。

89 :デフォルトの名無しさん:2008/08/25(月) 02:19:03
何のためのRT-Linux


90 :デフォルトの名無しさん:2008/08/25(月) 21:28:31
>>86
pthread_cond_waitに入るときに、クリティカルセクション内で
現在待ちに入っているスレッドの優先度をメモっておいて、
pthread_cond_broadcastで起きたときに、クリティカルセクション内で
自分より高い優先度のスレッドが待ちに入っているなら、
何もせずに再びpthread_cond_waitに入る、じゃだめなのかな。

必ずその優先度の高いスレッドも起こされるはず・・・だと思う。
やばいタイミングとかあるか・・・な?

91 :デフォルトの名無しさん:2008/08/25(月) 21:48:00
CPU稼働率落ちそうだな。

92 :86:2008/08/25(月) 22:44:47
解決した。
pthread_condとかつかわずに セマフォで普通に組めるのね。

ありがと。

>>87
うん

>>88、89
そこでヒントがほしかった><

>>90
簡単な仕組みにしたいっすね。

>>91
ですね

93 :デフォルトの名無しさん:2008/08/25(月) 23:33:52
簡単にCreateThreadできるようになるクラスとかないかな

94 :デフォルトの名無しさん:2008/08/25(月) 23:43:39
boost::threadとか?

95 :デフォルトの名無しさん:2008/09/09(火) 15:11:50
データ処理部分とHDDから読み込み&書き込み処理部分ってスレッド分けた方が効率上がると思うんですが、
HDDのIO部分自体は分けないで一つのスレッドでやった方が効率いいですよね?
2つの異なるHDDから読み込み&書き込みする場合はHDD毎にスレッド作った方が効率いいですよね?
間違ってたら指摘お願いしますm(_ _)m

96 :デフォルトの名無しさん:2008/09/09(火) 15:21:44
>>95
ドライバはカーネルが動かす。従って、CPUが複数(或いは複数コア)あるなら
ユーザアプリとは並列に動ける。おまけに、ディスク自体にもバッファがあるから普通は余り意識しない。
まして一般的にディスクの方が圧倒的に遅いから、HDD毎にスレッドを作るなんて事はしない。

97 :デフォルトの名無しさん:2008/09/09(火) 15:23:45
追記です。二つ目の質問は
「一つのHDDから複数のデータを読み書きするとき、データごとに別スレッドにはしないべきか」と言う意味です
宜しくお願いします

98 :デフォルトの名無しさん:2008/09/09(火) 15:33:43
HDDは遅いから複数スレッドの方がいい
HDD1が終わるまで待っている時間が無駄

99 :デフォルトの名無しさん:2008/09/09(火) 15:38:58
早速回答ありがとうございます!
しかし>>96>>98の言っていることが逆に見えて混乱しています

たとえカーネルが実際のIO等を行ってるとしても、読み込み終わるまでアプリは待機しますよね?
IO毎にスレッドを分ければその間CPUはアイドル状態にならずに効率が上がるかと思うのですが・・・

しかし、同じHDDで読み書きするデータごとにスレッドを分けるのは流石にやりすぎですよね^^;

100 :デフォルトの名無しさん:2008/09/09(火) 15:43:03
>>99
>95はI/Oに限定した話じゃないの? I/Oしかやることがないならスレッド分けたって待つだけじゃん。
処理とI/Oを分けるかって話なら処理がI/Oに依存しないで済むなら分けておいたら? ってことになる。

101 :デフォルトの名無しさん:2008/09/09(火) 15:47:51
一番初めに
「データ処理部分とHDDから読み込み&書き込み処理部分ってスレッド分けた方が」
って書いてあるだろ

102 :デフォルトの名無しさん:2008/09/09(火) 16:22:13
>>100
ありがとうございます。処理とIOを分けたかったんです。
処理とIOは依存しないわけではないのですが、パイプライン式に順次並列処理しようかと思います。

103 :デフォルトの名無しさん:2008/09/09(火) 16:33:02
読みながら処理しながら書くの?
読んでから処理してから書くの?
読みながら処理してから書くの?


104 :デフォルトの名無しさん:2008/09/09(火) 17:26:37
こんな感じで実行予定です
以下同行は並列と見てください

HDD1からDATA1読み込み
HDD1からDATA2読み込み  DATA1の処理
HDD1からDATA3読み込み  DATA2の処理  HDD2にDATA1書き込み
HDD1からDATA4読み込み  DATA3の処理  HDD2にDATA2書き込み
                   DATA4の処理  HDD2にDATA3書き込み
                              HDD2にDATA4書き込み


105 :デフォルトの名無しさん:2008/09/09(火) 17:46:11
マルチスレッドなんて使わずに非同期入出力で

106 :デフォルトの名無しさん:2008/09/09(火) 18:30:45
非同期でOSまかせが速い、効率いいとはいえない。
データをまとめて出力するなどキャッシュを作った方が速い。
10Kを一万回やったら非同期でも時間かかる

107 :デフォルトの名無しさん:2008/09/10(水) 09:47:23
読み込んだデータをクラスに展開しないといけないので、非同期読み込みだと
メモリを最悪倍近く無駄に食うような気がしたのでこの方法がいいかと思ったのですが・・・

また、細切れに読み込んでも連続したデータであればキャッシュは効くと聞いたことが
あるんですがそれも違うのでしょうか?

108 :デフォルトの名無しさん:2008/09/11(木) 04:25:04
先読みに頼るぐらいならまとめて読め

109 :デフォルトの名無しさん:2008/09/11(木) 17:42:38
>>107
win32なら、ファイルを開くときのオプションでキャッシュに連続の先読みを指示するオプションがある。
基本的にAPIの呼び出し回数を減らすのが速い

110 :デフォルトの名無しさん:2008/09/12(金) 15:57:55
並列動作で効率を高めるため、最適な数のスレッドを生成したいのですが
コア数を取得するAPIが見つからなくて困っています。API等では用意されていないのでしょうか

111 :デフォルトの名無しさん:2008/09/12(金) 16:07:37
なんのことはない,Win32の GetSystemInfo() を叩けばいいらしい
SYSTEM_INFO構造体を受け取って
dwNumberOfProcessorsメンバーにコア数が入っているとのこと
http://gurizuri0505.halfmoon.jp/20080806/2423

112 :デフォルトの名無しさん:2008/09/12(金) 16:09:23
http://www.usefullcode.net/2006/12/apios.html

113 :デフォルトの名無しさん:2008/09/12(金) 16:48:59
即レスさんくす!
無事取得できましたm(_ _)m

114 :デフォルトの名無しさん:2008/09/13(土) 04:35:56
タスクマネージャのパフォーマンスグラフみたいに、
コア毎の負荷(使用率)を知りたいのですが、
簡単に取得する方法はありますか?


115 :デフォルトの名無しさん:2008/09/13(土) 09:40:30
環境次第

116 :デフォルトの名無しさん:2008/09/20(土) 10:59:05
マルチスレッド用の効率的なQueueを書いてください

117 :デフォルトの名無しさん:2008/09/20(土) 11:53:09
状態変数の練習にはいいんじゃね

118 :デフォルトの名無しさん:2008/09/20(土) 11:59:21
lock free queue

119 :デフォルトの名無しさん:2008/09/20(土) 12:28:10
プライオリティキューを
マルチスレッド化したいです

120 :デフォルトの名無しさん:2008/09/20(土) 15:09:44
pthread_cond_wait()が遅くて
しょりがおいつかないときって
大体方法何かないですか
たすけて〜〜〜

121 :デフォルトの名無しさん:2008/09/20(土) 15:32:57
どうやって遅いって調べたんだ

つかwaitしてるようで実はポーリングになってるとかいうオチじゃなかろうな

122 :デフォルトの名無しさん:2008/09/22(月) 09:07:18
私たちはマルチスレッドですか?

123 :デフォルトの名無しさん:2008/09/22(月) 09:19:12
>>122
精子はマルチで卵子に向かいますが
卵子は基本的には一匹入ったらLockをかけるので
通常はシングルで動きます
でも、時々Lockに失敗して双子以上ができる場合があるので注意が必要です

124 :デフォルトの名無しさん:2008/09/22(月) 09:53:22
マルチスレッドと言うより、
イベントドリブンというか、割り込み駆動な感じだな。

125 :デフォルトの名無しさん:2008/09/22(月) 12:27:29
NMI最強

126 :デフォルトの名無しさん:2008/09/22(月) 15:54:58
今日のわたしはモード2なのよ
ttp://www.youtube.com/watch?v=gpzCBUwU_Ys


127 :デフォルトの名無しさん:2008/10/05(日) 11:44:01
複数スレッドのプログラムへのCPUコアの対応としては>>44とのことですが、
コア数を設定できるソフトの場合、4コアCPUなので4コアを設定したとしても
OSが状況に応じてそれより少ないコアで処理させてり、というようなことが
起こってしまうのでしょうか?

128 :デフォルトの名無しさん:2008/10/05(日) 12:05:42
>>127
ユーザープログラムを4コア設定にしようと
OSが割り当ててくれないかぎり無駄。

129 :127:2008/10/05(日) 12:10:42
>>128
なるほど・・・
いちおう4コアとか設定はできるものの、それは「4スレッド以上使うプログラムで実行しますよ」ということであって、
OSによりコアに手空きがあれば初めて実現することなんですね。
勉強になりました。
そうすると「このプログラムは2コアまで対応してるからCPUは2コアのものを購入」となるところを、余裕を見て
4コアCPUにしておく、という考え方が有効になるわけですね。
勉強になりました。
ありがとうございました。

130 :デフォルトの名無しさん:2008/10/05(日) 17:18:13
有効ってまあ有効と言えば有効だけどあまり有効って感じじゃない。


131 :デフォルトの名無しさん:2008/10/05(日) 21:55:34
裏で200も300もスレッド走ってなきゃ
2コアでも4コアでも指定したスレッド起こせるだろw

その実装がスケール可能かつ性能どれだけ伸びるか考えろよw

132 :デフォルトの名無しさん:2008/10/06(月) 11:30:00
余り細かい話になると、OSとCPUを特定しないと意味がなくなる気がするのだが。
因みにLinuxの場合、Gnomeが、ひいてはXが動いているとそれだけで1コア占有するくらいパフォーマンスが落ちることもあるので注意。
# 今時、それほど酷くないけどね。

133 :デフォルトの名無しさん:2008/10/06(月) 22:25:18
>>132
それこそKernelとGnomeのバージョン言えって
話だけどな

134 :デフォルトの名無しさん:2008/11/03(月) 14:53:14
pthread に、スレッドが pthread_cond_wait で待ち状態にあるかを判定する関数はありますか?

135 :デフォルトの名無しさん:2008/11/03(月) 14:56:13
pthread に、スレッドが pthread_cond_wait で待ち状態にあるかを判定する関数はありますか?

136 :デフォルトの名無しさん:2008/11/03(月) 15:03:28
2回書き込んでしまった。すんません。

137 :デフォルトの名無しさん:2008/11/03(月) 15:11:31
大事なことだからしょうがない

138 :デフォルトの名無しさん:2008/11/03(月) 15:20:31
大事なことだからしょうがない

139 :デフォルトの名無しさん:2008/11/03(月) 15:27:32
して、待ち状態は判定できるんですか?

140 :デフォルトの名無しさん:2008/11/03(月) 15:58:00
A.問い合わせる

B.返事来る

C.返事が甲なので甲とみなした処理をする


んでB〜Cの間に乙になってて発狂する予感

141 :デフォルトの名無しさん:2008/11/03(月) 21:35:35
>>135
wait状態を取得する関数があったとしても、現在もその状態である保障は無いね。

142 :デフォルトの名無しさん:2008/11/04(火) 12:19:49
状態を取得した一瞬後には状態が変わってるかもしれんしな

143 :デフォルトの名無しさん:2008/11/04(火) 12:52:40
pthread_cond_waitの引数のmutexを使えばできそうな。
pthread_mutex_trylockでmutexがロックできたらwait中。


144 :デフォルトの名無しさん:2008/11/05(水) 00:02:01
トランザクションメモリの実装について
くわし〜〜くかいた本ある?

145 :デフォルトの名無しさん:2008/11/05(水) 01:02:19
>>144
「Transactional Memory」
くわし〜〜くはないがたくさんは載ってる

146 :デフォルトの名無しさん:2008/11/06(木) 00:02:30
>>143 wakeupしたあとにCPUがまわってくるのを待ってる状態という場合もある



147 :デフォルトの名無しさん:2008/11/09(日) 01:48:11
デバイスとの非同期処理の為に、別スレッドでポーリングしているんだが、
ポーリング関数内で、select -> read の処理を丸ごとロックしてる。
書き込みは メインスレッド内でロックして write 。

一応動いてるんだけど、どうも自信がない。
間違って select なりmutex なりを使っている気がする。
こういう類いの処理ってどういう本読めばいいのかな。
何かアドバイスください。

148 :デフォルトの名無しさん:2008/11/09(日) 11:21:59
それだと、ポーリング用スレッドがselect+readでロックしている間、
メインスレッドがロックを獲得できない(writeできない)気がするがどうか。

select実行中のロックは不要だろう。
ただselect用のFD_SET作成中はロックがいる気がする。

みたいな。

149 :デフォルトの名無しさん:2008/11/09(日) 16:25:47
>>147
情報が少なくてよくわからないけど、とどのつまり、何のために
ロックしなくちゃいけないかってこと次第

read と write が同時に発行できるならロック不要だし、
同時に出来ないなら、そのルールに合わせてロック入れる。

あと、多分、 select は不要なんじゃないかね


150 :デフォルトの名無しさん:2008/11/09(日) 16:46:16
関数型言語だと具体的にどういう風にマルチスレッドに最適なの?
去年あたりからErlangとかScalaとかHaskellとかが話題になってて気になる。
全ての関数がワーカスレッドベースになるとかそんなとんでも話じゃないよね?

151 :デフォルトの名無しさん:2008/11/09(日) 17:42:57
STM難しい
やる夫助けてくれ

152 :デフォルトの名無しさん:2008/11/09(日) 18:05:32
>>150
第五世代コンピュータでヤフれ

153 :デフォルトの名無しさん:2008/11/09(日) 20:00:16
すみません。言語としてWinAPI(C言語)、C#、Javaを覚えたのですが(どれもGUIやファイル操作、DB接続ができる程度のレベルです。あとネットワークも少々)
スレッドプログラムを次はマスターしたいのですが、どの言語でスレッドを学ぶのが一番いいですか?

ひとつ覚えたら残りの言語も覚えたいと思っていますので、とっかかりに一番いいのをおしえてください。
よろしくお願いします。

154 :デフォルトの名無しさん:2008/11/09(日) 20:11:20
Java

155 :デフォルトの名無しさん:2008/11/09(日) 20:29:50
>>153
どれでもいいよ。そんな取り立てて挙げるほど大層なもんじゃない。

156 :デフォルトの名無しさん:2008/11/09(日) 20:52:34
まぁJavaかC#だな。C言語でやるとLockが面倒だし

157 :デフォルトの名無しさん:2008/11/09(日) 22:39:47
だね。
スレッドに絡む部分、概念の学習に専念できるという意味でも、
JavaかC#辺りがやりやすいと思う。


158 :デフォルトの名無しさん:2008/11/09(日) 22:42:28
良書が揃ってるのはJavaだからJavaにしとけばいいと思うよ

159 :153:2008/11/09(日) 23:06:46
みなさんどうもありがとうございます。>>156さん、WinAPIでやるとちょっと面倒なんですね。
なるべく単純な概念だけを覚えたいので、C#かJavaにしようとおもいます。

でも、>>154サン以降全員Javaが候補に入ってるのでJavaにしようとおもいます。
いまから、本屋にいって立ち読みしてきたいとおみます。みなさん、ありがとうございました。

念願のスレッドプログラムの第一歩を踏み込めそうです。

160 :デフォルトの名無しさん:2008/11/10(月) 11:33:47
ところでおまいらhyukiの
『Java言語で学ぶデザインパターン入門マルチスレッド編』
っておすすめでしょうか?

161 :デフォルトの名無しさん:2008/11/10(月) 11:45:24
Java固有の話とそうでない話を見分けるつもりで読むといいよ

162 :デフォルトの名無しさん:2008/11/10(月) 12:08:45
並行プログラムの本がある、おすすめ。

163 :デフォルトの名無しさん:2008/11/10(月) 17:09:52
>>160
入門書としてはベスト。それ卒業したら「Java並行処理プログラミング」

164 :デフォルトの名無しさん:2008/11/10(月) 18:30:24
JavaってマルチCPUなりコアなりの環境でもシングルCPUしか使えない
と認識してるけどあってる?

165 :デフォルトの名無しさん:2008/11/10(月) 18:31:56
あってる
グリーンスレッドっていう環境にやさしいスレッド方式があって、
デフォルトはそれになってる

166 :デフォルトの名無しさん:2008/11/10(月) 18:46:24
グリーンスレッドなのはjavaの最初の版だけだったと記憶してるけど、
今でも切り替えられたっけ?

167 :デフォルトの名無しさん:2008/11/10(月) 19:23:04
>>165
十年前から乙。
>>166
無理。グリーンスレッドとネイティブスレッドの切り替えがあるのはClassicVMで、HotspotVMはネイティブスレッドのみ。
で、ClassicVMはJava1.4あたりで切られたようだ。

168 :デフォルトの名無しさん:2008/11/10(月) 21:01:28
1.2 ぐらいまではずっとグリーンスレッドだった。
最初の版だけなんてことはない。

169 :デフォルトの名無しさん:2008/11/10(月) 23:05:10
WroxのProfessional Multicore Programming
ってCore2とかAMDのCPUのことも書いてあるんだな

170 :デフォルトの名無しさん:2008/11/11(火) 00:42:41
http://pc.watch.impress.co.jp/docs/2008/1107/winhec2_02.jpg

これをうまく制御するプログラミングが知りたい

171 :デフォルトの名無しさん:2008/11/11(火) 00:48:22
>>170
Intelのパフォーマンスライブラリに期待しよう

172 :デフォルトの名無しさん:2008/11/11(火) 10:48:50
>>170
すげー
ビリー・ミリガンみてーだな

173 :デフォルトの名無しさん:2008/11/12(水) 04:44:45
>>170
元気なプロセスをいっぱい動かせば良いだけのような気もする。

174 :デフォルトの名無しさん:2008/11/12(水) 07:02:25
同じアドレスに一斉に読み書きするとか
同じロックを一斉に取得、解放するとか
そういうループをブン回して
どうなるか観察したい

175 :デフォルトの名無しさん:2008/11/13(木) 00:36:35
>>170
スレッドを192個作る。
各スレッドのaffinityを設定して、CPUに貼り付ける。
特定のスレッドのセットをビジーループにして、タスクマネージャに文字を出す。

176 :デフォルトの名無しさん:2008/11/13(木) 00:47:04
>>175
> 特定のスレッドのセットをビジーループにして、タスクマネージャに文字を出す。

ビルのイルミネーションみたいでいいね!

177 :デフォルトの名無しさん:2008/11/13(木) 09:57:17
winで1プロセスに64コア以上ってどうやるんだっけか

178 :デフォルトの名無しさん:2008/11/17(月) 20:48:06
>>177
>Windows 7/Windows Server 2008 R2 では 64 論理 CPU をひとつの "グループ" と定義し,
>プロセスは初期状態で "グループ" のどれかに束縛されている(どのグループに属するかはラウンドロビンで決定される).
>そして,新しく定義された API で明示的に許可を与えない限り,プロセス内のスレッドは
>所属 "グループ" の CPU でのみ実行される.

>つまり,新しい CPU グループ制御 API を使用しない限り,ひとつのプロセスは高々 64 個の
>プロセッサしか活用しない.

ttp://d.hatena.ne.jp/NyaRuRu/20081107/p1

179 :デフォルトの名無しさん:2008/11/18(火) 11:06:48
窓7が主流になる頃には64コアCPUとか出てるって事?
凄いな

180 :デフォルトの名無しさん:2008/11/18(火) 11:14:12
マルチCPU

181 :デフォルトの名無しさん:2008/11/18(火) 11:30:11
8コア*8CPUでやっと64
4CPUのマザーは見たことあるけど…

182 :デフォルトの名無しさん:2008/11/18(火) 13:20:57
ブレードにすればよかろう。

183 :デフォルトの名無しさん:2008/11/18(火) 22:01:52
コンシューマ向けの話じゃないのか

184 :デフォルトの名無しさん:2008/11/19(水) 00:25:44
て言うか、ブレードってブレード毎にOSが載ると思うが。
8ブレードとかを1つのOSで制御できる奴なんてあるのか?

185 :デフォルトの名無しさん:2008/11/19(水) 00:37:32
>>184
http://www.hitachi.co.jp/products/bladesymphony/product/bs1000.html
インテル Itanium プロセッサー搭載サーバブレードでは、バックプレーンの
高速インターコネクトを介し最大4枚のサーバブレードをSMP接続することで、
最大8プロセッサ(16コア)のSMPサーバーとしても利用可能。

http://h50146.www5.hp.com/products/servers/nonstop/hardware/NB50000c/index.html
最新のデュアルコア インテル Itanium プロセッサ(9100シリーズ)を最大4,080個搭載可能

186 :デフォルトの名無しさん:2008/11/19(水) 07:36:32
>>185
これ買おうかな
やっぱ自宅警備にはこれくらいのマシンがないとな

187 :デフォルトの名無しさん:2008/11/20(木) 17:32:02
int i;
for( i=0; i<10; i++ )
{
  h = CreateThread ( NULL, 0, (LPTHREAD_START_ROUTINE)DoIt, NULL, 0, &id );
}

void WINAPI DoIt()
{
  // ここでいろいろ
}

のようにして同じ関数を複数のスレッドで行いたいのですが
ここでいろいろのところに制御がいかず すぐにスレッドが終了するのですが
同じ関数をスレッドで実行することはできないのでしょうか?

WindowsXP
C/C++ Win32API

188 :デフォルトの名無しさん:2008/11/20(木) 17:47:14
>>187
まず先に突っ込んでおくが、LPTHREAD_START_ROUTINEと
合わない関数をキャストで無理矢理渡すな。
DoIt()がLPTHREAD_START_ROUTINEに適合する関数なら
キャストなんて必要ない。

すぐにスレッドが終了するってのは、どうやって確認した?
CreateThreadを呼んだメインスレッドは、各スレッドが仕事を
終えるまで待機している?
そもそもDoIt()がすぐに終了する内容じゃないの?

189 :デフォルトの名無しさん:2008/11/20(木) 18:09:42
>>188
すいません
処理の流れがつかめてませんでした

解決しました

190 :デフォルトの名無しさん:2008/11/20(木) 18:18:19
便乗して質問ですが
WindowsXP Home Edition にて作成するスレッド数の上限はありますか?

191 :デフォルトの名無しさん:2008/11/20(木) 18:26:58
http://msdn.microsoft.com/ja-jp/library/cc429080.aspx
> 1 つのプロセスが作成できるスレッドの数は、利用可能な仮想メモリによって制限されます。
> 既定では、各スレッドに 1MB のスタック空間が割り当てられています。
> そのため、最大 2,028 個のスレッドを作成できます。

192 :デフォルトの名無しさん:2008/11/20(木) 19:35:05
マルチもいいけど 実行ファイルが自分で空いてるCPU選ぶようにしたい
Windows側でプロセス作成時に勝手にやってるとありがたい

193 :デフォルトの名無しさん:2008/11/20(木) 21:55:25
意味がわからん。
スレッドはあいているCPUでしか実行出来ないし。

ひょっとして、自分のプロセス専用にCPUが
割り振られて欲しいって話か?

194 :デフォルトの名無しさん:2008/11/21(金) 10:58:32
Sleep関数について質問ですが

MSDNによると
VOID Sleep(
  DWORD dwMilliseconds   // 中断の時間
);
とありますが
マイナスの値を代入した時の挙動はどうなるのでしょうか?

実際ためしてみたのですが、永遠制御が返ってきません

195 :デフォルトの名無しさん:2008/11/21(金) 11:34:10
DWORDは符号なしの型だからマイナス値を取れないと思うが

196 :デフォルトの名無しさん:2008/11/21(金) 11:39:26
>>195
なるほど

しかし、VC++6.0 では怒られないんですよ
http://2ch.homelinux.com/2d/32/src/1227235104677.jpg

197 :デフォルトの名無しさん:2008/11/21(金) 11:41:30
VC6はゴミということで

198 :デフォルトの名無しさん:2008/11/21(金) 11:44:17
まぁそりゃ暗黙に型変換されてるんだろう
警告なしにそういった型変換をするのはCの悪いところ
というか警告レベルを上げましょう

199 :デフォルトの名無しさん:2008/11/21(金) 12:49:10
マルチスレッド対応で60FPSを維持する方法ってどうやるんですか?

200 :デフォルトの名無しさん:2008/11/21(金) 12:59:59
ぇ?w

垂直同期とか

201 :デフォルトの名無しさん:2008/11/21(金) 13:57:29
>>196
49.7日待てば目覚めるはず

202 :デフォルトの名無しさん:2008/11/21(金) 14:03:23
えいえんは、あるよ
49.7日ぐらい

203 :デフォルトの名無しさん:2008/11/21(金) 19:43:02
>>197
Cの仕様なのに何言ってんだ。

204 :デフォルトの名無しさん:2008/11/21(金) 19:58:03
Cはゴミということで

205 :デフォルトの名無しさん:2008/11/22(土) 00:28:22
>196
まず警告レベルを上げろ。

206 :デフォルトの名無しさん:2008/11/22(土) 10:52:51
>>205
警告レベル4にしたら
STLのライブラリのソースでwarnningが・・・
MS君・・・

207 :デフォルトの名無しさん:2008/11/22(土) 22:06:38
STL で warning はよくあること。
まあ気にすんな。
鬱陶しければ #pragma warning(disable: XXXX) で消して
後で #pragma warning(default: XXXX) で復活させれば良い。

208 :デフォルトの名無しさん:2008/11/28(金) 03:09:31
CreateThreadでクラスのメンバ関数って渡せますか?

209 :デフォルトの名無しさん:2008/11/28(金) 03:21:05
なんとなく自己解決しました

210 :デフォルトの名無しさん:2008/11/28(金) 16:46:25
test


211 :デフォルトの名無しさん:2008/12/01(月) 19:47:00
>>201
INFINITE = 0xFFFFFFFF = (DWORD)-1

212 :デフォルトの名無しさん:2008/12/01(月) 21:46:58
>>211
あーそうなんだー


213 :デフォルトの名無しさん:2008/12/02(火) 00:26:53
P2Pや分散メモリに適した高速
ロックってどんなのがあるのですか?

214 :デフォルトの名無しさん:2008/12/02(火) 00:43:43
とりあえず知ってる言葉を並べてみました。

215 :デフォルトの名無しさん:2008/12/02(火) 07:57:29
>>213
高速なパッセージならやっぱ3大ギタリスト、とくにベックじゃね?
ルカサーも捨てがたいが
若いのは知らん

216 :デフォルトの名無しさん:2008/12/02(火) 11:30:25
やっぱりクリティカルなセクションをアトミックに相互排他する場合
レスポンスタイムが長いメモリをダイレクトにアクセスするのは非効率だから
トランザクショナルメモリみたいな遅延する仕組みがマストニードじゃないですかね

217 :デフォルトの名無しさん:2008/12/02(火) 13:11:00
日本語でおk

218 :デフォルトの名無しさん:2008/12/02(火) 13:27:51
やっぱり際どい領域を原子的に相互排他する場合
反応時間が長い記憶装置を直接読み書きするのは非効率だから
トランザクショナルメモリみたいな遅延する仕組みがどうしても必要じゃないですかね

トランザクショナルメモリだけはどうにもならんかった。

219 :デフォルトの名無しさん:2008/12/02(火) 13:37:44
「処理単位記憶装置」かな?

220 :デフォルトの名無しさん:2008/12/02(火) 14:44:45
都覧公国量産型六番書鳴記憶

221 :デフォルトの名無しさん:2008/12/02(火) 20:55:12
ザクメモリってどうやってつくるの?
アルゴリズム全然解らん

222 :デフォルトの名無しさん:2008/12/02(火) 21:45:47
弱そうなメモリだな

223 :デフォルトの名無しさん:2008/12/02(火) 21:51:07
トラングフショナルメモリ

224 :デフォルトの名無しさん:2008/12/02(火) 21:51:07
トランザクショナルメモリって
どんなアルゴリズムなのですかね?

何処探してもみつからない

225 :デフォルトの名無しさん:2008/12/02(火) 22:02:31
ロックフリーあたりで調べればいいと思う
でもコストが大きい気がするのでリードライトロック程度で十分かと


226 :デフォルトの名無しさん:2008/12/02(火) 22:14:10
リードライトロックの中にもフェアかフェアじゃないかで変わるけどね。
オブジェクト指向はハードウェアの都合までは吸収してくれんよなぁ。
マルチスレッドのデザパタ見ててそう思う。

227 :デフォルトの名無しさん:2008/12/02(火) 22:44:09
排他制御書き込みって
pthread_rwlockで実現できますか?

228 :デフォルトの名無しさん:2008/12/03(水) 00:04:59
素直にmutexつかっとけ
読み書き両方な

229 :デフォルトの名無しさん:2008/12/03(水) 00:17:05
>228
排他制御書き込み実現しようとすると
pthread_mutexでは、try_lockを全mutex分
毎回ぶん回すってことでおkなのかな?

この辺の定石ってよくわからん

230 :デフォルトの名無しさん:2008/12/03(水) 03:01:55
mutexが複数あるの?
どういう排他制御をしたいのかわからん

231 :デフォルトの名無しさん:2008/12/06(土) 15:29:07
スレッド2000個作って
画像データダウンロードするやつ作ったんだけど
スレッドが全部同時に動作しないんだ
どこがいけないんだ?

232 :デフォルトの名無しさん:2008/12/06(土) 15:42:50
当てずっぽうだけどサーバが2000接続も同時に処理できないんじゃね
1個ずつ順番に処理して残りは待たされてるとか

233 :デフォルトの名無しさん:2008/12/06(土) 15:53:38
そもそも2000スレッドが同時に動くはずがない。

234 :デフォルトの名無しさん:2008/12/06(土) 15:58:58
1000コア*2(HT)ですね
もしそんなのがあったとしても現状Linuxしか動かせない

235 :デフォルトの名無しさん:2008/12/06(土) 16:25:36
「全部同時に」ってのがどの程度の同時性を指してるんでしょうね

236 :デフォルトの名無しさん:2008/12/06(土) 18:00:38
Sunのやつなら動くと思うよ

237 :デフォルトの名無しさん:2008/12/06(土) 19:34:10
どの程度とかの精度の問題ではないんですよ
動けばいいだけのレベルなんですけど
for ループ内で約2000 個のスレッド作るんで、
タイミング的にはほぼ同時な気がしますが
OSにもよるかもしれませんが、
そうそう10秒以上も差が出るとは思えないんで
精度は10秒以内くらいの超おおざっぱでいいですけど
動かないんですよ

ちなみにCUI コマンドプロンプトで多数のスレッドから
printf されるとやはり多重に出力され
hogehogehogehoge が
hohohogegegehoge になったりするんでしょうか?

238 :デフォルトの名無しさん:2008/12/06(土) 19:34:15
環境は?
win32じゃなさそうだが

239 :デフォルトの名無しさん:2008/12/06(土) 19:45:36
Erlangなら60000スレッドぐらい起せるよ

240 :デフォルトの名無しさん:2008/12/06(土) 19:54:33
>>237
標準出力はバッファリングされるので、混ざる場合はバッファサイズずつ混ざる。
>237のように1バイトずつ混ざることはない。

241 :デフォルトの名無しさん:2008/12/06(土) 22:34:02
>>237
動かないってどう動かないんだよ。

242 :デフォルトの名無しさん:2008/12/06(土) 22:45:56
>>238
機密事項なので書けません><

243 :デフォルトの名無しさん:2008/12/06(土) 23:39:13
おれも1万個ぐらい動かしてるけど別に問題ないな。
機密事項だから環境は書けないが。

244 :デフォルトの名無しさん:2008/12/06(土) 23:53:58
>スレッド2000個作って画像データダウンロードする
あほのすることだな


245 :デフォルトの名無しさん:2008/12/07(日) 05:05:46
>>244
ネットワークモニタの使用率が25%超えたことないんで
限界までいどみたかったとです

246 :デフォルトの名無しさん:2008/12/07(日) 05:36:11
>>245
自分で対向サーバを用意すれば簡単だよ。

247 :デフォルトの名無しさん:2008/12/07(日) 06:44:22
スレッドって関係あるん?

248 :デフォルトの名無しさん:2008/12/07(日) 07:44:39
>>247
deteike

249 :デフォルトの名無しさん:2008/12/07(日) 10:16:03
2000個もスレッド作ってりゃオーバーヘッド大きすぎてそりゃ限界までいかんわな。
っていうかそもそもネットワークモニタって実効速度の%出してくれるんだっけ??


250 :デフォルトの名無しさん:2008/12/07(日) 11:04:38
>>249
タスクマネージャにあるよ

OSの限界ギリギリまで性能を出そうとしたのに
なんてOSだ・・・

251 :デフォルトの名無しさん:2008/12/07(日) 11:48:23
馬鹿は巣にお帰りください。

252 :デフォルトの名無しさん:2008/12/07(日) 15:04:34
だからなんでスレッドにすると帯域使用量が上がるんだっけ?
でっかいファイル一つを read するのと、スレッド2000個で read するので
差が出る理由はなに?


253 :デフォルトの名無しさん:2008/12/07(日) 15:06:38
ネットワークの話じゃなかったのか。

254 :デフォルトの名無しさん:2008/12/07(日) 15:19:33
ああ、そういうことね
1スレッドひとつにつき1つの画像をダウンロードするプログラムを組んだ
このスレッドを2000個同時に実行したけど
2000個同時(プログラム的には)には動作してくれなかった
ということ

255 :デフォルトの名無しさん:2008/12/07(日) 15:47:41
だから、2000ポート空けて待つような対向サーバを自前で用意しろって。

256 :デフォルトの名無しさん:2008/12/07(日) 16:10:56
>>252
思い込み

257 :デフォルトの名無しさん:2008/12/07(日) 16:25:13
>>250
だからさあ、例えばギガビットイーサだったら100%って1Gbpsじゃないの?
実効速度250Mps出てても25%だぜ?


258 :デフォルトの名無しさん:2008/12/07(日) 20:02:19
バス速度的に実際1Gbpsなんて無理
100Base-TXで考えなさい

259 :デフォルトの名無しさん:2008/12/07(日) 20:07:35
FPGAのNICなら1Gっていったら1G出ますが?

260 :デフォルトの名無しさん:2008/12/07(日) 20:08:02
うん
馬鹿は帰れ

261 :デフォルトの名無しさん:2008/12/07(日) 20:11:23
>>254
そもそも、シングルコア、1スレッドあたりのタイムスライスを10msとすると、
1周するのに単純計算で10ms×2,000=20,000ms=20秒だ。実際には10msよりも
もっと長いのが普通(※1)だし、スレッド切り替えにもコストがかかる(※2)し、
マルチコアとしてもコア数分の1にしかならない上に、コア間の調停にも
やっぱりコストがかかる(※3)。
あと、ネットワークの実効速度についても、デカいパケットが順番に流れる
なら、かなり帯域上限に近付けることができるが、細かいパケットが非同期に
衝突しまくりながら流れるようだと、いいとこ1/3くらいしか出ない。

ぶっちゃけ、アプローチが間違ってるとしか思えん。

※1:ぐぐってみたところ、Windowsについてはこんなんが引っかかった。
ttp://itpro.nikkeibp.co.jp/article/COLUMN/20080602/305755/?ST=develop&P=3
もっと良い資料やUNIXについての言及があれば教えてくれ。
※2:レジスタ等のコンテキスト情報を全部保存してパイプラインを捨てて
他スレッドのコンテキストを読み込む。キャッシュから溢れてたら最悪
メインメモリまで取りに行くハメになるぞ。
※3:各コアが互いに読み書きできるレイヤまでデータが届く必要があるため。

262 :デフォルトの名無しさん:2008/12/07(日) 20:37:21
たしか一般に、CPUサイクルで見て、
スレッド作成が数万〜10万サイクル(ひょっとすると数十万〜だったかも)、
コンテキストスイッチが数千〜1万サイクル
とか見た気がする。


263 :デフォルトの名無しさん:2008/12/07(日) 20:38:37
おっと、スレッドに関わるオーバーヘッドの話ね。


264 :デフォルトの名無しさん:2008/12/08(月) 01:15:52
>>262
>コンテキストスイッチが数千〜1万サイクル

今時LinuxでもO(1)スケジューラなわけだが。

265 :デフォルトの名無しさん:2008/12/08(月) 01:22:44
そりゃ的外れなレスなこって

266 :デフォルトの名無しさん:2008/12/08(月) 01:48:56
ワロタ


267 :デフォルトの名無しさん:2008/12/08(月) 09:39:27
WindowsとかLinuxとか・・・
そんな貧乏臭いOSの話ばっかでワロタ

268 :デフォルトの名無しさん:2008/12/08(月) 10:27:54
そうですか

269 :デフォルトの名無しさん:2008/12/08(月) 13:48:37
アセンブラ級はついていけn

270 :デフォルトの名無しさん:2008/12/08(月) 18:58:28
何十万ものスレッドをサポートするようなシステムもあるんだよね?

どういう構造になってんだろ
根本的に考え方からちがうのかな?


271 :デフォルトの名無しさん:2008/12/08(月) 19:01:51
>>270
カーネルスレッドは使わない(ユーザスレッドでやる)、か、そういうスレッドを
サポートしたカーネルでないと無理。普通のUnixの普通のカーネル(含むLinux)
とかだと無理。

272 :デフォルトの名無しさん:2008/12/08(月) 21:55:16
OSはWindowsXPなんですよ
で、ソースですが
for( int i=0; i<2000; i++ )
{
  _beginthred( DoIt, 0, NULL );
}

void DoIt( void * )
{
  DownloadURL( URL, filename );
  _endthread();
}
ってな感じですけど
ほとんど同時時間にスレッドを起動させてるのですが、
タイムスライスが各スレッドに割り当てられないのでしょうかね?

それともやっぱり >>232 さんの言っているように
サーバー側が延滞処理をほどこしているんでしょうかね?

問い合わせたくてもあまり進んで聞けるようなことではないので

273 :デフォルトの名無しさん:2008/12/08(月) 22:05:16
>272
スタック用の仮想メモリが足りなくなってない?

あるいは、その呼んでいるDownloadURLが
STAみたいな実装とかw


>261
IOが支配的なスレッドで、タイムスライスの意味なんか
ほとんどないとおもうけど。

274 :デフォルトの名無しさん:2008/12/08(月) 22:48:50
同一サーバにHTTPコネクションを2000張ろうとしていたオチと予想

275 :デフォルトの名無しさん:2008/12/08(月) 23:28:21
Irvineとかで試してみればどうかな

276 :デフォルトの名無しさん:2008/12/08(月) 23:41:31
>>274
攻撃とみなされても仕方ありませんな

277 :デフォルトの名無しさん:2008/12/09(火) 00:06:27
>>273
仮想メモリなのに足りなくなるとは、これいかに。

278 :デフォルトの名無しさん:2008/12/09(火) 00:15:39
2000個のスレッドでスタックだけで仮想メモリ使い切るだろWin32なら。


279 :デフォルトの名無しさん:2008/12/09(火) 00:20:56
いくらIOバウンドだって普通2000はやりすぎ。
普通はせいぜい100までだろう、CPU数にもよるがそれでも多いくらいだろう。
だいたい2000個の各ファイルのサイズはどのくらいで、
単体での転送速度はどのくらいなんだ。

ってダウンロードが2個までしか同時に動いてなかったりしてなw

あとサーバ側も普通は当然そんなに同時処理できない
キューに入って順番に処理されるだけ。


280 :デフォルトの名無しさん:2008/12/09(火) 01:06:30
>>278
> 2000個のスレッドでスタックだけで仮想メモリ使い切るだろWin32なら。

相変わらず意味不明。

281 :デフォルトの名無しさん:2008/12/09(火) 01:07:09
俺がワーカスレッドをプールする場合は、
特に深く考えずに単にコア数の倍だけ用意しとく。
IOブロックで動けるようになった他のスレッドもIOでブロックされるだけだしね。

282 :デフォルトの名無しさん:2008/12/09(火) 01:23:17
>277,280
正確には仮想メモリ空間。
Win32では、ふつー、プロセス毎に、ユーザ空間として
使用可能なのは、下位から7fffffffあたりまでで、2GB。
だいたい、ポインタが32bitであることの限界とみていい。

で、Win32のスレッドは、1つあたり、規定では1MBの
スタックを仮想メモリ空間に確保する。他にもDLLとかの
コード領域も同じ2GBの空間を使うわけで。

283 :デフォルトの名無しさん:2008/12/09(火) 01:35:04
>>282
仮想メモリというのはプロセス毎にあってだな・・・

284 :デフォルトの名無しさん:2008/12/09(火) 01:47:50
>>283
>237嫁

285 :デフォルトの名無しさん:2008/12/09(火) 01:56:53
>>283のおバカさを示すなら>>191の方が適切だろ。

286 :デフォルトの名無しさん:2008/12/09(火) 09:08:47
>>281
だったらコア数の2倍はちょっと少なくない?
まあIOってもネットワークなどの場合で、
もちろん少ない投入数で帯域使いきれるような場合や
同一サーバにつなぐような場合は別だが。


287 :デフォルトの名無しさん:2008/12/09(火) 10:26:51
Win32(笑)

288 :デフォルトの名無しさん:2008/12/09(火) 10:28:16
ネイティブなプロセスやスレッドで並列性増やす方法は全然スケールしないから
軽量プロセス/スレッドが流行るんだろ
Erlangのような言語は言語のレベルでそういうものをサポートしている

目的がI/O多重化なら昔ながらのselect系のシステムコールが使える
WindowsならIOCP
Javaは1.4以降でnioという形でそれをサポートしてるし
Cならlighttpdで使われているlibeventのようなものがある

それはそうと、Windows XPあたりだと、デフォではTCPの同時接続数が10だかに
制限されているはずだが

289 :デフォルトの名無しさん:2008/12/09(火) 12:08:39
>>288
ソースは?

290 :デフォルトの名無しさん:2008/12/09(火) 12:11:40
>>289
「どれ」についてのソースなのか分からんが、
最後のものについてなら、そのまんま
Windows XP 同時接続数
でぐぐればいくらでも情報が手に入るだろ

291 :デフォルトの名無しさん:2008/12/09(火) 12:18:08
UDPは制限あるの?

292 :デフォルトの名無しさん:2008/12/09(火) 12:19:40
知らん
UDPにはconnectionという概念がないから、多分無いんじゃないかとは思うが
自分で調べたらどうだ

293 :デフォルトの名無しさん:2008/12/09(火) 12:25:13
いやです
ありがとうございました

294 :デフォルトの名無しさん:2008/12/09(火) 12:40:30
ググってみたが、XPのSP2から1秒間につき10コネクションという
制限がついたらしい。
時間をあければ万単位までいけるみたいだが。

295 :デフォルトの名無しさん:2008/12/09(火) 12:40:39
Windows XP Professional の場合、ネットワーク経由で同時に接続することができるコンピュータの最大数は 10 です。
とありますが、
メッセンジャーに繋げてますが
この状態だと最大数は9になるのでしょうか?

296 :デフォルトの名無しさん:2008/12/09(火) 13:11:01
制限解除するパッチもあるよ。公式じゃないけど。

297 :デフォルトの名無しさん:2008/12/09(火) 13:11:23
もう少し詳しく調べてみた。

同時最大接続数が10に制限されるのは、listenする側の制限。
ようするに自分がサーバになる場合。

外向きの接続に関する制限は、half-open connectionが
1秒間に10個までに制限されている。(SP2から)
half-open connectionは相手がacceptしてない接続のこと。

外向きの接続数に関しては、能力的な限界以外に制限は無さそう。
ただし1スレッドにつき64ソケットの上限有り。(回避は可能)

298 :デフォルトの名無しさん:2008/12/09(火) 13:13:51
>>297
え?内向きの制限はもともとサーバー系でない奴にはついていて、
XP SP2以降のは、外向きの制限だろ?


299 :298:2008/12/09(火) 13:15:20
要は、listenじゃなくて、外に貼りに行くコネクション数に制限がついたってことな

300 :デフォルトの名無しさん:2008/12/09(火) 14:35:58
>>298-299
そういう制限は見当たらなかった。
日本語の非プログラマ系のブログでそう書いてるところはあるが、勘違いだろう。

実際にセッションモニタ見てると、10なんて余裕で超えてるし。

301 :デフォルトの名無しさん:2008/12/09(火) 14:47:37
>>300
は?
Event ID 4226でぐぐれよ
秒間の「外向きの」同時接続試行回数に関する制限で、
非公式のtcpip.sysに対するパッチも出ているから

302 :デフォルトの名無しさん:2008/12/09(火) 15:00:15
P2Pとかやると直ぐでるからわかる

303 :デフォルトの名無しさん:2008/12/09(火) 15:12:52
ああ、論点のずれが分かった
10個以上のTCP/IPのコネクションが維持できないって制限じゃないだろ
秒間に10個以上SYNパケット(TCPの最初のハンドシェイクで使う)を
投げないようにしているだけのはずだ

要するにスレッド沢山つくって並列でダウンロードさせようとしたところで
10個目以降ではconnect()呼んだ時点で制限にひっかかり、少なくとも他の
ハンドシェイクが完了するまでは待たされるってこった

304 :デフォルトの名無しさん:2008/12/09(火) 15:36:05
ちゃんと297でhalf-open connectionと書いたんだが。
それを否定されたら、同時セッション数としか読み取れないよ。

305 :デフォルトの名無しさん:2008/12/09(火) 15:45:44
そうだな、よく読んでなかった
すまん

306 :デフォルトの名無しさん:2008/12/09(火) 17:47:13
クライアントでどこまでスケールさせる気だ。

307 :デフォルトの名無しさん:2008/12/09(火) 20:04:18
googleのクローラでね?w

308 :デフォルトの名無しさん:2008/12/10(水) 17:25:35
シングルスレッドでダウンロードするとうまくいくのですが
マルチスレッドでダウンロードするとエラーが返ってきて
GetLastError() で戻り値を調べても 0 で何が原因か分からないのですが
どなたか分かりませんか?
WinXP です

309 :308:2008/12/10(水) 17:29:32
マルチスレッドといっても、デバックの為、スレッドはひとつなので
競合などはおきないように設計しているのですけど、うまくいかないのです

310 :デフォルトの名無しさん:2008/12/10(水) 17:39:11
さすがにそれだけで答えろって言われても、俺には無理だな。
GetLastErrorを呼ぶスレッドは合ってるの?

311 :デフォルトの名無しさん:2008/12/10(水) 17:42:36
ダウンロードはどのAPIを使っているの?

312 :デフォルトの名無しさん:2008/12/10(水) 19:15:01
>>311
ググってもでないのよねフフフフフフフフフ

313 :308:2008/12/10(水) 19:19:36
>>311
機密事項なので答えられません><

314 :デフォルトの名無しさん:2008/12/10(水) 20:40:26
>>311
WinInet
InternetOpen
以外のAPIだけとは言っておく

315 :デフォルトの名無しさん:2008/12/10(水) 20:42:31
>>311
とあるライブラリなんです
何かはいえませんが

316 :デフォルトの名無しさん:2008/12/10(水) 20:55:51
俺は原因わかったよ
ここには書けないけど

317 :デフォルトの名無しさん:2008/12/10(水) 21:36:55
内々に連絡しておいた。

318 :デフォルトの名無しさん:2008/12/11(木) 03:36:59
Debug版を納品とかフフフフフフフフフフフフフフフフフフフフフ
フフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフ

319 :デフォルトの名無しさん:2008/12/11(木) 09:31:46
ソースも示さずデバッグ依頼とな。

320 :デフォルトの名無しさん:2008/12/11(木) 09:37:51
ソース。
http://anchorage.2ch.net/test/read.cgi/mnewsplus/1228941968/

残念ながらもう消えてしまったようだが。

321 :デフォルトの名無しさん:2008/12/11(木) 12:06:37
>>318
お主もなかなかのフフフフフフ

でもユーザー名ばれるのよねフフフフフフフッフフフフフフッフ

322 :デフォルトの名無しさん:2008/12/11(木) 12:29:11
夜中にひとりでデバッグしてる時に
フフフフフフフフフフフフフフフフフフフフフフフフフ
とか
feeefeee feeefeee feeefeee feeefeee
とか見ると鳥肌が立ちそうになる・・・

323 :デフォルトの名無しさん:2008/12/11(木) 14:11:44
POSIXスレッドでmutexロックでのデッドロックの回避法教えてください

324 :デフォルトの名無しさん:2008/12/11(木) 14:27:28
馬鹿どもにマルチスレッドを走らせるな

325 :デフォルトの名無しさん:2008/12/11(木) 14:36:53
>>323
2個以上のmutexを同時にロックしないというルールを徹底させるのが一番簡単かと

326 :デフォルトの名無しさん:2008/12/11(木) 15:32:14
走る〜♪
走る〜♪
スレッドーたーちー♪

327 :デフォルトの名無しさん:2008/12/11(木) 15:32:57
馬鹿ですいません><

328 :デフォルトの名無しさん:2008/12/11(木) 15:58:59
_beginthread( multi, 0, data );

>はわわわわ〜
>はわわわわ〜
>はわわわわ〜
>はわわわわ〜
>はわわわわ〜
>はわわわわ〜
>はわわわわ〜
>はわわわわ〜
>はわわわわ〜
>はわわわわ〜
>はわわわわ〜
>はわわわわ〜
>はわわわわ〜
>はわわわわ〜
>はわわわわ〜
>はわわわわ〜
>はわわわわ〜
>はわわわわ〜
>はわわわわ〜

329 :デフォルトの名無しさん:2008/12/11(木) 18:46:03
APIの問題ではなかったようだ
設計の問題だったようだ
これは普通気づかない

330 :デフォルトの名無しさん:2008/12/11(木) 20:45:05
Critical!
Criticalなのぉ〜
Criticalな処理をしていなかったのぉ〜
んぼおおおおおおおおおおおおおおおお

331 :デフォルトの名無しさん:2008/12/12(金) 04:49:09
馬鹿はマルチスレッドやっちゃだめだよ。
死んだじっちゃんの口癖だった。
馬鹿って言うのは思考力が著しく劣る人なんだけど、
具体的に例をあげれば、自分で調べて答えを見つけられない人の事なんだ。

332 :デフォルトの名無しさん:2008/12/12(金) 07:20:42
だ〜か〜らぁ〜
ぐぐってもgooで聞いてもダメなのぉぉぉぉ〜〜〜〜

333 :デフォルトの名無しさん:2008/12/12(金) 11:05:47
デッドロック 予防 とか、デッドロック 回避 とかで検索して、端から見ていってみ。

334 :デフォルトの名無しさん:2008/12/13(土) 13:36:29
1スレッド
2スレッド
3スレッド
4スレッド
5スレッド
全部ためしたののですが1スレッドが一番早かったです
どうしてでしょうか?

335 :デフォルトの名無しさん:2008/12/13(土) 14:23:51
よくあることです。

336 :デフォルトの名無しさん:2008/12/13(土) 14:40:12
何を試したんだよ

337 :デフォルトの名無しさん:2008/12/13(土) 17:25:44
キアイ

338 :デフォルトの名無しさん:2008/12/13(土) 19:48:33
あるスレッドで処理した結果をメインスレッドに渡したいのだがどうすればいい?
_beginthreadexの第3引数に結果用のポインタを渡せばいいのか

339 :デフォルトの名無しさん:2008/12/13(土) 20:43:24
典型的にはソウデスナ
処理してほしい内容と
処理結果の格納場所を
与えるのがよろしいかと思いますダ

340 :デフォルトの名無しさん:2008/12/14(日) 01:39:30
>>338
CPUにお祈りする

341 :デフォルトの名無しさん:2008/12/14(日) 02:58:11
>>334
マルチスレッド化して速くなるかどうかは状況による。
その状況がわからなきゃ、何とも言えない。

342 :デフォルトの名無しさん:2008/12/16(火) 07:49:17
>>338
グローバル変数でいいよ
メモリ空間を共有してるのがスレッドのメリットなんだし

343 :デフォルトの名無しさん:2008/12/16(火) 09:18:38


344 :デフォルトの名無しさん:2008/12/16(火) 11:09:40
volatile最強

345 :デフォルトの名無しさん:2008/12/16(火) 11:13:32
>>388
俺はそういう場合スレッドセーフなスマートポインタ使うな

スレッドにデータを渡す前に参照カウント増やしといて
スレッド側では使い終わったら解放

メインスレッドは結果が必要なくなればスレッドが終了していなくてもデータを解放できる

346 :デフォルトの名無しさん:2008/12/16(火) 11:22:01
クラスにしてthis渡してるな
class tiny_thread abstract {
protected:
  HANDLE m_hthread;
  unsigned m_id;
  : いろいろメンバー
private:
  static unsigned WINAPI thread_start(void *o) {
    tiny_thread *tt = (tiny_thread *) o;
    return tt->run();
  }
public:
  bool start() {
    m_hthread = (HANDLE) _beginthreadex(NULL, 0, thread_start, this, 0, &m_id);
    return m_hthread != 0;
  }
  virtual int run() = 0;
};


347 :デフォルトの名無しさん:2008/12/16(火) 15:41:15
>>388は素人童貞

348 :デフォルトの名無しさん:2008/12/16(火) 15:56:58
>>388 に期待

349 :デフォルトの名無しさん:2008/12/17(水) 01:34:39
・メインスレッドが必ずサブスレッドより長生きするようにする。
 メインがサブをjoinなり必要に応じて中断するなりする。
・結果格納場所のポインタやコールバック関数のアドレスをサブに渡す。
 メインがUIスレッドの場合、サブからPostThreadMessageした方が楽かも知れない
・通信用メモリの解放責任をメイン側と決めておく

>>345みたいなサブスレッドだけ生き続ける設計は個人的に(GCの無い言語では)嫌だ

これらが難しいと思うなら>>342だね。カッコ悪いけど確実かな

350 :デフォルトの名無しさん:2008/12/17(水) 01:53:27
PostThreadMessageは取りこぼしが発生するので使っちゃいけません。
PostMessageを代わりに使おう。

351 :デフォルトの名無しさん:2008/12/20(土) 00:19:42
ところで、ファイバーってどうなん。
アイドル状態のスレッドでパカパカやって動かすとか
スケジュール処理なワーカスレッド代わりとかしか思い浮かばん。

漏れは、スレッドの処理は概ね、待ち処理とか先行処理なので、
あまり使い方が思い浮かばない。

352 :デフォルトの名無しさん:2008/12/20(土) 01:51:56
>>351
ファイバーは移植のためにあるようなもので
新規プロジェクトで使う価値は無に等しい。

353 :デフォルトの名無しさん:2008/12/20(土) 02:10:30
>>352
短絡杉
プリエンプティブであることは必ずしも望ましいことじゃない。
ゲームではファイバーが好まれる。
Larrabeeでもシェーダはファイバーで実装されるそうだ。
マルチコアでハイパフォーマンスだすためにファイーバーは重要。

354 :デフォルトの名無しさん:2008/12/20(土) 02:31:59
自分でコンテキストスイッチとかめんどくせぇぇぇ

355 :デフォルトの名無しさん:2008/12/20(土) 03:01:53
ちまちま排他処理すんのめんどくせぇぇぇ

356 :デフォルトの名無しさん:2008/12/20(土) 12:21:50
>>352、353
マルチスレッドで複数の関数叩くのと、ファイバーを複数キックするのの違いってやっぱ、
同期処理が不必要(他のスレッドでキック中のファイバーは自動的に同期される?)だとか
スタックの制限(ファイバーキックされた段階でスタック指定できる)ですか?
いえ、無論色んな意味合いで違うことは判るけど。



357 :デフォルトの名無しさん:2008/12/20(土) 16:20:24
int result = write( buf, size );
if( result == -1 && errno == EAGAIN ) SwitchNextCoroutine();
I/Oイベントドリブンなスケジューラをみたことある。↑みたいなの。
あとは同期が要らないってのが素晴らしい。


358 :デフォルトの名無しさん:2008/12/20(土) 20:34:51
VisualStudio 2010にはC#のyieldを使ったファイバーもどきライブラリが付いてくるらしいね

http://channel9.msdn.com/posts/Charles/George-Chrysanthakopoulos-CCR-and-DSS-Visual-Toolkit-2008/

359 :デフォルトの名無しさん:2008/12/20(土) 23:50:27
それは歪でいまいちだね〜
まずコルーチンがあって
それにスケジューラを足してファイバー
イテレータ風に味付けしてジェネレータ(C#のyieldのことね)
という階層があるべき姿だと思うな。

360 :デフォルトの名無しさん:2009/01/10(土) 00:18:47
64CPU環境でスレッドを256本生成したときに
struct data[2000];
なんてあって、dataの個々の要素を排他的にアクセスしたい場合
pthread_mutex以外に使えそうな手段ってありますか?

CASってどうやって使うのかよくわからんし助けて



361 :デフォルトの名無しさん:2009/01/10(土) 00:48:43
pthread_mutexでマズい理由は?

362 :デフォルトの名無しさん:2009/01/10(土) 00:58:20
>>361
2000個もpthread_mutex_tって用意して使えるのですかね?

363 :デフォルトの名無しさん:2009/01/10(土) 01:08:25
発想が変?

364 :デフォルトの名無しさん:2009/01/10(土) 01:47:06
mutexを2000個作って問題ないと思うよ。
自分だったら、struct data[200] 全体に対して1個のmutexにして、それ
でパフォーマンスの問題が出たらそのときに対処を考える。
reader-writerロックが使えれば使う。


365 :デフォルトの名無しさん:2009/01/10(土) 01:47:49
訂正。
> 自分だったら、struct data[200] 全体に対して1個のmutexにして、それ
struct data[2000] ね。


366 :デフォルトの名無しさん:2009/01/10(土) 18:28:23
>>362
pthread_mutex_t はただのデータだから、何個作っても
そのプロセスのメモリ以外の資源は使わない

367 :デフォルトの名無しさん:2009/01/11(日) 00:54:05
連結リストをCAS使って実装するときのお手本ってありますか?


368 :デフォルトの名無しさん:2009/01/11(日) 01:04:19
>>367
ttp://www.cs.rochester.edu/u/michael/PODC96.html

369 :デフォルトの名無しさん:2009/01/11(日) 01:14:01
双方向は無いのか........................

370 :デフォルトの名無しさん:2009/01/11(日) 01:50:26
双方向でできると思ってんのかっ

371 :デフォルトの名無しさん:2009/01/19(月) 00:40:02
rw_lockAPIが存在する環境で
同じrw_lock変数を以下のような構造で使うのって
問題ないでしょうか。

func()
{
rw_lock(read)
if 条件{
   rw_lock(write)
rw_unlock(write)
}
rw_unlock(read)
}

372 :デフォルトの名無しさん:2009/01/19(月) 02:34:03
オレオレOSのオレオレrw_lock APIなら大丈夫だけど?

373 :デフォルトの名無しさん:2009/01/19(月) 13:24:35
実装次第だが、普通に考えるとデッドロックするな

374 :デフォルトの名無しさん:2009/01/19(月) 21:32:54
r_lock 確保してるんだから if の中の w_lock が取れないだろjk

375 :デフォルトの名無しさん:2009/01/20(火) 06:28:27
なぜrでロックしないといけないのかわからんけど、条件に関わるのか?

376 :デフォルトの名無しさん:2009/01/20(火) 11:21:30
>>375
このパターン自体は典型的なケースだろ
APIによっては、ReaderとWriterの他に「Writerに変更可能なReader」が用意されていることもある

377 :デフォルトの名無しさん:2009/01/27(火) 16:00:09
WindowsでCreateThread中Cランタイムに含まれる関数を使うとリークを起こすとありますが、
普段からCreateThreadは使わずbeginthreadを使ったほうがいいんですか?
完全にCランタイム使わずってのも面倒だし、内部で使ってる関数があるかもしれない
そういうことまで考えてあえてCreateThreadを使うメリットはあるのでしょうか?

378 :デフォルトの名無しさん:2009/01/27(火) 16:06:34
軽い

379 :デフォルトの名無しさん:2009/01/27(火) 16:14:38
ない

380 :デフォルトの名無しさん:2009/01/27(火) 17:56:15
_beginthreadexでおk

381 :デフォルトの名無しさん:2009/01/28(水) 14:15:26
ないな

382 :デフォルトの名無しさん:2009/02/01(日) 13:59:30
pthreadでmutexで
再起ロックする場合と
依存関係をハッキリさせてスレッドIDとFAST_MUTEXで判別

どっちが高速ですか?

383 :デフォルトの名無しさん:2009/02/01(日) 15:33:29
後者。
以前計測したことがある。

ただし、依存関係の洗い出し作業がとても大変だった。
デッドロックに直結するから、とても気をつけないといけない。

要求性能がシビアだったから後者で仕事のためにやったけど、趣味ならば前者をお薦めする。
排他制御がボトルネックになるようなら、前者で実装すればいい。

俺の場合は、本当に特殊で制限が厳しかったから前者でやっただけ。

384 :デフォルトの名無しさん:2009/02/01(日) 15:35:13
×排他制御がボトルネックになるようなら、前者で実装すればいい。
○排他制御がボトルネックになってから、後者で実装すればいい。

385 :デフォルトの名無しさん:2009/02/01(日) 15:38:02
FAST_MUTEXって何?

386 :383:2009/02/01(日) 16:18:24
色々ぐだぐだだな。
お家で寝たいよ。

387 :デフォルトの名無しさん:2009/02/01(日) 23:25:11
struct hoge{
int var
pthread_mutex_t m;
struct hoge * next;
};

こんな構造体あって


while(h){
pthread_mutex_lock(h->m);
h->var++;
pthread_mutex_unlock(h->m);
h = h->next;
}

こんな風にリンクリストを舐める前後を排他して
舐めていくという処理は正しいでしょうか?

388 :デフォルトの名無しさん:2009/02/01(日) 23:54:31
加算をアトミックにしたいなら正しいんじゃない。

389 :デフォルトの名無しさん:2009/02/02(月) 00:06:27
>>388
では、これもレースコンディション無く
検索可能ですかね?

struct hoge{
int var;
int id;
pthread_mutex_t m;
struct hoge * next;
};

void search(id)
{
while(h){
pthread_mutex_lock(h->m);
if( h->id == id){
h->var++;
pthread_mutex_unlock(h->m);
return;
}
pthread_mutex_unlock(h->m);
h = h->next;
}

}

390 :デフォルトの名無しさん:2009/02/09(月) 14:04:10
shared_ptrで管理するオブジェクトAをスレッドXに渡し、スレッドXからdllを呼んで、dll内でオブジェクトAのメモリを確保する、
ということをしたいのですが、以下のコードでjoin終了時、shared_ptr<A>の解放処理のところで例外が発生します。
どういった理由が考えられるでしょうか?
マルチスレッドでもdllを使わなければ問題なし、dllを使ってもマルチスレッドにしなければ問題なしでした。

struct A {}; // スレッドXにshared_ptrで渡されるデータ
typedef void (__cdecl* DllFunc)(std::tr1::shared_ptr<A>& a); // スレッドから呼ばれるDLL
struct X { // boost::threadに渡すスレッドオブジェクト
std::tr1::shared_ptr<A> a_;
 X(std::tr1::shared_ptr<A> a) : a_(a) {} // DLLに渡すデータ
 void operator()(void) { // スレッド実行時に呼ばれる関数
  HMODULE handle = LoadLibrary(L"dll_func.dll");
  DllFunc dll_func = (DllFunc)GetProcAddress(handle, "dll_func");
  dll_func(a_);
  FreeLibrary(handle);
  c.notify_one();
 }
};
int main(int argc, char** argv) {
 std::tr1::shared_ptr<A> a(new A);
 std::tr1::shared_ptr<X> x(new X(a));
 boost::thread th(*x);
 th.join(); // ここで例外発生
}
<dll_func.cpp>
BOOL WINAPI DllMain (HINSTANCE hinstDll, DWORD fdwReason, LPVOID lpvReserved) { return TRUE; }
extern "C" __declspec(dllexport) void __cdecl dll_func(shared_ptr<A>& a) { a.reset(new A); // これがなければ大丈夫 }



391 :デフォルトの名無しさん:2009/02/09(月) 15:33:18
よりによってここに書くか。すれ違いだWin32スレ行け。
DLLの勉強一からやりなおせ。

最初から全コードのせときゃもっと早く回答ついたんだろうが、ウザイからオシエネ。


392 :デフォルトの名無しさん:2009/02/09(月) 16:58:44
DLL内でnewしたのをEXE内で解放したらエラー出るんじゃない?
そもそもshared_ptrだって内部で参照カウント用にnewしてるからDLLじゃ使えない気がするなー。

393 :392:2009/02/09(月) 17:02:58
スレッドは全然関係ないね。うん。

394 :デフォルトの名無しさん:2009/02/10(火) 05:13:43
>>390
たぶんこれだけで死ねる。
 std::tr1::shared_ptr<A> a(new A);
 X(a)();

395 :デフォルトの名無しさん:2009/02/10(火) 21:54:55
DLLか・・・COMについて調べたほうがいいんじゃないですかね
いろいろヒントあるよ

396 :デフォルトの名無しさん:2009/02/14(土) 15:33:17
shared_ptr使ってるくせにdeleter知らないとか

397 :デフォルトの名無しさん:2009/02/19(木) 23:31:28
>>288
Windows Xp home SP3 で自作のTCPサーバ運用してるけど、インバウンド接続の
同時接続数の制限が10ってことはないよ。
今モニタ見ても20人くらい繋がってる。
p2pがすごい数でつながってるだろうし

この件についてはいろいろなひとがよく確かめずにいろいろ書いてる。
自分でちょっとやってみればすぐわかる。


398 :デフォルトの名無しさん:2009/02/19(木) 23:33:34
>>397
実装はともかくライセンスで制限されてるはず

399 :デフォルトの名無しさん:2009/02/19(木) 23:37:37
そうなんだよね。 使わないでくれという約束で みんな破って使ってるわけだ。

400 :デフォルトの名無しさん:2009/02/19(木) 23:46:20
SQLだったかで試してたときにイベントログに制限されたメッセージが
出たことある。あとShare動かしてる時とか頻繁に出る気がする。
単純にセッションの制限では無かった筈。


401 :デフォルトの名無しさん:2009/02/20(金) 00:12:50
MS製のサーバは独自に制限した実装  IISじゃなくてPWSだっけ
WMEとかはレジストリいじって50人くらいつないだりしてたな。

402 :デフォルトの名無しさん:2009/02/20(金) 02:13:42
それとは別に、セキュリティ的な話で、
SYN_SENTなソケットをシステム全体で
10くらいしか持てないって制限もあったはず。

403 :デフォルトの名無しさん:2009/02/22(日) 19:23:55
初心者な質問ですが、
Thread A        Thread B
for(;;)           for(;;)
printf("AAA\n");    printf("BBB\n");
という処理を行うと、AAA行とBBB行が入り乱れて表示されるんですが、
AABABB\n\n などと表示されることはありえないんでしょうか。

環境はWindows XPで、VC++2008EEでプログラムを書いてます。

404 :デフォルトの名無しさん:2009/02/22(日) 19:36:03
>>403
ここらへんに何か書いてあるんじゃねーの?
http://msdn.microsoft.com/ja-jp/library/172d2hhw.aspx

405 :デフォルトの名無しさん:2009/02/23(月) 04:04:56
>>403
バッファリング

406 :デフォルトの名無しさん:2009/02/23(月) 21:19:24
スレッドに別のスレッドから信号を送って途中で処理をキャンセルしたいのですが、
現状、以下のようにしています。

void run() { // スレッド実行部
 for () { // 長いループ
  ...処理...
  if (check()) return; // 処理をキャンセル
 }
}

check()でキャンセルのフラグをチェックし、このフラグを別のスレッドから書き換えるという方法です。
でもこの方法だとループ内の処理が重くなったときにキャンセル操作に対する反応も遅くなってしまうため
どうしたものかと悩んでます。
スレッド内でタイマーのようなものを発行して、定期的にcancel()のチェックをするといった方法はできないでしょうか?
環境はVC9です。

407 :デフォルトの名無しさん:2009/02/23(月) 22:47:56
>>406
別スレッドから強制停止するとリソースリークの元だよ。
  if (check()) return; // 処理をキャンセル
を重い処理の途中に幾つか入れる方がまし。

408 :406:2009/02/23(月) 23:51:22
>>407
> を重い処理の途中に幾つか入れる方がまし。

どうも。やっぱりこういう単純な方法しかないですか。
重い処理を別スレッドで行わせながら
キャンセル操作の反応がよい安全な方法ってのはないんでしょうか。
cancel()を挿入しまくるというのもなんだかスマートじゃないなぁ・・・。

409 :デフォルトの名無しさん:2009/02/24(火) 00:50:35
非同期に飛ばされるぐらいならコードが汚くなる方が良い


と思うのは俺だけじゃないよな?

410 :デフォルトの名無しさん:2009/02/24(火) 01:12:42
その重い処理ってのがなんなのか
スマートとか言うならその重い処理をスマートに分割すりゃいいじゃない

どうしてもチェックしまくりたくないっていうなら処理を持ってるクラスのインスタンスを急にnullにしてやって
例外捕らえて終了してしまえ、最悪だけど

411 :デフォルトの名無しさん:2009/02/24(火) 01:40:59
別プロセスにして殺すってのは?

結局そういうのって要求されるキャンセル応答時間次第。
人間相手ならmsecオーダでおkでしょ。
きっとループ1回につき1msecもかからないのでは?

412 :デフォルトの名無しさん:2009/02/24(火) 01:51:03
ワーカースレッド2つ以上用意にして
対処すればよくね?

複数個のスレッドでビジー状態になるなら
その処理内容そのものを分割しタスク化した方がいい


413 :デフォルトの名無しさん:2009/02/24(火) 02:50:07
違う質問スレで質問した後でこちらを見つけたので一応こちらでも・・・

CreateThread関数で第三引数をクラスのメンバ関数にしたい場合は
どういう記述をすればいいのか教えてください
よろしくお願いします



414 :468:2009/02/24(火) 02:56:15
>>410
>その重い処理ってのがなんなのか

例えば大きなサイズの行列計算や、待ち行列を使った探索問題なんかを想定しています。
問題を分割することはある程度はできるんですが、それはそれで頑張るとして、
それ以外のアプローチははないかなと。

>>411
> 別プロセスにして殺すってのは?

すみません。よくわかりません。
別プロセスならば殺しても元のプロセスに影響がでないという意味でしょうか。
>>410の後半で言ってることに近い

>>412
> ワーカースレッド2つ以上用意にして 対処すればよくね?

同じスレッドオブジェクトをAとBの2つ用意して、
Aが動いてるときにキャンセルしたときはキャンセルしたふりをして
(Aの計算は次のcancel()チェックまで続いてる)、
新規の呼び出しがあったときはBを動かすというイメージですか?これはいけるかも…。



415 :468:2009/02/24(火) 02:58:01
一部修正

>>410の後半で言ってることに近い
 ↓
>>410の後半で言ってることに近いですか?



416 :デフォルトの名無しさん:2009/02/24(火) 07:10:44
>>413
コールバック関数にはstaticなメンバ関数(クラスメソッド)しか使えない。
コールバック関数を使うAPIは大抵ポインタ型の引数を渡せるから、
クラスを使いたいときはそこにthisポインタを渡して使う。

417 :デフォルトの名無しさん:2009/02/24(火) 08:52:04
>>413
できない
普通の関数作ってその中で呼び出す

418 :デフォルトの名無しさん:2009/02/24(火) 16:53:09
>>416‐417
ありがとうございます
とりあえず、>>417の方法でやってみます

419 :デフォルトの名無しさん:2009/02/24(火) 20:52:23
>>414
別プロセスにすると、ターミネートしたときのリソースの開放をOSがやってくれる
ってことではあるまいか。
それはともかく、その長い処理がうまく分割できず、どうしても時間がかかる場合は
汎的には、キャンセルボタンの入力を取得する側(フラグを立てる側ね)で、キャンセルが
押されたからしばらく待てっていうサインをユーザーに与える方が重要な希ガス。

420 :デフォルトの名無しさん:2009/02/24(火) 21:45:33
別プロセスのほうがクリーンアップの点では簡単&安心だなあ

ただ、多くの情報を受け渡したり、途中で通信が必要だったりすると
しんどいけどな

421 :デフォルトの名無しさん:2009/02/24(火) 23:05:03
しんどいと言うか、性能の問題がでるかも

422 :406:2009/02/25(水) 00:45:53
>>419-
なるほど。別プロセスにすることも検討できそうです。
なんとなく雰囲気は分かりました。どうもありがとう。

423 :デフォルトの名無しさん:2009/02/25(水) 18:38:04
処理毎に別プロセスって、昔の業務アプリみたいだな。っていうか、
今でもVBあたりでそんな開発やってそう。

1画面=1exeファイルで、画面間はsystem()でプロセス呼び出し。
画面フォーム上で入力したデータ等は、ファイルに書き出して渡す。

大抵、exeファイルの名前は全部数字と意味不明なアルファベットで、
メモリ食いまくりで、やたらに遅い。(w

424 :デフォルトの名無しさん:2009/02/25(水) 19:28:47
大規模なアプリはマルチプロセスの方が開発しやすいね
Windowsの場合は性能的にマルチタスクに向かないけど

425 :デフォルトの名無しさん:2009/02/25(水) 21:04:19
>>423
unixだとマルチプロセスは多いけどな。

VB6のアプリだとそういう作りになるのは仕方ない。
モジュール分割の手段がCOMしかない。
20画面もあるとロードモジュールが10M超える。
IDEに読み込んだりコンパイルするのにも一苦労。
プロセス間でDBのセッションを引き継げたらマルチプロセスでも軽くなるはずなのだけど、
それも出来ないからDBの接続でどうしても画面遷移が重くなってしまう。

426 :425:2009/02/26(木) 01:19:09
>>424
マルチスレッドは、スレッド間のメモリ保護機構がないので、他スレッド
による破壊のリスクと引き換えに、高速なデータ共有が可能と思うが?
Windowsがマルチタスクに向かないとか、何を根拠に?

>>425
昔はメインメモリが少なく高価だったという事情もあるし、「unixだと」
という括りはどうかな?

20画面なんて、そんなに大きな規模なプログラムじゃないよね?その程度
の規模で単純にVBのソースだけなら、10MBを超えるようなことはないの
では?

確かにVB6当時のハード環境(Pentium 300MHz〜1GHz, メモリ64MB程度?)
でのビルドは遅かったかもしれないが、VBはVCよりは速かった様に記憶
しているけど?

それと、プロセス間でDBのセッションを引き継げないのは、VBや、Windows
に限定された話ではないのでは?

極端に処理が遅い業務アプリは、データベースの設計自体に問題があり、
無駄にDB間でレコードをコピーしたり、テーブルのリンクが必要だったり
ということが多い気がする。

427 :デフォルトの名無しさん:2009/02/26(木) 01:55:03
プロセス間のデータ共有なら共有メモリがあるよ
特に親子関係があれば、mmap ANON とかでお手軽極楽

スレッドのメリットは(スレッド間なら)高速にディスパッチ出来る点だね
heap だろうとなんだろうとメモリは全部共有されるというのは
メリットでもあるけど、デメリットでもあるかな。
バグの原因になりがちだよね


428 :デフォルトの名無しさん:2009/02/26(木) 03:45:35
構造化されたデータを別プロセスと共有メモリ経由でやりとりするとして

c構造体ならまあなんとかなるんだが(いやそれでも大変だが)
c++クラスだとすんごいやりにくい

何かウマい方法あります?

受け渡し用にクラス作るのもアホらしいし・・・
変態的テンプレートでなんとかなるもんだろうか

それとも単なる通信バッファとしてしか使わない?

429 :デフォルトの名無しさん:2009/02/26(木) 03:52:42
C++ならCの構造体も使えるんじゃ…。

430 :デフォルトの名無しさん:2009/02/26(木) 04:07:16
そういうのはソケット使って単純化してる。
プロセス間共有メモリは後で環境や仕様が変わったときに
変更が大変だし流用も難しい。バグも入りやすい。
パフォーマンスを上げたいとか、よっぽどの理由でも
ない限り使われないんじゃないかな。
スレッドと違って>>428の言うデメリットもあるし。
ウマい方法はありません。

431 :デフォルトの名無しさん:2009/02/26(木) 04:53:41
>>426
酷いミスリードだな。>424はマルチプロセスによるマルチタスクという技法がWindows向けでないと言っているように見えるが。

432 :デフォルトの名無しさん:2009/02/26(木) 04:59:25
IE8はマルチプロセスですぜ

433 :デフォルトの名無しさん:2009/02/26(木) 05:49:22
>>426
お前は誰なんだ

434 :デフォルトの名無しさん:2009/02/26(木) 06:45:39
unixといえば今でもパイプをfork/execで分け合ってというイメージが強いな。
DBのコネクションは知らないがファイルハンドルならプロセス間で受け渡せる。
Windowsにもハンドルを複製して子プロセスに渡すオプションはあるのだが、
OS/2やNTは最初からスレッドをサポートしてたのであまり使われない。

435 :426:2009/02/26(木) 17:42:01
>>425
ハンドルの複製に失敗しますた。orz 426=423です。

>>431
未だにWindowsがunixに劣っていると思っている原理主義者か、TRON房かも。
何を以ってunixを定義しているのか聞いてみたい。

>>434
ハンドルをコピーしたりは、MS-DOSにもあったかな。INT 28Hだか忘れたけど、
プリンタスプーラ用の割込使えば、一応擬似マルチタスクで一部のシステム
コールを呼べた。

デュアルコアやクァッドコアのCPUだと、マルチスレッド化すると理論上
2倍や4倍で動くと勘違いしているヤツもたまにいるよね。おまえのOSは
いったいいくつプロセスが動いていると思っているんだと、小一時間。(略

436 :デフォルトの名無しさん:2009/02/26(木) 18:11:07
WindowsがUNIXより優れてると思い込んでるなら
まずはその幻想をぶち壊す!

437 :デフォルトの名無しさん:2009/02/26(木) 18:40:58
>>436
上条さん乙。
つか、んな事誰も言ってないから。

438 :デフォルトの名無しさん:2009/02/26(木) 23:22:19
マルチスレッドスレでマルチプロセス云々言ってる時に何の前提もなく
「マルチタスク」なんて言う奴は普通にスルーでいいと思うんだけど...

439 :デフォルトの名無しさん:2009/02/26(木) 23:47:59
よ〜し、おじさんもマルチプログラミングとかタイムシェアリングとかの古語を持ち出しちゃうぞ。

440 :デフォルトの名無しさん:2009/02/26(木) 23:51:02
>>435
実質、4coreXeonのシステムだとOpenMPで4スレッドにして3.9倍速くなるけどね。
逆に、>435のCPUはOSをアイドル状態で動かすだけでどんだけ負荷喰ってるんだって話だな。

441 :426:2009/02/27(金) 10:22:04
>>440
スレッドでどんなコードを走らせているか知らないけど、スレッド内で
アクセスするデータもコードも、CPU内のキャッシュに収まるくらい
小さなプログラムでもない限り、そういう結果はまずありえないと思うな。

それとも脳内キャッシュ?

442 :426:2009/02/27(金) 10:43:15
非同期I/Oを使わずスレッド内でファイルI/O待ちしているとか、ネット
ワーク物理層の帯域幅に比べて通信速度が遅く、スレッド化でマルチ
セッション化できるといった、ある意味冗長な造りのプログラムなら
ありえるね。

OSのアイドル状態を持ち出すあたり、他に何個のプロセスがいつ走って
いるか考えていないのかな?(w

443 :デフォルトの名無しさん:2009/02/27(金) 10:43:58
>>441
OpenMP知らないなら黙っていた方がいいと思うよ。

444 :デフォルトの名無しさん:2009/02/27(金) 10:45:51
>>443
3.9倍早くなるって
作ったプログラム全体?それとも特定の処理に
限定された内容?どっちなの?

445 :443:2009/02/27(金) 11:04:31
>>444
私に聞くなw
恐らく演算に集中している部分じゃないの?
MKLなんかは大き目のデータのFFTでそれくらいのリニアリティを叩き出すから。

446 :デフォルトの名無しさん:2009/02/27(金) 13:15:48
embarrassingly parallel なワークロードならそれくらい行ってもおかしくない

でも大抵の処理は並列化不可能な部分が無視できない量存在してて、
アムダールの法則でもって高速化の限界が簡単に見えてしまうと思うよ

447 :デフォルトの名無しさん:2009/02/27(金) 13:58:29
>>436
コンシューマー相手のソフトウェアのパッケージ販売の観点からは
明らかに優れている。全然スレ違いだが。

448 :デフォルトの名無しさん:2009/02/27(金) 19:47:19
>>443
OpenMP に期待しすぎ。

何でもかんでも 3.9倍になる魔法なら俺も欲しいが。(w

449 :デフォルトの名無しさん:2009/02/28(土) 02:39:25
>デュアルコアやクァッドコアのCPUだと、マルチスレッド化すると理論上
>2倍や4倍で動くと勘違いしているヤツもたまにいるよね。おまえのOSは
>いったいいくつプロセスが動いていると思っているんだと、小一時間。(略

略とか言われても。誰か解読してあげてよ。
少なくとも実測で3.9倍でてるわけだから、理論上は4倍出ると言っても問題ないよな。
たくさんのプロセスが動いてるとき、マルチコアだとちゃんと速くなるよな。
意味不明。

450 :デフォルトの名無しさん:2009/02/28(土) 03:13:14
どういう問題を解いて3.9倍なのか書かないと意味がないかと。

知人の計算屋さんがAMDの8CPU機にメモリしこたま積んで
巨大グラフを相手にした問題を解いていたことがありましたが、
問題の構造上メモリアクセスに局所性が全くないのでCPUの
速度や数以前にメモリ帯域が飽和して速度が頭打ちになると
ぼやいていた事が。

451 :デフォルトの名無しさん:2009/02/28(土) 14:17:04
>>450
まあその辺に桁違いのコストを掛けてクリアしてることが
スパコンの存在意義だしね


452 :443:2009/02/28(土) 16:53:30
>>448
期待するも何も、実験した結果だし。

>>450
>445に書いた通り、只管FFTを計算するようなプログラムと言うくらい。

その結果では、4core2cpuのシステムで、4並列まではびっくりするほどリニアリティがあるけど、
その先は一つ増やしても0.7個分くらいしかパフォーマンスが上がらなかった記憶が。
# 8並列で7倍くらいかな? 必要なら記録を探してくるけど。

尤も、自作のプログラムだと4並列でも8並列でも殆ど変わらなくて泣けた罠。
インテル某氏の話だと、MKLはOpenMPで並列化してもリニアリティを確保できるように
作られているそうで、折角FFTを使わない版を作ったのにお蔵入りになりそうだったり。

453 :デフォルトの名無しさん:2009/02/28(土) 16:55:08
スパコンと言えばTOP500で10位にWin鯖クラスタが付けてたけど
(CPUとメモリだけ)似たような構成の他のと比べて特に劣ってるようでも秀でてるようでもなかった

454 :デフォルトの名無しさん:2009/02/28(土) 18:46:09
>>452
OpenMP に頼って満足してる人はこのスレに用はないでしょ。
どうぞお引取りください。

455 :デフォルトの名無しさん:2009/02/28(土) 19:01:43
>>454
>452じゃないけどここはマルチスレッド全般でしょ?
>1にも「OS・言語・環境は問わない」って書いてるんだからいいと思うけど
ただし>452=443=440はおバカさんだと思うけどねw

456 :デフォルトの名無しさん:2009/02/28(土) 21:22:08
OpenMP の話題がまずいと言ってるわけじゃなくて、「OpenMP
に頼って満足してる人」って書いてあるんだが...。

スレタイに「相談室」って書いてあるのが見えませんか?

457 :デフォルトの名無しさん:2009/02/28(土) 21:41:20
>>456
相談した人にOpenMPに頼って満足してるってレスするのは問題ないだろ

458 :デフォルトの名無しさん:2009/02/28(土) 22:04:33
で、どこに相談した人がいるんだ? (w

459 :デフォルトの名無しさん:2009/02/28(土) 22:09:48
俺は>452個人の話はしてないんだが。お前誰と闘ってるんだ?

460 :452:2009/02/28(土) 22:13:07
まぁ、私は「OpenMPに頼って満足してる」のではなく、「OpenMPを巧く使うMKLに勝てなくて泣いてる」のだけれどねw

461 :デフォルトの名無しさん:2009/02/28(土) 22:13:48
よくわからないけど、置いときますね。
#light
open System.Threading
let tid = fun () -> Thread.CurrentThread.ManagedThreadId
let sleep = fun (t:int) -> System.Threading.Thread.Sleep t
let x1() = [|1..100|] |> Array.map(fun x -> sleep(100); [|x ; tid()|])
let x2 = [|1..100|] |> Array.map(fun x -> async { sleep(100); return [|x ; tid()|] } ) |> Async.Parallel
let _ = printfn "%A" (x1()); printfn "%A" (Async.Run x2)


462 :デフォルトの名無しさん:2009/02/28(土) 22:35:01
>>450
おれは、>>452 個人の話をしてるんですけど。

まさか、>>454 に書いてあるアンカーすら見えなくなるほど
頭に血が上ってるとか? (w

463 :デフォルトの名無しさん:2009/02/28(土) 22:48:56
>>462
俺は「OpenMPに頼って満足してる」のを理由に追い出そうとしたことに
ついて話をしている。>>452個人のことはどうでもいい。
どうやらただの煽りあいになりそうだからこの話題は終了する。

464 :デフォルトの名無しさん:2009/03/01(日) 02:32:16
>>460
何故勝てなくて泣く必要があるのか少し気になる。

465 :デフォルトの名無しさん:2009/03/01(日) 16:47:46
>>463
「相談した人もいないのに勝手に OpenMP に頼って満足してる人」は
このスレに用はないでしょ。

これでいいか?

> >>452個人のことはどうでもいい。

# >>452 にレスしてるのに、勝手に割り込んできて逆切れかよ...

466 :デフォルトの名無しさん:2009/03/01(日) 18:49:02
OpenMPってどんなの?たとえば、Videoのエンコード・デコード
処理が書いてある逐次処理のCなりC++のソースコードが
あったら、ほとんど変更なしに並列化できるん?

それとも、既存のソースは一から書き直しくらいしないと
パフォーマンスは出ない?

467 :デフォルトの名無しさん:2009/03/01(日) 18:53:11
相談者が現れたので>>452の出番ですwww

468 :デフォルトの名無しさん:2009/03/01(日) 18:55:20
それ以前に446にふさわしい言葉は「ググれカス」だろう。

469 :デフォルトの名無しさん:2009/03/01(日) 19:14:45
>>466
OpenMPスレという物もあってだな(ry

470 :デフォルトの名無しさん:2009/03/02(月) 02:02:51
OpenMP詳細しらんが、既存のソースは1から書き直しまで
いかなくても、大幅に書き直さないとパフォーマンスは
でないのだろうな。常識的に考えて。

コア数に応じてリニアにパフォーマンスがあがって、既存
のソースから簡単に移行できますよ、っつーなら神なのだが。

471 :デフォルトの名無しさん:2009/03/02(月) 02:35:03
それを可能にするには関数型など副作用のない言語が有利
今更言うことでもないが

472 :デフォルトの名無しさん:2009/03/02(月) 02:38:08
>>471
んなこたーわかってんだよ。新規にはじめる分野はそれでもえーよ。
資産の移行も重要なんだよ。

473 :デフォルトの名無しさん:2009/03/02(月) 02:42:00
おまえの書いたコードなんぞ資産と呼ぶ価値も移行する価値も無いから気にすんな

474 :デフォルトの名無しさん:2009/03/02(月) 02:46:42
>>473
俺の書いたコードが資産だなんて、いついったんだよ?
煽るにしろ、頭の悪さが透けてるんだよ。

475 :デフォルトの名無しさん:2009/03/02(月) 03:08:36
>>472の「おまえ」が>>474だなんて、いついったんだよ?
煽るにしろ、頭の悪さが透けてるんだよ。

476 :デフォルトの名無しさん:2009/03/02(月) 11:59:03
これは惨めなミス。

477 :デフォルトの名無しさん:2009/03/02(月) 13:39:15
>デュアルコアやクァッドコアのCPUだと、マルチスレッド化すると理論上
>2倍や4倍で動くと勘違いしているヤツもたまにいるよね。おまえのOSは
>いったいいくつプロセスが動いていると思っているんだと、小一時間。(略

478 :デフォルトの名無しさん:2009/03/02(月) 23:44:21
>>477
こいつの言ってることまじでわからんのだが・・・。
こいつがアフォなのか、俺がアフォなのか誰か解説よろしく!

479 :デフォルトの名無しさん:2009/03/03(火) 00:03:02
コア1 ●◎◎◎◎◎◎◎◎◎
コア2 ●○○○○○○○○○
コア3 ●○○○○○○○○○
コア4 ●○○○○○○○○○

         ↓

コア1 ●◎◎◎◎◎◎◎◎◎
コア2 ●◎◎◎◎◎◎◎◎◎
コア3 ●◎◎◎◎◎◎◎◎◎
コア4 ●◎◎◎◎◎◎◎◎◎

○ 空き
● 別プロセス
◎ 自プロセス

4倍になる

480 :デフォルトの名無しさん:2009/03/03(火) 00:28:55
>>477
基本的には>>477がちょっとずれていると思う。
コア数に比例してリニアに2倍4倍にならないのは事実。
でもハウスキーピングなプロセスの数云々は性能を押し下げる
理由としてはどちらかというとマイナーな部類だと思う。

481 :デフォルトの名無しさん:2009/03/03(火) 00:29:19
ちょっとゲロでちゃった

482 :デフォルトの名無しさん:2009/03/03(火) 00:35:18
並列化効率の話がまず最初だよね。
アムダールの法則。

483 :デフォルトの名無しさん:2009/03/03(火) 00:38:03
>>480
いや、こうまで単純化していいかどうかわからんが、
ハウスキーピングのプロセスがほぼsleep状態と
仮定したら無視できるわけで。

というより、4コア100%使用する処理走らせるんだったら、
無視できるほどなわけで(スワップデーモンとか
ハードアクセスの重いスレッドが走らない前提なら)。

バスネックでリニアに伸びないとか、キャッシュの競合
だとかいうならまだしも。やっぱり俺には>>477はさっぱ
りわからん。

484 :デフォルトの名無しさん:2009/03/03(火) 01:50:33
アイドル状態のプロセスでもビジーループでCPU消費してる
とか思ってんじゃないの

485 :デフォルトの名無しさん:2009/03/03(火) 01:56:06
>>484
単に1つのプロセスが1コアを占有し続けると考えているのではあるまいか。

486 :デフォルトの名無しさん:2009/03/14(土) 05:22:42
マルチスレッドについて質問です。
環境は VC++2005 SDK です。

子ウィンドウの WM_CREATE にて無限ループをさせても
親ウィンドウが操作できる
事を実現したいです。

他スレにて、
>Windowsのウィンドウはスレッドに属する。
>ウィンドウプロシージャはウィンドウの属するスレッドで実行される。
>さて、どのスレッドに属するかというと、CreateWindow(Ex)を呼んだスレッド。
というレスをいただき、新しいスレッドにてCreateWindow する手段を取りました。
子ウィンドウの WM_CREATE までは処理が進むのですが、
無限ループどころか for (i=0; i<100; i++) { i = i; } を WM_CREATE 内に
記述した途端にフリーズする様になってしまいました。
コメントアウトすれば、問題なく動作します。

ファイルをアップロードしたので、見ていただけないでしょうか?
ttp://www3.uploda.org/uporg0077.cpp.html
受信パスは test です。
どのように修正すれば良いか、ご教授願います。
よろしくお願いします。

487 :デフォルトの名無しさん:2009/03/14(土) 05:54:15
>>486
windowsのウィンドは、プライマリスレッドで生成しないと
いろいろいろいろいろいろいろいろトラブルが起こるので、そういう設計は見直した方がいい。
そもそも子ウィンドウは親ウィンドウと同じスレッドで生成しないとトラブルになる。

例えば親をAスレッドが、子をBスレッドが作ったりすると、
親のプロシージャはAスレッドが実行し、子のプロシージャはBスレッドが実行することになる。
子から親への通知や親から子への通知がメッセージで発生したら発生したら、
デッドロックの宝庫になることは想像に難くない。

それ以前にメッセージループって親子で共通のような気が・・・

488 :デフォルトの名無しさん:2009/03/14(土) 06:05:38
>>486
アップロードしたプログラムだとそもそも子ウインドウは表示されないだろ。

動くようにするには子ウインドウと呼んでいるものを、新しいスレッドのウインドウにすること。
つまりメッセージループをそこでまわす。

MSG msg;
ShowWindow(hChild, SW_SHOWDEFAULT);
UpdateWindow(hChild);
while(GetMessage(&msg, NULL, 0, 0)) {
 TranslateMessage(&msg);
 DispatchMessage(&msg);
}
//static int k = 0;
//k = 1;
//while (1)
//  k++;


489 :デフォルトの名無しさん:2009/03/14(土) 06:16:38
WM_CREATEで無限ループしたらCreateWindowから制御が戻らないわけだが

490 :486:2009/03/14(土) 15:00:34
>>487
色々と問題があるという事ですか...
そこまでは考えておりませんでした。
ですが、今はこの枠組みで作ろうと思います。
アドバイスありがとうございます。

>>488
メッセージのループを回すのを忘れておりました。
ありがとうございます。
ただ、今回はメッセージのループのみが欲しいので
ウィンドウは非常時で構いません。

>>489
確かにそうでした。
あるメッセージを受けた時に
その中で Sleep(1000); を実行する事にしました。

・・・が、それでも親ウィンドウが 1000 ミリ秒 固まってしまいました。

以下の様にしておりますが、
これでは各ウィンドウは別スレッドで動かないのでしょうか?
ttp://www2.uploda.org/uporg2088151.cpp.html
受信パスは test です。
よろしくお願いします。

491 :デフォルトの名無しさん:2009/03/14(土) 15:07:12
作ろうと思います、じゃねー
動作が未定義なんだからそんなプログラミングすんな

492 :デフォルトの名無しさん:2009/03/14(土) 15:18:07
>>491
互いのウィンドウでメッセージのやり取りを頻繁にするような事は致しません。
親スレッドとは独立したウィンドウプロシージャのメッセージループ
(表現が合っているかは自信がありませんが)が欲しいのです。

以下、長文失礼します。

5 [msec] の情報が入るサイズのバッファを複数用意し
信号をバッファに入力し、あるバッファが満タンになったら
windows からメッセージが投げられ、
受け取ったメッセージ内で信号処理をする、
というものを作っています。
この時、信号処理に時間がかかるため
常にメッセージを受け取った時の処理を行ってしまい
メニュー操作が出来なくなる状態です。

アプリケーションを強制終了すると、信号処理した数値列が
ちゃんとファイル出力されているので
信号の入力及び信号処理は問題なく進んでいます。

これを解決するにはメニューを持つウィンドウと
メッセージループのあるウィンドウを別スレッドで走らせれば良い
と考えました。


493 :492:2009/03/14(土) 15:53:32
連稿失礼します。
Sleep(1000); を

int i, j;
for (i=0, j=0; i<1000000000; i++)
j++;

としてみましたが、結果は同じでした。
親ウィンドウのスレッドにフォーカスが戻っていないのでしょうか?

494 :デフォルトの名無しさん:2009/03/14(土) 16:43:47
子ウィンドウ作る必要なんて無いところを、
わざわざ回りくどいやり方しているようにしか思えないんだけど。
ワーカースレッドにデータ送りたいだけじゃないの?

495 :デフォルトの名無しさん:2009/03/14(土) 18:10:18
>>494
ワーカースレッドについて知識が無かったのでググってみました。
MFCでのみ使用可能な関数でしか作れない事が判りました。
今はSDKで組んでおり、MFCは使った事が無いので今の私には使えそうにありません。
情報ありがとうございました。

496 :デフォルトの名無しさん:2009/03/14(土) 18:28:36
>>495
ワーカースレッドは概念であって、SDKのみだから作れないということは無いよ

そもそも、貴方のやろうとしていること自体がワーカースレッドの利用だ

497 :デフォルトの名無しさん:2009/03/15(日) 15:23:44
>>496
ワーカースレッドについて調べ方が間違っていたようです。
もっと調べを進めます。ありがとうございます。

498 :デフォルトの名無しさん:2009/03/15(日) 20:09:14
>>492
ワーカースレッドというのは、作業を行うスレッドという程度の意味です。
信号処理中はGUIが不要のようですので、GUIは1個のスレッドにまとめて下さい。
以下、基本は次のような処理になります。Q0とQ1のアクセスを排他制御して下さい。
プライマリスレッド
  メインウィンドウの作成。
  バッファ群を作成する。例えば5ms用のバッファをN個作成して、
  2個のキューQ0(未使用バッファ用)とQ1(充填済みバッファ用)を作成する
  バッファを全てQ0に格納し、スレッドA・Bを作成・実行する。
  以降はGUIによるスレッドA・Bのコントロールを行う

スレッドA(バッファ充填処理)
  1.信号受信処理の初期化
  2.Q0からバッファを取り出す。無ければ待つ。
  3.バッファを充填する処理(この辺で外部からのスレッド終了通知チェック)
  4.バッファが一杯になったらQ1へ入れ、2へ戻る
  
スレッドB(信号処理スレッド)
  #スレッドAで、Q1の格納数が0->1になったとき起こされる。
  1.Q1からバッファを取り出す(なければ待つ)
  2.信号処理(この辺で外部からのスレッド終了通知チェック)
  3.結果の出力
  4.バッファをQ0へ入れ、1へ戻る

499 :デフォルトの名無しさん:2009/03/15(日) 20:18:36
>>498
あー便所で説明してくれないと解らない

500 :デフォルトの名無しさん:2009/03/15(日) 20:42:55
>>499
ウホッいい男!

501 :492:2009/03/15(日) 20:45:19
>>498
詳しい構成、本当にありがとうございます。
頑張って理解してみます。

502 :デフォルトの名無しさん:2009/03/27(金) 03:19:19
void A::sync_fun() {
  boost::mutex::scoped_lock lock(m_);
  // 何かの処理
}

上のlockで待機しているスレッドがあるときにAのオブジェクトをdeleteするとスレッドは待機したままですね。
下のようにするかtimed_waitにする必要があるのか、そこまで気にすることもないのか。
みなさんはどうされますか?

void A::sync_fun() {
  boost::mutex::scoped_lock lock(m_);
  cond_.wait(lock, bind(&A::pred, this));
  if (invalid_) return;
  // 何かの処理
}

bool A::pred() const { return stat_ || invalid_; }

A::~A() throw() {
  {
    boost::mutex::scoped_lock lock(m_);
    invalid_ = true;
  }

  cond_.notify_all();
}


503 :デフォルトの名無しさん:2009/03/28(土) 18:55:17
>>502
どうするかは、何のクラスかによるだろう。
一般論でAが、sync_fun()実行中に破棄される可能性があって、
どうしても回避できないならAのデストラクタでunlockする。

504 :デフォルトの名無しさん:2009/04/04(土) 16:12:48
ダウンローダをマルチスレッドで作成しようと思っているのですが
スレッドを10個作り
それぞれにURLを追加して、次々にダウンロードさせる仕様にしようかと思っていますが
このスレッドの終了タイミングはどういった条件で終了すればいいでしょうか?

メインスレッドが終了するとこの10個のスレッドも終了するので
どうしたものかと考えています

505 :デフォルトの名無しさん:2009/04/04(土) 16:19:45
あげます
すいません

506 :デフォルトの名無しさん:2009/04/04(土) 16:20:37
.

507 :デフォルトの名無しさん:2009/04/04(土) 16:36:26
>>504
何を聞きたいのかよく分からんけど、
メインスレッドで10個のスレッドの
終了待ちさせれば良いんでないの。

508 :デフォルトの名無しさん:2009/04/04(土) 16:45:56
>>507
なるほど
そういう手がありましたか
ありがとうございました

509 :デフォルトの名無しさん:2009/04/04(土) 17:26:41
何か一冊マルチスレッドの本読むのおすすめする

510 :デフォルトの名無しさん:2009/04/05(日) 04:12:53
class Hoge{
public:
 void End(){
 /*他のスレッド、シグナルハンドラとかから呼ばれる */
 Lock_.GetLock(); // 実際はRAII使ってるよ
 continuable_ = false;
 //その他のリソース会報処理
 }

 void Task(){
 // thread poolから実行されるタスク。
 Lock_.GetLock();
 if( continuable_ == false ){ return; }
 // IO処理とか色々非同期でやる
 }
};

なんか、フラグ使ってやるのが嫌なんだけど、
非同期で実行されるオペレーションをキャンセルさせる
スマートな方法ってない他にない?
この実装は間違ってる?

511 :デフォルトの名無しさん:2009/04/05(日) 11:59:52
いいんじゃねえの。
スレッドを自発的に終了させるには
スレッド自身が何かをチェックしなけりゃならんし。

512 :デフォルトの名無しさん:2009/04/05(日) 13:17:02
間違ってないし、フラグを使う方法は普通によくある

513 :デフォルトの名無しさん:2009/04/05(日) 19:31:13
別プロセスにしてkill -9、これが最強。

514 :デフォルトの名無しさん:2009/04/05(日) 19:36:59
せめてSIGTERMでやんわり殺してやれよ。

515 :デフォルトの名無しさん:2009/04/06(月) 12:50:48
そうそう、せめて覚悟する時間くらいは与えてあげないと。
尤も、そうすると逆切れして殺しに来るかも試練が。

516 :デフォルトの名無しさん:2009/04/09(木) 00:33:31
変数か構造体かクラスのインスタンスa,b,c,dがあるとして、
まず、スレッド1がaとbを使用、スレッド2がc,dを使用する。
その後、スレッド間通信とかでスレッド1も2も上のa,b,c,dを使用した処理が完了したことをスレッド1,2に伝える。
そして、スレッド1がa,cを使用、スレッド2がb,dを使用する。
といったような処理をするときに、特別にロックとか必要ですか。

517 :デフォルトの名無しさん:2009/04/09(木) 00:58:51
>その後、スレッド間通信とかでスレッド1も2も上のa,b,c,dを使用した処理が完了したことをスレッド1,2に伝える。
これで同期取ってるから、そこをちゃんとすればよい。

518 :デフォルトの名無しさん:2009/04/09(木) 01:47:33
弱い順序付けの場合だめな場合がありえるかもね

519 :デフォルトの名無しさん:2009/04/09(木) 17:49:21
ねーよw

520 :デフォルトの名無しさん:2009/04/09(木) 19:12:35
>>518
お前にとって同期ってなんだ?

521 :デフォルトの名無しさん:2009/04/09(木) 19:52:20
グローバル変数keyに対して、他のスレッドで値を変更してループの続行、終了を決める場合に
while ( key ){ count++; }
というコード書くとコンパイラの最適化によって、無限ループになる可能性があるということですが、
while ( *pk ){ count++; }
のようにアドレスから参照しようとしても同じことになるのでしょうか。

522 :デフォルトの名無しさん:2009/04/09(木) 20:54:12
わかんない。

つーか key を volatile にすりゃいいんでない?

523 :デフォルトの名無しさん:2009/04/09(木) 21:01:11
>>521
うん。十分ありえる。

524 :デフォルトの名無しさん:2009/04/09(木) 21:07:43
volatileで大丈夫そうですね。ありがとうございました。

525 :デフォルトの名無しさん:2009/04/12(日) 11:51:26
マルチスレッドがどういうタイミングで割り込まれるのかわからないのですが
たとえば、if(++i == n) のコードなら
iをインクリメントしてからnを比較するまでの間で
割り込まれる可能性はあるんでしょうか?

526 :デフォルトの名無しさん:2009/04/12(日) 12:30:10
あるよ
そもそも正しくインクリメントされることも保証されない
(CPUやコンパイル出力によるけど)

なぜなら、
(1) メモリからiの値を読み出す
(2) 値+1を計算する
(3) iの領域に計算結果を書き込む
という3ステップになる可能性があるから

527 :デフォルトの名無しさん:2009/04/12(日) 12:43:39
>>526
そのステップ間で割り込まれるんですか、結構分割されるものなんですね
ありがとうございました

528 :デフォルトの名無しさん:2009/04/12(日) 14:33:39
>>527
ただし、いつもそのように分割されるとは限らない。

529 :デフォルトの名無しさん:2009/04/13(月) 22:54:34
volatile最強杉www

530 :デフォルトの名無しさん:2009/04/14(火) 10:18:14
fread等でのデータ読み込みをシングルスレッドで実行する場合と
マルチスレッドで実行し、メインスレッドでは出来るだけ何もしない場合の速度は同程度になるものでしょうか?

531 :デフォルトの名無しさん:2009/04/14(火) 10:27:26
>>530
速度は実測が基本。

たぶんその比較内容だと、激しく環境(ハードウェア、OS、コンパイラ)に依存する。

532 :530:2009/04/14(火) 10:57:26
WindowsXP、vc2003、C2D E7200です。
timeGetTimeで測定した所、
マルチスレッド側の速度が安定しないのですが、
100kb程度のデータで2倍、1mb程度だと4割程度の速度差になりました

メインスレッドは以下のようなループになっていています
while(1){
 if(PeekMessage(&msg,0,0,0,PM_NOREMOVE)){
  TranslateMessage(&msg);
  DispatchMessage(&msg);
 } else {
  // メインスレッド

 }
}

533 :デフォルトの名無しさん:2009/04/14(火) 11:00:25
色々条件がよく判らんが、ここが一番判らん。
>100kb程度のデータで2倍、1mb程度だと4割程度の速度差になりました
2倍の速度差と4割の速度差ってどういう意味なんだか。
シングルスレッドに対してマルチスレッド版は2倍の速度差、つまり3倍所要時間が掛かったのか?

534 :530:2009/04/14(火) 11:11:23
すみません、
所要時間
    シングル マルチ
100kb 0.013秒  0.025秒
1mb  0.100秒  0.140秒

です

535 :デフォルトの名無しさん:2009/04/14(火) 11:17:22
>>530
マルチスレッドは、複数のことを同時にしたいときに使う技術なので、
そういう視点で選択した方がいいですよ。

ただ速度といっても、プライマリスレッドからストレージアクセスを
しているときキャンセルボタンを押したいんだけどその反応が鈍い、とか、
ストレージをアクセスしながらムービーを表示しているのだけれどコマ落ちする、とか、
単純コピーを速くしたい、では、とるべき手段に違いがありすぎます。

単にあるデータをストレージから読み込む処理だけに着目するなら、シンプルな
シングルスレッドの方が高速になることが多いと思います。
予め別のスレッドで利用するファイルを予測してアクセスし、キャッシュに入れておく
などというのはまた別の問題ですが。

536 :530:2009/04/14(火) 11:33:30
>>535
ありがとうございます
極力シングルで動作できるような方法考えることにします

537 :デフォルトの名無しさん:2009/04/19(日) 14:10:04
>>435
Phenomの2コアで2スレッド動かしたら2.2倍以上のスコアを叩き出した。
確かに2倍になる訳じゃないね。但し、配列をL2とL3に合わせて巧く分割
できた場合に限るけど。あと、OSのや他プロセスのボトルネックがある分
やっぱりマルチコアの方が早いね。実質90%でしか動けないシングルは倍
にしても180%だけど、90%+100%で動けるマルチコアだと実質190%で10%
ぐらい早くなる。

538 :デフォルトの名無しさん:2009/04/19(日) 14:41:22
>>521
別にvolatile使わなくても問題なくね?
static int key=1;
void Thread0()
{
 key=0;//volatile指定が無い場合消失する可能性がある。
 Sleep(100);
 key=1;
}
void Thread1()
{
  while ( key ){ count++; }
}
こんな事でもしない限り無限ループにならんべや。
こんなコード書くことまず無いだろ。

それと、そもそも、グローバル変数使うなよ。

539 :デフォルトの名無しさん:2009/04/19(日) 19:33:59
>>538
バカでしょ

540 :デフォルトの名無しさん:2009/04/19(日) 22:08:19
>>538
まず、ネタなのかマジなのかを書いてくれ。

541 :デフォルトの名無しさん:2009/04/19(日) 22:25:33
>>538
バカなの?死ぬの?

542 :デフォルトの名無しさん:2009/04/19(日) 22:53:09
>>539-541
まじか。何で?

543 :デフォルトの名無しさん:2009/04/19(日) 23:02:48
volatileを使うと排他制御しなくて
よくなるから必要

544 :デフォルトの名無しさん:2009/04/19(日) 23:19:55
それは誤り

545 :デフォルトの名無しさん:2009/04/19(日) 23:50:48
keyをテストする所にメモリバリア入れないと駄目じゃないかね

546 :デフォルトの名無しさん:2009/04/20(月) 01:29:15
例えばJavaやC#などだと参照してる変数がvolatileだと期待通りに動くが、
そうじゃないとどうなるか分からんのじゃない?


547 :デフォルトの名無しさん:2009/04/20(月) 15:54:13
>>543
volatileと排他制御はなんの関係もないぞ。
volatileは最適化の抑止で、せいぜい>>538の様な事や
レジスタだけでなくメモリ側にも変数を割り当てるぐらいだ。
そもそも、CやC++に排他制御なんて概念は無いから
クリティカルセクションなんかを使う他無い。
ちなみに、Javaは排他制御がかかるが、グローバル変数
と言っているからCかC++だ。もしかして、間違えてないか?

548 :デフォルトの名無しさん:2009/04/20(月) 16:04:59
 で、>>539-541は、人をバカ呼ばわりしただけの
まっとうな理由あるんでしょうねぇ。まさか、Javaや
C#のvolatileしか知らない癖にバカにしてたなんて
恥ずかしい理由じゃありませんよねぇ当然。

549 :デフォルトの名無しさん:2009/04/20(月) 16:23:18

J

550 :デフォルトの名無しさん:2009/04/20(月) 19:35:31
【OS】WindowsXP SP3
【言語】C
ソース ttp://f50.aaa.livedoor.jp/~iwazaki/uploader/src/up2117.txt
↑をcygwinでコンパイルすると
In function `thread_func':
14: warning: assignment makes integer from pointer without a cast
In function `main':
54: warning: passing arg 3 of `pthread_create' from incompatible pointer type
というエラーが出ます。
14行目と54行目が悪いことはわかりますが具体的な原因がわかりません。
ちなみにexeファイルは生成されます。

よろしくお願いします。

551 :デフォルトの名無しさん:2009/04/20(月) 20:32:51
>>550
4: warning: assignment makes integer from pointer without a cast
In function `main':
キャスト無しじゃ整数をポインタにできないっていうような事書いてあるね。

pthreadのプロトタイプはこんな感じで第3引数には関数ポインタを、第4引数にはvoidポインタを取るように
なってる?
int pthread_create(pthread_t * thread, pthread_attr_t * attr, void * (*start_routine)(void *), void * arg);

君のコードだといずれもdoubleにキャストしているけど何故だい?
pthread_create(&a[i], NULL, (double *)thread_func, (double *)array);

※スレッドなんて飛躍したものに手を出す前にこの手のエラーを自己解決できる
程度には言語機能を勉強し直した方がいい。

552 :デフォルトの名無しさん:2009/04/20(月) 20:41:56
>>550
んだんだ、
それに、Cなんだから、void * が絡むときはキャストしない方が
素直で、読みやすいコードになる。
たとえば、
double *data = (double *) arg;
は、
double *data = arg;
としろ、ってことね。C++から来た人はこれをやりたがるのね。
C++だとこの場合にもキャストが必要だから。

乱文澄まそ

553 :デフォルトの名無しさん:2009/04/21(火) 01:49:59
>>551
pthread_create(&a[i], NULL, (double *)thread_func, (double *)array);
は単に見落としていたようです。
お手数掛けて申し訳ないです。
直したらこの行のエラーは出なくなりました。

>>552
C++をやっていたわけではないのですが、配布されたソースコードの例にはこの形で書かれていたのでそれに準じて書きました。

そしてまだ14行目でエラーが出ますがpthread_selfの扱い方はそもそもこれでよいのでしょうか?
ちょろっと調べて出てきたものを使っただけなのでよく理解していません。

554 :553:2009/04/21(火) 02:06:23
すみません、調べたらわかりました。
ただし他の問題が浮上しました。
pthread_t型をint型か何かに変換できないんですかね・・・。

555 :デフォルトの名無しさん:2009/04/21(火) 02:31:33
>>554
pthread_tはポインタか構造体かなんかでしょ。
そもそも、別の型に代入しちゃいけない。
語のライブラリだと結構やろうと思えば別の型
に無理やり代入する事も出きるけどしちゃいけない、
内部に干渉しちゃいけないものがある。
大体識別値(discriptor)と呼ばれるものなんかがそう。
あと、初心者の内はメモリ操作が簡単にできる事が解って乱用する
人がいるがポインタのキャストはやたらめったらつかうもんじゃない。

てか、君の悩みはスレッド以前の問題だから、Cの初心者スレなんか
で質問しなさい。




556 :デフォルトの名無しさん:2009/04/21(火) 20:37:55
言い方は気にくわないなw
小さい芽潰して楽しんでるふうにしかみえねーよ老害

>>554
pthread_tはunsinged longのtypedefだよ


557 :デフォルトの名無しさん:2009/04/21(火) 21:56:02
>>556
何を言ってるんだおまえは? >>550のwarningを100回読み直してから出直してこい

558 :デフォルトの名無しさん:2009/04/22(水) 00:05:38
>小さい芽潰して楽しんでるふうにしかみえねーよ老害
ふーん
芽をつぶして楽しんでて害なんだ
ふーん


559 :デフォルトの名無しさん:2009/04/22(水) 01:49:54
そうなんじゃね、多分。

560 :デフォルトの名無しさん:2009/04/22(水) 02:46:06
大人なんだからもっと仲良くしろよ

561 :デフォルトの名無しさん:2009/04/22(水) 21:38:45
歯痛制御で俺の虫歯を何とかしてくれ

562 :デフォルトの名無しさん:2009/04/22(水) 22:28:22
チュイーン ギキィィーー

563 :555:2009/04/22(水) 22:56:29
>>556
 俺、21歳なんだが。3D関連でC++始めて5年以上にはなるが、
そうか俺も、もう老害か・・・。

564 :デフォルトの名無しさん:2009/04/23(木) 00:01:02
>>561
本業歯医者の趣味グラマだけど何か用?

565 :デフォルトの名無しさん:2009/04/23(木) 02:10:25
>>564
医者の趣味グラマっておおいな。
LHAも医者だし猫プロの筆者も医者。
しかも、本業より優秀そうなんだよな・・・。

566 :デフォルトの名無しさん:2009/04/23(木) 02:33:52
本当は工学系にいきたかったのに、
なまじっか頭いいと医療系への進学を勧められちゃう奴って多いからな

567 :デフォルトの名無しさん:2009/04/23(木) 09:19:51
いつも思うんだけど、歯科治療技術も日々発展してるだろうから
古い医者より新しいところの方がいいのかねえ

568 :デフォルトの名無しさん:2009/04/23(木) 11:19:32
ジャストシステムのスタートアップにも医学生がいたな。
人間って本当に不公平にできてるよ。

569 :デフォルトの名無しさん:2009/04/23(木) 12:48:15
>>564
予約時間の十分前には歯科に着いているのに
待合室で一時間待たされ、診察室に通されたと思ったら
また三十分以上待たされるのを何とかしてくれ

どう見ても歯科医と歯科助手がデッドロックを起こしているようでなかなか回ってこない

570 :デフォルトの名無しさん:2009/04/23(木) 19:35:34
>>569
誰がうまいこと言えとw
デッドロックは言いえて妙だったわ。

571 :デフォルトの名無しさん:2009/04/23(木) 23:58:32
>>567
少なくとも、レントゲン撮影したら「現像するから日を改めて」なんてところは止めた方がいい。
今時、治療椅子ごとに端末があってそこで見られるのが当たり前。

572 :デフォルトの名無しさん:2009/04/24(金) 09:00:21
>>571
端末は無いけど、数分で現像したフィルムができるのが普通じゃない?
2,30年前からそうだったと思うんだけど

573 :デフォルトの名無しさん:2009/04/24(金) 09:44:28
いい加減にしとけよ

574 :デフォルトの名無しさん:2009/04/24(金) 11:57:45
マルチスレッドと減増
関係あっても、遠い存在のような


575 :デフォルトの名無しさん:2009/04/24(金) 17:51:20
>>556
老害ではなく、基地害だ


576 :デフォルトの名無しさん:2009/05/02(土) 22:30:20
俺の日記帳
今日は5月2日です。
何してるの?

577 :デフォルトの名無しさん:2009/05/04(月) 23:25:22
C++0xではマルチスレッドプログラムを組むのは
容易になるのであろうか

578 :デフォルトの名無しさん:2009/05/04(月) 23:26:23
C++でマルチスレッドは危険ですよ

579 :デフォルトの名無しさん:2009/05/04(月) 23:36:49
>>578
Win32本では平気でマルチスレッド走らせる例が書いてあるけど
デッドロックについても詳しく説明してある

580 :デフォルトの名無しさん:2009/05/05(火) 04:20:22
>>579
なんだその会話になってないレスは

581 :デフォルトの名無しさん:2009/05/05(火) 06:50:37
CやC++の言語レベルではマルチスレッドについての取り決めはない。
ライブラリ(pthreadなど)やプラットフォーム(osやハードウェア)や実装(コンパイラ)レベルで、
扱いが決められているので、そういったものの前提抜きでマルチスレッドは語れない。

582 :デフォルトの名無しさん:2009/05/05(火) 09:33:35
メモリモデルの仮定が入っちゃうからやりにくいだろうなあ

583 :デフォルトの名無しさん:2009/05/05(火) 09:58:42
>577
concurrency 周りが大幅に強化されてるんで、恐らくは。

584 :デフォルトの名無しさん:2009/05/09(土) 12:04:34
マルチスレッドにする利点は何?
複数の処理を同時に走らせることができるなんて妄想は無しで。

585 :デフォルトの名無しさん:2009/05/09(土) 12:10:53
世界の全てが妄想なので、答えは消滅しました。

586 :デフォルトの名無しさん:2009/05/09(土) 12:12:54
複数の処理を同時に走らせることができる、妄想で無しに。

587 :デフォルトの名無しさん:2009/05/09(土) 13:11:27
個人的には>>584が何故「複数の処理を同時に走らせることができる」ことが妄想だなんて妄想を抱いたのか知りたい希ガス。
マルチスレッドの利点は全てそこから派生しているはずなのだが。

588 :デフォルトの名無しさん:2009/05/09(土) 13:25:02
>>587
TSSは同時ではないとでも言いたいんじゃないか?

589 :デフォルトの名無しさん:2009/05/09(土) 15:05:51
>複数の処理を同時に走らせることができる
ってのはいわゆる手段なんで。
大元の目的は「暇をもてあましてるリソースを有効活用する」だな。
マルチスレッドはCPUがヒマしてる場合の、GPGPUはGPUがヒマしてる場合の手段だな。

>584がどんな妄想してるか迄はわからんが。


590 :デフォルトの名無しさん:2009/05/09(土) 15:53:09
>>589
それ以外にもあるぞ。むしろプログラマ的にいちばんうれしいのは、コンテキストの異なる処理を明示的な切り替え無しに同居させられることじゃなかろうか。
重い処理を別スレッドでガリガリ処理しつつ、その進行状況をGUIで表示するとか。

591 :デフォルトの名無しさん:2009/05/09(土) 23:10:29
ハァ?
すべてをファイル・デバイスにしてそれをpollすればシングルスレッドで可能ですが何か?

592 :デフォルトの名無しさん:2009/05/09(土) 23:20:27
スレタイ無視

593 :デフォルトの名無しさん:2009/05/09(土) 23:39:00
昔のunixはスレッドなしでもfork/execだけでたいていの事はやれてたな。

594 :デフォルトの名無しさん:2009/05/10(日) 05:27:53
>>591
ちょっと話違うが、Androidのセンサーまわりの設計もそんな感じ。
だが、そのファイルディスクリプタをもらう元が、1つしかなかったり
してセンサーごとにドライバが作れない。

1.0のころはモジュール化すらされてなかったり、1.5になっても
いまだダセー設計だし。設計したやつの顔が見たいな。

595 :デフォルトの名無しさん:2009/05/10(日) 08:32:10
ドライバといった低レベルI/O処理の基本はスレッドより割り込み。
割り込みがないディバイスだとポーリングも使うけど。

596 :デフォルトの名無しさん:2009/05/10(日) 09:07:05
何かの処理で待ちも含めてぐるぐる回りながら、他の処理も同時にやりたい、とかいう場合に
いちいち処理を細切れにしてpollを含むメインループから呼び出す形に縛られるのは面倒だわな。

マジレスすると。

597 :デフォルトの名無しさん:2009/05/10(日) 10:29:43
>>593
でも今はマルチスレッドがサポートされているということは、その煩雑な方式では力不足だったってことだよね。

598 :デフォルトの名無しさん:2009/05/10(日) 10:51:01
今のところは、
やることを細切れにできるようにしておいて
pollするスレッド(大半の時間は待機)が
少数のワーカーに仕事を振り分け
ワーカーはひたすら仕事だけを待ちつづける、というやり方が
I/O待ちやマルチCPU(コア)を有効に生かせ、
メモリやコンテキストスイッチのロスも少なく出来ると言われてるな。

599 :デフォルトの名無しさん:2009/05/10(日) 10:56:07
開発効率という効率を無視すれば、それがベストだねw

600 :デフォルトの名無しさん:2009/05/10(日) 13:17:08
OSのスケジューラをエミュレートしてるだけのような

601 :デフォルトの名無しさん:2009/05/10(日) 15:04:43
コア数を大幅に越えるスレッドを生成すると、
コンテキストスイッチのせいでむしろ性能が低下する。ってのは本当なの?
実測して確かめたいんだけど、どういうコードを書けばいいのか解らん。
えろいひと教えて

602 :デフォルトの名無しさん:2009/05/10(日) 15:07:34
スレッドプールにすりゃ解決よ

603 :デフォルトの名無しさん:2009/05/10(日) 15:11:52
>>601
本当
スレッドに手を出した頃それに嵌ったことがある
各スレッドの同期にmutex/conditionを使う形で大量のスレッド作って試してみればわかるよ
むやみにスレッド数を多くするのはそもそも設計が良くないです

604 :デフォルトの名無しさん:2009/05/10(日) 16:01:38
オーバーヘッドが増大する。 スレッドの多さは関係無し。 
たとえば1ms以内で終了するスレッドを生成すれば効率悪い。

605 :デフォルトの名無しさん:2009/05/10(日) 16:02:56
>>601
スレッドって、一般にはコンテキストスイッチが入らない
(だから軽い)というモノだろう?

原理的には性能低下は無い。
但し、実際のところコア間でキャッシュを共有してたり、
メモリバスを共有してるので、複数のコアを同時に使うことで
シングルコアよりも性能低下することはありうる。


606 :デフォルトの名無しさん:2009/05/10(日) 16:22:26
マルチスレッドのプログラム組んでるんでて
ある変数に複数のスレッドから同時にアクセスできるときは
排他的処理しないとだめ?
というか たぶん今のエラーはそうだろうと思う

607 :デフォルトの名無しさん:2009/05/10(日) 16:24:10
複数スレッドからアクセスしても、OSがエラーはいたことはないな。
値は、ぶっ壊れるけどね。

608 :デフォルトの名無しさん:2009/05/10(日) 16:28:00
読むだけなら問題ない

609 :デフォルトの名無しさん:2009/05/10(日) 16:29:54
読み書きしても、エラーでたことない。 
たとえばグローバルsum=0に、複数スレッドから足し算してもエラーで停止しないが。

610 :デフォルトの名無しさん:2009/05/10(日) 16:31:49
どういった場合に、メモリーエラーが起こるのかが知りたい。

611 :デフォルトの名無しさん:2009/05/10(日) 16:33:36
>>605
> スレッドって、一般にはコンテキストスイッチが入らない

今コンキストスイッチしないのって絶滅危惧種だろ

612 :デフォルトの名無しさん:2009/05/10(日) 16:36:05
なるほど
変数がスタックで削除したり追加したりだからダメなのか

613 :デフォルトの名無しさん:2009/05/10(日) 18:23:53
>>605
マテ、スレッドでもコンテキストスイッチは発生するぞ。
スレッドが(プロセスに比べて)軽いのは、スタックとレジスタだけ
切り替えれば済む(これもコンテキストの切り替えだ)からであって、
コンテキストスイッチそのものが行われないからじゃない。

614 :デフォルトの名無しさん:2009/05/10(日) 18:26:42
1CPUの場合はタイムスライスだけになるから減らないが、
CPUが複数ならスイッチ自体を減らせるという話じゃないかい。


615 :デフォルトの名無しさん:2009/05/10(日) 22:05:51
>>613
ユーザランドでのスレッド実装だと
カーネルモードに入る回数が少なくて済むとかじゃね?

というかこの手のは、何が重いか時代により激しく違ってくるから
一般論といってもそれが何時のものかによるなあ

616 :デフォルトの名無しさん:2009/05/11(月) 21:55:27
昔を語るのが一般とは思えない。

617 :601:2009/05/11(月) 22:46:47
時代によって変わるもんなのか。
レジスタ、スタックの退避とか、カーネルに入って出てくる処理とかが重いのかとかとか思ってたんだけど。
fiberは軽いよ。とか聞くけど、それはおいといて。
>>603
mutexとか排他は考えないで、純粋に「コンテキストスイッチ」処理がどれくらい重いもんなのか
図りたい。
linuxでpthread使ってやろうと思ってるんだけど、どんなコードを書けばいいんだろ
単純に0から0xffffffffまで足す処理をシングルスレッドでやるか、
0〜0xffを足す処理を0x1010101個のスレッド立てて計算させて、どっちが早いか。とか?<そりゃないだろって

618 :デフォルトの名無しさん:2009/05/11(月) 22:57:13
>>617
CPUの数だけ分割するのが速い

619 :デフォルトの名無しさん:2009/05/11(月) 23:28:58
例えば
20ms(OS次第)以上かかる計算処理を一つのJobとして
Job計10000個をキューに入れる。
スレッドをプールしておいて、各スレッドはキューからJobを取り出してひたすら実行する。
この時、プールするスレッド数をプロセッサ数と同数の場合と2000個の場合とで実行時間を計る。

現実的には、スタック領域以外にも
各スレッドで多少の独立したメモリ領域は使うことが多いと思われるので
ただの(レジスタやスタックで納まる)計算はではなく、
16Kなり64Kなりの領域をスレッド毎に確保しておいて
その内部の値を使った計算とする。

等というのはどうだろうか。

620 :デフォルトの名無しさん:2009/05/11(月) 23:39:02
別にキューに入れる必要無いな。
同じことを繰り返すだけなんだから、CASを使ったカウントアップだけして
一定の数字になったらスレッド終了で充分か。
これなら、共有メモリを使えば、プロセスとの比較も出来る。

ただ、スレッドは「スタートのシグナル」を全部同時に出すことが出来るけど
プロセスだとどうなんだろ。全然知らない。

621 :デフォルトの名無しさん:2009/05/21(木) 21:54:47
昔はPVM、今の時代はMPI
そしてOpenMPとMPIのハイブリッド実行が主流なのだろうか

622 :デフォルトの名無しさん:2009/05/21(木) 22:39:20
>同じことを繰り返すだけなんだから、CASを使ったカウントアップだけして
>一定の数字になったらスレッド終了で充分か。

こんな非現実的な処理の時間を計測して何の意味があるわけ?


623 :デフォルトの名無しさん:2009/05/21(木) 22:40:10
おそらくプロセッサ(コア)が増えれば増えるほど遅くなると思うけど。


624 :デフォルトの名無しさん:2009/05/21(木) 22:44:10
ああ読み違えてたすまんのう
単に処理繰り返し数のカウントで使うだけってことね…


625 :デフォルトの名無しさん:2009/05/21(木) 23:23:37
VC(VisualStudio2005)でコーディングしております。

「g_hThread = (HANDLE)_beginthreadex(NULL,0,MainLoop,0,0,&g_dwThreadId)」
で、スレッドを生成し、そちらで、

if(GetAsyncKeyState(VK_UP)&0x8000)

ではキーが取得できるのに、

GetKeyboardState(diks)
if(diks[VK_UP] & 0x80)

ではキーが取得できません。
どうも、メッセージキューやらが原因みたいですが、理屈がイマイチわかりません。
解決策や問題点など、教えていただけると幸いです

626 :626:2009/05/22(金) 00:14:01
追記です。

そもそもGetKeyboardState()はメッセージキューに溜まったものを見るものであって、
新しく生成したスレッドでは、肝心のメッセージを取得することができない、、、
というあたりまではなんとなく理解できました

ちなみにやりたいことはキー情報の一括取得(できればリアルタイムの)です。
(GetAsyncKeyState()では1つ1つしか取れないので・・・
引き続き、解決策などありましたら、お願いします

627 :626:2009/05/22(金) 01:06:46
生成したスレッドの方で、

// Threadのインプットのアタッチ
int targetThread, selfThread;
targetThread = GetWindowThreadProcessId(GetForegroundWindow(), NULL);
selfThread = GetCurrentThreadId();
AttachThreadInput(selfThread, targetThread, TRUE );

/*===== メインループ =====*/

// Threadを切り離す
AttachThreadInput(selfThread, targetThread, FALSE );

とすれば、GetKeyboardState()でも一応取得できました。
荒療治な気がしますが・・・
もっと良い方法などありましたら、お願いします

628 : ◆0uxK91AxII :2009/05/22(金) 02:41:05
>>617
適当なsystemcallを行い、前後でCPUのtimestampでも読めば、
最も軽い場合については、調べられる。

>>625
DirectInputを使うとか。

629 :デフォルトの名無しさん:2009/05/22(金) 03:20:02
>>627
GetKeyboardState()が使用する入力情報は、スレッドごとにある。
AttachThreadInput()はそれを共有させるためのAPIなので、その目的なら
それが一番適切な方法。
ただ、フォアグラウンドウインドウにAttachしてるのは間違いじゃないか?

GetAsyncKeyState()は自分のプロセスが非アクティブでもキー情報を取得できるAPI。
自プロセスの別スレッドでキー入力を拾う目的で使うのは、使えないことはないが
自分がアクティブかどうかの確認が必要で面倒。

630 :626:2009/05/22(金) 04:59:32
>>628
DirectInputは同じような理由で取得できず...(・ω・

>>629
問題なく動いてるんで今の形(フォアグラウンド)で放置してたんですが、
ウインドウハンドルって引数以外で取得できるんでしょうか

631 :デフォルトの名無しさん:2009/05/22(金) 06:02:44
>>630
GetWindowThreadProcessIdもGetForegroundWindowもいらない。
beginthreadexを呼んだスレッドで、そのままAttachするだけ。

そもそも、自分のウインドウを取得するのにGetForegroundWindowを
使うこと自体おかしい。
アプリケーションを起動したら必ずフォアグラウンドになるわけではないし。

632 :626:2009/05/22(金) 15:13:54
確かにかなり回りくどいことしてました。

ただ、Attachの処理は生成処理の直下で一度だけ呼び出しても機能しなかったので、
beginthreadexを呼んだスレッドID(MainThreadId)だけをセーブして、
>>627と同じ場所で「AttachThreadInput(CurrentThreadId, MainThreadId, TRUE );」という形にまとめました。

633 :デフォルトの名無しさん:2009/05/22(金) 16:18:42
新しく作成されたスレッドはGUI関連のAPIを呼び出すまでメッセージキュー等が
作成されないから、スレッド作成直後だと失敗するね。

新しいスレッドでウインドウを持っているならウインドウ作成後、ウインドウが
なければPeekMessageの空呼び出しの後でAttachがいいかな。

634 :???:2009/05/22(金) 16:58:17
アセンブリ言語によるプログラミングで、1+2+3+・・・・+10と、1から10までの足し算をするプログラムはどのようなものになりますか?

16進数表現です。

635 :デフォルトの名無しさん:2009/05/22(金) 17:14:22
まずは正しいスレッドを探すことからだな

636 :デフォルトの名無しさん:2009/06/09(火) 21:56:35
質問です。

constで定義されている、読み込み専用の変数に対して
複数のスレッドがアクセスするとき、同期(クリティカルセクションなど)は
必要ありますか?

637 :デフォルトの名無しさん:2009/06/10(水) 07:47:41
よっぽど変なハードウェアでない限り
要りません。

638 :デフォルトの名無しさん:2009/06/10(水) 19:52:05
volatileで十分w

639 :デフォルトの名無しさん:2009/06/13(土) 18:02:44
volatile使うやつは情弱

640 :デフォルトの名無しさん:2009/06/26(金) 02:20:50
WindowsXP、VC2008EEの環境で作っています。
>>636の質問とかぶるのですが、1つのコンテナを複数のスレッドからイテレータでアクセス(読み込みのみで書き込みはない)しています。
実行時にイテレータを使った部分(直接使用しているのはSTL)でエラーが出て強制終了になってしまいます。
試しにスレッドを1つにしたらエラーは出ませんでした。
どういった原因が考えられるでしょうか?

641 :デフォルトの名無しさん:2009/06/26(金) 03:48:25
そのSTL実装がスレッドセーフじゃないんでしょ。
機能としての読み込みであっても、内部で書き込みしていて競合する場合もあるだろう。
アトミックなところまでスレッドセーフが保証できないならロックすべき。

642 :デフォルトの名無しさん:2009/06/26(金) 04:59:50
>>641
なるほど・・。
マルチスレッドは難しいですね。

643 :デフォルトの名無しさん:2009/07/04(土) 11:06:03
>>640
単純に興味本位なんだが、const_iterator でも駄目なの?

644 :デフォルトの名無しさん:2009/07/04(土) 11:09:45
最近マルチスレッド環境下でスレッド毎にプールを持つ
malloc() 実装がよくあるよね? 諸々の事情でそれが使
えない場合、アプリ側で出来る事ってある?

OO 的に小さなオブジェクトを生成/破棄するんだけど、
スレッドを跨って破棄を委譲するケースもあるんだ。で
も、単純にメモリ管理スレッド作っても過去の効率の悪
い malloc() 実装の焼き直しみたいになって多分効率悪
いと思うんだよね…。

645 :デフォルトの名無しさん:2009/07/04(土) 11:16:05
アプリ側でそういう実装をやってるのはあっても動作環境側でそんな実装やってるの在るか?
複数のプール持つ実装はあるだろうけどスレッド固有になるような実装してたらそれこそスレッド跨げないし

646 :デフォルトの名無しさん:2009/07/04(土) 11:49:37
>>645
ああ、中央ヒープはあるんだよ。でも、スレッド毎にも
管理されるよね? 多分細かくスレッドが生成/破棄され
るようなケースではかなり改善されるんだと思う。

http://goog-perftools.sourceforge.net/doc/tcmalloc.html
↑Google の tcmalloc はコアヒープとスレッド毎のキャッ
シュという形で実装されている。

http://people.freebsd.org/~jasone/jemalloc/bsdcan2006/jemalloc.pdf
↑FreeBSd の jemalloc もスレッド毎に管理されてるみ
たい(TLS)だけど、要求されるサイズによって割り当て
部を買えるような話がある。

でも、やっぱりスレッド跨ると古い malloc() と同じ話?
うーん、ここまで来ると「どのコアで動くか」まで関連
するかなぁ…。

647 :デフォルトの名無しさん:2009/07/04(土) 12:19:54
jemallocは自分が割り当てられたarenaをヒープのメタデータにつっこんでおいてfree時にはそこから解放するようになってる
割り当てはそれこそぽんぽん次のarenaをTLDに結ぶけどさ
そうでもしなきゃFreeBSDのデフォルトになれてない

完全に一切ロックせずスレッド固有のヒープにするなんてのはアプリ内の実装でなきゃ出来んよ

648 :デフォルトの名無しさん:2009/07/04(土) 12:35:06
いやだからそのアプロ側でどうすんの? ってのを聞いてるわけで…。

649 :デフォルトの名無しさん:2009/07/04(土) 12:43:37
一体何を心配して居るんだお前は?

650 :デフォルトの名無しさん:2009/07/04(土) 13:46:18
小さいメモリ大量なら、固定長のバッファをリンクリストかなんかに
つないでおいて、利用すればいいじゃん。malloc, freeよか速い
だろ。

651 :デフォルトの名無しさん:2009/07/04(土) 17:04:33
>>644
mallocにしてはやりすぎじゃない?
C++のallocatorならそういうのもあると思う。

652 :デフォルトの名無しさん:2009/07/06(月) 15:13:06
とりあえず何も考えず素直に作って問題が出たら詳細に
考えることにするよ。一応アロケータ的なインタフェイ
ス挟んでるから後からでもなんとかなると思う。

malloc/free に時間かかってる/かかってないの判定と
かは gprof 辺りで大丈夫なんだっけ?

653 :デフォルトの名無しさん:2009/07/07(火) 13:30:13
>>652
一応gprofでも判らなくもないと思う。呼び出し回数は記録されないけどね。
使える環境なら、vtuneみたいなツールを使う方が(当然)判りやすい。

654 :デフォルトの名無しさん:2009/08/04(火) 10:34:44
pthreadで、デタッチ状態のスレッドをポコポコつくったりしてるとき
生成したスレッドのうち今何個生きているかを知りたいんだけど
pthread_hogehoge() で何か知れるような手段用意されてたっけ?

655 :デフォルトの名無しさん:2009/08/04(火) 11:52:30
マルスレage

656 :デフォルトの名無しさん:2009/08/04(火) 12:00:52
無いんじゃない?atomicなカウンタでも使えばいいじゃん。

657 :デフォルトの名無しさん:2009/08/04(火) 17:07:08
>>656
もしそういうカウンタがもうあるなら再車輪せずに済むかな、と。

658 :デフォルトの名無しさん:2009/08/04(火) 18:51:12
Linuxの話だけど、この件については他でも同じ
ttp://www.yolinux.com/TUTORIALS/LinuxTutorialPosixThreads.html
A thread does not maintain a list of created threads, nor does it know the thread that created it.

スレッド数だけであれば、psでスレッドの情報出すときと同じ方法でできる?

659 :デフォルトの名無しさん:2009/08/04(火) 21:20:30
>>658
pstreeとかのソース読んだからまあ大体のことはできるんだけど
そうか、管理しないことをウリにしてんのか。仕方ないなぁ。
スレッド管理はOS任せか〜。そりゃそうだよなぁ。

660 :デフォルトの名無しさん:2009/08/09(日) 15:09:11
Javaで複数のインスタンスのAというメソッドに同期をかけたい場合は、
どうすればよいのでしょうか?

661 :デフォルトの名無しさん:2009/08/09(日) 15:52:00
>>660
同期は(メソッドにかけるものじゃなくて)メソッドが
アクセスするリソース(メモリやディスク)にかけるものだよ。
あと「同期」はスレッド間でイベントの発生待ち&発生通知を
実現する場合に使われる単語。もしもスレッド間で
(メソッドを通した)リソースへのアクセスの競合を避けるのが
目的なら、「排他制御(あるいはロック)」という単語を使うのが適切。

で、質問が(後者の)排他制御を実現する場合に関するもとすれば、
各インスタンスのメソッドAで(アクセスしたいリソースへの)
排他制御を実装するコードを単純に書けばいい、というのがレスになる。

もしも各インスタンスのクラスが同一ではないため、複数クラスで
メソッドのコードを変更するのはプログラム構造が複雑になると
考えているなら、たとえば以下のようなヒントが参考になるかもしれない。

・コールバック機構を利用して並行処理時に発生するバグを防止する
  http://japan.internet.com/developer/20050927/25.html

662 :デフォルトの名無しさん:2009/08/09(日) 16:02:51
>>661
ご回答ありがとうございます。
プロセス起動時の初期処理用メソッド(DBからマスタを取得し、キャッシュする)に同期をかけたいと思っていました。
お返事どおり、メソッドではなく、リソース(オブジェクト)に対して、ロックをかけるのが正しいですね。
キャッシュクラスをシングルトンで実装し、同期化をさせることにします。

663 :デフォルトの名無しさん:2009/08/11(火) 00:33:30
メソッドにsynchronizedを付けると、同一インスタンスで1つのスレッドしか実行できないということですか?
複数インスタンスあれば、実行できてしまうのでしょうか?

664 :デフォルトの名無しさん:2009/08/11(火) 00:50:50
できてしまいます

665 :デフォルトの名無しさん:2009/08/12(水) 22:09:06
staticメソッドなら大丈夫。
synchronized(Hoge.class) とか

666 :デフォルトの名無しさん:2009/08/12(水) 22:56:58
>>665
> staticメソッドなら大丈夫。
> synchronized(Hoge.class) とか

そこまで書くならstaticメソッドじゃなくてもいいじゃん

667 :デフォルトの名無しさん:2009/08/16(日) 00:34:07
マルチスレッド環境でマスタデータをDBからとってきて、HashMapかListなどに持たせるのは
問題ないのでしょうか?
基本的にJavaプロセスを起動している間にマスタデータが変更されることはない環境です。

668 :デフォルトの名無しさん:2009/08/16(日) 00:34:56
667です。
データを持たせるHashMapかListはクラス変数で持たせたいのですが。

669 :デフォルトの名無しさん:2009/08/16(日) 00:37:29
情報不足
どういう問題がありえると思ってるんだ?

670 :デフォルトの名無しさん:2009/08/16(日) 01:02:48
すみません。
HashMapとかListに数千件というマスタ情報を持たせるのがおかしくないのかという点と、
HashMapやListにデータを追加するときはロックをかけますが、データを取得するときは
ロックをかけなくても問題ないかを知りたいです。


671 :デフォルトの名無しさん:2009/08/16(日) 01:16:29
>>670
ハッシュなんてもんはメモリが許すなら数万件程度は入る事を前提で作るんだが


672 :デフォルトの名無しさん:2009/08/16(日) 01:37:04
>>670
(すでに別の方法で同期済み等で) 追加と取得が同時には起きないと判っているなら、取得同士の間のロックは不要
追加と取得が同時に起きるかもしれないなら、取得にもロックは必要

673 :デフォルトの名無しさん:2009/08/16(日) 06:35:50
通信とかどうでもいいから普通にマルチコアに特化したライブラリってないのさ?

674 :デフォルトの名無しさん:2009/08/16(日) 08:59:53
つintel TBB

675 :デフォルトの名無しさん:2009/08/16(日) 09:49:44
>>673
スレッド間通信が無くても役に立つマルチスレッドアプリとは何者?

676 :デフォルトの名無しさん:2009/08/16(日) 21:13:28
ブルートフォースとか

677 :デフォルトの名無しさん:2009/08/17(月) 10:00:56
>>675
サーバとか

678 :デフォルトの名無しさん:2009/08/18(火) 12:29:42
pthreadでPSで表示したときのスレッド名を変える方法ってありますか?

679 :デフォルトの名無しさん:2009/08/20(木) 11:14:51
ないんじゃない?

680 :デフォルトの名無しさん:2009/08/27(木) 19:59:12
PR_SET_NAMEすればいいんじゃない?

681 :デフォルトの名無しさん:2009/08/28(金) 15:32:43
Cでマルチスレッドのプログラミングで
ふたつのスレッドの時間的な同期をとって
同時に同じファイルを開くにはどのように書けばよいですか

682 :デフォルトの名無しさん:2009/08/28(金) 16:04:42
>>681
そんなことできるんですか

683 :デフォルトの名無しさん:2009/08/28(金) 16:11:59
>>681
その発想はなかった

684 :デフォルトの名無しさん:2009/08/28(金) 16:12:05
>>680
ありがとう。とても役に立った。

685 :682:2009/08/28(金) 16:18:17
>>681
2つのスレッドから共通のモジュールを介してファイルにアクセスするようにしてはどうですか
2つのスレッドからは1つのファイルを開いているように見せつつ,
そのアクセス(読み書き)先の実体であるモジュールの中で排他制御するんです

686 :デフォルトの名無しさん:2009/08/28(金) 17:14:56
対象OSにどういった同期手段が用意されているかによる
どの程度同時性を求めるかにもよるし、それはつまり何のために同時でなきゃならないのかにもよる


687 :デフォルトの名無しさん:2009/08/28(金) 20:01:11
>>681
日本語の文章がちゃんと書けない人はプログラミングも出来ない。
by 竹内

688 :デフォルトの名無しさん:2009/08/28(金) 20:10:31
>>686
これ、日本語が致命的に下手なだけで、要点は
ただ排他制御したいってことだろ

689 :デフォルトの名無しさん:2009/08/28(金) 20:20:01
時間的な同期を取るってんだから、「同時」の意味が違うかもしれんぞ

690 :デフォルトの名無しさん:2009/08/28(金) 22:58:07
日本語が下手ではなく、
頭の中で思考の同期が取れてないのでは。

691 :デフォルトの名無しさん:2009/08/29(土) 02:53:56
排他制御しないって意味かもしれんぞ

692 :デフォルトの名無しさん:2009/08/29(土) 06:04:35
まぁ、>>681がマルチスレッドでプログラミングすべきでないことだけは間違いないな…

693 :デフォルトの名無しさん:2009/08/29(土) 08:12:32
>>681
同時に開く保証はできない。
「ほぼ同じ頃に開くことができるかもしれない」が限度

694 :デフォルトの名無しさん:2009/08/29(土) 08:32:21
2スレッドをイベント待ちにしてから、同時に起こすのかと思った。

695 :デフォルトの名無しさん:2009/08/29(土) 09:00:31
マルチスレッドプログラムでのよくある落とし穴をまとめたサイトってどこかにない?

696 :デフォルトの名無しさん:2009/08/29(土) 09:36:25
>>695
ttp://www.itmedia.co.jp/enterprise/articles/0503/23/news086.html
まんまのがあるではないか。

>Windowsプログラマーでスレッドをいちども使ったことがない人はいないだろう。

一瞬それはないだろうと思ったがスレッド使わなきゃWindowsのプログラムは作れぬなw

697 :デフォルトの名無しさん:2009/08/29(土) 11:12:44
シングルはあるよな

698 :デフォルトの名無しさん:2009/08/29(土) 11:14:07
まぁ「プログラムなんてとりあえず動けばいいや」と考えている奴は大抵マルチスレッド関連でバグ出してハマるしな。

699 :デフォルトの名無しさん:2009/08/29(土) 11:19:51
>>698
そういうのは未だ救いようがあるが自分の痛さに気づいていない
プログラマーは救いようが無い。

700 :696:2009/08/29(土) 11:39:02
よく見たらゴミ記事であるな。
参考にしないほうが良い。スマヌ Orz

701 :696:2009/08/29(土) 11:47:41
ゴミ記事って言うのは酷すぎた。。
前提知識のない初心者が見ると混乱すると言うのが正しい。

702 :デフォルトの名無しさん:2009/08/29(土) 18:11:28
冒頭の四行くらいで日本語も問題切り分けも怪しく感じたから流し読みしたけど
どうでもよさそうな記事だった

703 :デフォルトの名無しさん:2009/08/29(土) 21:52:57
シングルトン実装から始まって愚駄ぐだになって終わってると。

704 :名無しさん@そうだ選挙に行こう:2009/08/30(日) 10:25:00
>>696の記事の二重チェックロックなんだけど

if (_Value == null) {
 lock (ValueLock) {
  if (_Value == null) {
   A temp = new A();
   Thread.MemoryBarrier();
   _Value = temp;
  }
 }
}
Return _Value;

これだと_Valueが更新される前にlockから抜ける可能性ない?
Thread.MemoryBarrier()するのは_Value = temp;の後じゃないの?

705 :名無しさん@そうだ選挙に行こう:2009/08/30(日) 13:05:55
_Valueの代入はlockの中にあるから、_Valueが更新される前にlockを抜けるわけはない
第2のスレッドがやってきて外側のif(_Value==null)を見たときに、
もし_Valueがまだnullならlockに引っかかるから最初のスレッドが更新を完全に終えるまで待たされるので問題ない (lock/unlock自体がメモリバリアになる)
問題は_Valueがすでにnullでなかった場合、_
Valueは新しいオブジェクトを指しているけれども_Valueの中のフィールドはまだ更新されてない、という事態が起きうる (メモリの書き込み順序は勝手に並び替えられるので)
それを防ぐためにメモリバリアを挟んで、_Valueが更新されるよりも前に_Valueの中身が更新されることを保証している

706 :名無しさん@そうだ選挙に行こう:2009/08/30(日) 13:28:19
_Valueが更新されるよりも前に_Valueが参照されないことを保証している

707 :名無しさん@そうだ選挙に行こう:2009/08/30(日) 13:35:51
_Valueへのアクセスは同期されてないから、lock中で_Valueが更新された直後から
他スレッドからAが使えるようになる。
でも

Aの構築
_Valueの更新
Aの構築の結果がAのフィールドに反映される

となる可能性があり、不完全な状態のAが使われる可能性がある。
だからAをnewした後にThread.MemoryBarrier()してから_Valueに代入する。
_Valueへの代入はlockを抜ける段階で保証される。

ということか。
勉強になった、ありがとう。

708 :名無しさん@そうだ選挙に行こう:2009/08/30(日) 13:39:37
一応はっておく
http://www.ibm.com/developerworks/jp/java/library/j-dcl/

709 :デフォルトの名無しさん:2009/09/01(火) 20:32:30
クアッドコアを使った並列処理を
MFCでのマルチスレッドでやろうとしておりますが、
シングルコアのときと同じマルチスレッドのプログラムでも
4つのコアを利用した並列処理になるんでしょうか?


710 :デフォルトの名無しさん:2009/09/01(火) 20:34:22
なるよ

711 :デフォルトの名無しさん:2009/09/01(火) 20:38:55
>>710
そうっすか!ならよかったです。

712 :デフォルトの名無しさん:2009/09/01(火) 21:08:29
erlang

713 :デフォルトの名無しさん:2009/09/02(水) 00:40:31
>>709
MFCには詳しくないけどシングルコアで問題なく動いてたMTセーフのつもりの
プログラムがマルチコアにもってくと異常動作することはそれなりにあるん
じゃないの?int型への代入・参照を非同期でやってたりするプログラムだと。


714 :デフォルトの名無しさん:2009/09/02(水) 01:07:14
>>713
何故int? 64bit整数ならわからんでもないけど。

715 :デフォルトの名無しさん:2009/09/02(水) 01:11:11
つーかそんなことを質問してるわけじゃねーし。
言ってみたかっただけだろ。

716 :デフォルトの名無しさん:2009/09/02(水) 01:18:05
intでもread-modify-writeはatomicじゃないぞx86は(も)

717 :デフォルトの名無しさん:2009/09/02(水) 01:18:42
>>709
なる。OSネイティブのスレッドは、明示的に指定しない限り、複数のコアに分散される。
とは言え、排他制御が適切でないと、各コアを有効に利用できないけど。

718 :デフォルトの名無しさん:2009/09/02(水) 01:27:46
>>716
いや、それだったらそもそもデータ型問わんのでは。

719 :デフォルトの名無しさん:2009/09/02(水) 01:33:30
いやいや、おまいら、それ以前にそれはスレッドセーフと呼ばないのでは。


720 :デフォルトの名無しさん:2009/09/02(水) 02:19:59
>>718
64bitなら、と言ってるから、マシンワードならアトミックと思ってるのかなと思った

721 :デフォルトの名無しさん:2009/09/02(水) 03:38:51
volatile

722 :デフォルトの名無しさん:2009/09/02(水) 06:06:12
volatileがどうかしたか?

723 :デフォルトの名無しさん:2009/09/02(水) 09:42:27
vottakle

724 :デフォルトの名無しさん:2009/09/02(水) 13:14:01
明白な答えが、ここで出せるわけ無いんだから。
あなたが欲しいのは同意なんじゃないの?だから荒れる。

725 :デフォルトの名無しさん:2009/09/02(水) 13:37:33
>>724
独り言が言いたいだけだ、とかでないなら
最低限アンカーくらい書いたら?

726 :デフォルトの名無しさん:2009/09/02(水) 13:55:09
>>725
ごめんめっちゃ誤爆

727 :デフォルトの名無しさん:2009/09/02(水) 13:57:38
        ∧∧
       ヽ(・ω・)/   ズコー
      \(.\ ノ
    、ハ,,、  ̄
     ̄

728 :デフォルトの名無しさん:2009/09/02(水) 14:27:31
>>696
いまひとつ怪しい記事だな。
だいたい今の.NETじゃ前提が変わりすぎてて、役にたたないどころか害のが多い気がするし。


729 :デフォルトの名無しさん:2009/09/02(水) 21:22:08
>>720
64bitを持ち出したのは、32bitマシン(あるいは32bitモード)だと、単一の書き込み/読み出しでも競合すると値が壊れる可能性があるから。
(最初の32bitが書き込み前の、次の32bitが書き込み後の値を読み出す可能性がある)
マシンワード以下なら、順序が入れ替わることはあっても値が壊れることはないと思ってるんだけど、それもあてにならない?
あと、x86系だと、ワード境界をまたぐ読み書きがどうなるかがよくわからない。

730 :デフォルトの名無しさん:2009/09/02(水) 21:40:02
P6以降はキャッシュアラインドなマシンワードのreadやwriteはアトミックだよ
read-modify-writeはLOCK#がassertされないとアトミックじゃないよ
xchg命令は昔からLOCK#がassertされる仕様だからアトミックだよ

コンパイラも含めた挙動はこの辺も参考にするといいよ
http://msdn.microsoft.com/ja-jp/library/bb310595(VS.85).aspx

731 :デフォルトの名無しさん:2009/09/02(水) 21:48:23
ttp://www.intel.com/Assets/PDF/manual/253668.pdf
ここの 8.1 LOCKED ATOMIC OPERATIONS を嫁

732 :デフォルトの名無しさん:2009/09/02(水) 22:01:55
>>729

>マシンワード以下なら、順序が入れ替わることはあっても値が壊れることはないと思ってるんだけど、それもあてにならない?

w

733 :デフォルトの名無しさん:2009/09/03(木) 00:09:10
The Art of Multiprocessor Programming
糞本だなぁ



734 :デフォルトの名無しさん:2009/09/03(木) 03:59:45
volatile

735 :デフォルトの名無しさん:2009/09/03(木) 05:34:09
volatile変数へのアクセスのアトミック性は、non-volatileな変数へのアクセスと同じ
だから、この流れにvolatileは何の関係も無いよ

736 :デフォルトの名無しさん:2009/09/03(木) 09:27:34
>>706
読み取り側ではメモリバリアはいらないの?


737 :デフォルトの名無しさん:2009/09/03(木) 10:14:24
_Valueの値を読み込む前にその指す先の値を読み込むのは不可能だから
メモリバリアがなくても読み込み順序は入れ替わらないはずで要らない・・・んじゃないかなたぶん

738 :デフォルトの名無しさん:2009/09/03(木) 15:09:34
>>737
>_Valueの値を読み込む前にその指す先の値を読み込むのは不可能だから
>メモリバリアがなくても読み込み順序は入れ替わらないはずで要らない
それが成り立たないアーキテクチャもあるんだな。
http://www.cs.umd.edu/~pugh/java/memoryModel/AlphaReordering.html

739 :デフォルトの名無しさん:2009/09/03(木) 15:31:35
volatileの話をするときは、C/C++なのかJava/C#(CLI)なのかをはっきりさせろ。
それぞれのvolatileの意味はまるっきり別なんだからな。

740 :デフォルトの名無しさん:2009/09/03(木) 15:59:30
そうか、やっぱりだめか
例の記事は今見直したらvolatileが付いてるな
なるほど

741 :デフォルトの名無しさん:2009/09/03(木) 16:18:16
それはメモりバリアかvolatileどっちかって話だから意味ないよ

742 :デフォルトの名無しさん:2009/09/03(木) 16:36:48
そろそろvolatileについて一言いっておくか
ttp://d.hatena.ne.jp/bsdhouse/20090720/1248085754

743 :デフォルトの名無しさん:2009/09/03(木) 22:04:04
C++っていつまでAtomicIntegerとかないわけ?
ふざけてないか?いい加減にしろ

744 :デフォルトの名無しさん:2009/09/03(木) 22:06:40
と言われても今年決まる新標準には採用されてるし
一企業や一個人に独占されてる言語と比べるなよ

745 :デフォルトの名無しさん:2009/09/03(木) 22:10:45
>>744
C++0xは2012年まで延期でしょ
今すごい揉めてるでしょ

746 :デフォルトの名無しさん:2009/09/03(木) 22:13:31
つーかC++使うならそのくらいはライブラリかAPIか自力で何とかできないと
結局他でつまづく

747 :デフォルトの名無しさん:2009/09/03(木) 22:23:59
ちょっと来週あたり
C++のatomic実装投下するから誰か100%
厳密に正しいか判断できる人いますか?

748 :デフォルトの名無しさん:2009/09/03(木) 23:38:00
投下してから聞け。

749 :デフォルトの名無しさん:2009/09/04(金) 00:20:53
現行C++ + Boost + TBBで組んでおけば、C++0xの時代になっても
スムーズに移行できるんじゃないかな

750 :デフォルトの名無しさん:2009/09/04(金) 22:04:46
最近はC++の仕事が減ってC#とCばっかりになったお

751 :デフォルトの名無しさん:2009/09/04(金) 23:55:21
http://blueroad.sakura.ne.jp/entry/20070815.php

752 :デフォルトの名無しさん:2009/09/05(土) 00:54:22
gccだとvolatileは付けても付けなくても
効果ないんだね

753 :デフォルトの名無しさん:2009/09/05(土) 01:06:06
SomeType() = default;

って奴を普通のC++に直すと
どうやってかけばいいの?

754 :デフォルトの名無しさん:2009/09/05(土) 01:11:29
>>753
// SomeType() = default;

755 :デフォルトの名無しさん:2009/09/05(土) 04:53:21
gccでもvolatile付けたら本来のvolatileの効果はあるだろ

756 :デフォルトの名無しさん:2009/09/05(土) 09:45:20
ちゃんと実装されているマルチスレッドアプリってあるのだろうか。
このスレ見てるとある特定の条件下でたまたま運良く動いているアプリばかりじゃないかと思ってしまう

757 :デフォルトの名無しさん:2009/09/05(土) 09:50:07
たまたまでもバグが入り込まなかったのならすばらしいことです


758 :デフォルトの名無しさん:2009/09/05(土) 10:17:49
このスレだけが世界のすべてだと想うなかれ

759 :デフォルトの名無しさん:2009/09/05(土) 10:20:06
引っ掛かりやすい問題点は多々あるが、ちゃんと分かってくれば安全に書ける
ただ、その「分かってくる」までのハードルがそれなりに高いから、手を出せる開発者
もなかなか増えないし、MTに対応することで恩恵の得られるアプリも少ないから、
MT対応アプリそのものがなかなか増えない訳だが
IntelもMTのフレームワークで金取ってる余裕ねーだろうにと思う(MSあたりは別に
どっちでもいいんだろうが)

760 :デフォルトの名無しさん:2009/09/05(土) 11:09:19
>>752

const volatile int x;

の説明も出来無さそうだな。


761 :デフォルトの名無しさん:2009/09/05(土) 11:11:26
ああ、const volatileの意味がすんなり理解できるかどうかはいいテストかもなw

762 :デフォルトの名無しさん:2009/09/05(土) 11:50:26
それがconst volatile autoな変数なら私には理解できません。

763 :デフォルトの名無しさん:2009/09/05(土) 12:13:34
C++0xのautoってcvとか*とか&とか付けられるんだろうか

764 :デフォルトの名無しさん:2009/09/05(土) 12:27:55
>>760
最適化されないRead Onlyな変数以外に何かの意味があるのか?

765 :デフォルトの名無しさん:2009/09/05(土) 12:29:06
別に最適化されない訳でもないが

766 :デフォルトの名無しさん:2009/09/05(土) 12:29:18
>>758
日本のマルチスレッドプログラム界の縮図がこのスレだと思っておりますが。

767 :デフォルトの名無しさん:2009/09/05(土) 12:33:20
ここには「実戦ではまだまだ書けませんが」って人もかなりいると思われ

768 :デフォルトの名無しさん:2009/09/05(土) 12:39:42
>>767
そういうヤツは時間の問題でちゃんと書けるようになる。
そんな自覚のないヤツほどマルチスレッドを使いたがる。

769 :デフォルトの名無しさん:2009/09/05(土) 12:40:11
「C/C++の」volatileを誤解してる奴はこれ↓読んどくといいぜ
ttp://mkosaki.blog46.fc2.com/blog-entry-91.html

770 :デフォルトの名無しさん:2009/09/05(土) 13:58:48
マルチスレッドってコンパイラの最適化やCPUの命令の実行順序まで
いちいち気にしていないとまともなプログラムは作れないって事ですか?

771 :デフォルトの名無しさん:2009/09/05(土) 14:23:36
いいえ
mutexやcondvarの使い方を知っていれば問題ありません

772 :デフォルトの名無しさん:2009/09/05(土) 14:28:32
mutexは遅いからイヤだ、などと言い出すから話がややこしくなるだけです

773 :デフォルトの名無しさん:2009/09/05(土) 14:30:03
condvar?

774 :デフォルトの名無しさん:2009/09/05(土) 14:35:10
条件変数
win32ならイベントオブジェクトか何か・・・・・・特定の出来事を待って寝ているスレッドを起こすメカニズム

775 :デフォルトの名無しさん:2009/09/05(土) 14:42:17
スレッド間通信そのものがボトルネックになるような場合は、mutexなんか使って
られないから>>770は真に近い
スレッド間通信のコストが無視できる場合は、>>770は偽に近い

776 :デフォルトの名無しさん:2009/09/05(土) 14:42:37
>>769
そのブログのおっさんって何者なんですか?

777 :デフォルトの名無しさん:2009/09/05(土) 14:45:40
スレッド管理APIを作る側なら>>770は真

778 :デフォルトの名無しさん:2009/09/05(土) 16:07:19
>>770
単純に動くものを作りたいなら、そこまでローレイヤーのことを考える必要はない。
が、
プログラムのパフォーマンスを上げたかったりするんだったら、
考える必要が絶対に出てくる。
「まともなプログラム」==「メジャーなソフトウェア」って認識なら、
言う通り、そこまで考えないとまともなプログラムは作れない


779 :デフォルトの名無しさん:2009/09/05(土) 16:08:26
>>770
適当に作ってはったりかます方が金になるから
きちんとモノ作りする奴は馬鹿を見ると思った方がいいぞ

780 :デフォルトの名無しさん:2009/09/06(日) 10:56:31
mutexの速度が気になるようなプログラムなんて組んだことないぜ
速度より安定性重視な俺はプロだって周りかよく言われます

781 :デフォルトの名無しさん:2009/09/06(日) 12:28:25
必要無いならそれでいい
カーネルやドライバを書いてるような連中はそういう訳にはいかない
科学技術計算やゲームエンジンを書いてるような連中もな

782 :デフォルトの名無しさん:2009/09/06(日) 13:20:16
正しく動くものできっちり金を取った後、
また高速化するたびにきっちり金を取るのはプロだと思う。

783 :デフォルトの名無しさん:2009/09/06(日) 13:31:25
最初からある程度高速じゃないと金の取れない業種もあるけどな

784 :デフォルトの名無しさん:2009/09/06(日) 14:14:35
そういうプロが幅を利かせるから日本のIT業界はいつまでたっても土方っていわれるんだろな

785 :デフォルトの名無しさん:2009/09/06(日) 14:18:37
よく知らんけど海外でもそういう手合いはいるんじゃね?
変に胸張って「俺らこそがプロ」みたいな顔をしてるかは別として
Googleみたいなとこのプロはそういう手合いとは思えないしな

786 :デフォルトの名無しさん:2009/09/06(日) 16:34:28
>>780に同意する。

いかにmutexの回数やクリティカルセクションの範囲を減らすかに設計能力を注ぐ。
要は、スレッド間の同期を減らし、スレッドの並列度を上げることが目的。
ただし、(>>770の言う)コンパイラの最適化やCPUの実行順序までは考えない。
(>>782の言う)正しく動くものを作ることを最優先する。

マルチスレッディングと、その最適化には、高度に抽象化された思考能力と設計技術が要求される。
(>>778の言う)ローレイヤのことを気にした(言い換えると、ローレイヤの振舞いを前提にした)
スレッディングのロジックを組むということは、プラットフォーム依存な設計であるということ。
(>>781の例であれば)科学技術計算ならUNIXからWindowsへ、ゲームエンジンならPS3からXBoxへ
移植するたびにロジックの再設計が必要になる。

もしかすると自分が知らないだけで、(意図的に?)そういうローレイヤ前提な設計をして、
移植の度に利益を得るという(>>778,779,781のような)世界があるのかもしれない。
ただ、それは(>>784の言う)土方仕事と呼ばれる日本のIT業界の縮図そのものであると思う。

例外があるとすれば、カーネルの、しかもスレッドスケジューラやmutexそのものを実装する
コアなデベロッパに限る。彼らはハード(CPU)の能力を最大限に生かす基盤を作る人達だから。

787 :デフォルトの名無しさん:2009/09/06(日) 17:00:35
いや、普通に移植性の高いlock-free queueとか書けるから。

788 :デフォルトの名無しさん:2009/09/06(日) 17:04:16
ハードリアルタイムやったことないやつって性能無視の安定指向が強いよな


789 :デフォルトの名無しさん:2009/09/06(日) 17:07:38
マシンパワーの需要と供給の比がカツカツかトントンか余りまくりかで全然違うからな
それを無視して、どれか一つのパラダイムだけで語る奴は問題がある

790 :デフォルトの名無しさん:2009/09/06(日) 17:08:37
CompareAndSetとか、既に
どの開発環境でもインラインアセンブラ関数
用意されてるから、CPU変わっても大した話
じゃないよ



791 :デフォルトの名無しさん:2009/09/06(日) 17:24:48
ところでお前らlock-free queue
とか朝飯前なんだよな?

なぁどうなんだ?

792 :デフォルトの名無しさん:2009/09/06(日) 17:28:54
>>789
ですよねー周りの見えない技術者ほど使えない物はないです


793 :デフォルトの名無しさん:2009/09/06(日) 19:15:48
物理シミュだと、精度が要るところは安定性重視でそうでないところはピーク性能重視。
マシンパワーの配分はジョブによって違うから動的に。

794 :デフォルトの名無しさん:2009/09/06(日) 21:30:11
>>791
Javaのマルチスレッド本にlock-free queueの実装が載ってたんだが。
「どうやってlock-freeを実現しているのか」は何とか理解できたが、
自分で一から書けるか、と聞かれると胸を張って「No!」と答えるしかない。

795 :デフォルトの名無しさん:2009/09/06(日) 21:32:03
>>791
俺は今書いてる
書いたらここにうpして

虐めて貰おう

796 :デフォルトの名無しさん:2009/09/06(日) 22:00:21
要求条件によって実装も細かく変わるからなぁ、lock-freeは

797 :デフォルトの名無しさん:2009/09/06(日) 22:08:59
IntelのMathKernelLibraryはやばい
あれこそプロの仕業だ

798 :デフォルトの名無しさん:2009/09/06(日) 22:28:11
>>781のような世界では
LockFree程度じゃ満足されないぞ。

RCUとかを使ってCasFreeにして、
メモリバリア(バスロック)を減らさないと充分ではないと言われるんだ。
メモリバリアがあると、シングルコアでもバスクロックで数クロックを消費するが
これが他のコアのCASが原因でも起こるわけだからな。

799 :デフォルトの名無しさん:2009/09/06(日) 23:31:17
>>797
MKLは、OpenMP対応しているから勿論OpenMPで並列実行させてもいいのだけれど。
意外なことに、MKLを使ったプロセスを複数同時実行させてもリニアリティが高いのが凄い。

800 :デフォルトの名無しさん:2009/09/07(月) 01:19:14
>>798
lock-freeが要求によって実装がまちまち、ってのはそういうのも含めたつもり
CASは使わないがメモリモデルや要件的にRCUも不要な場合とか、色々あるからなぁ

801 :デフォルトの名無しさん:2009/09/07(月) 01:20:34
ロック中に、割込処理みたいなコンテキストスイッチしない人が飛び込んできたら
デッドロックしちゃうけど、一般的にこういうのはどうやって回避する?

802 :デフォルトの名無しさん:2009/09/07(月) 01:31:35
飛び込ませないとか

803 :デフォルトの名無しさん:2009/09/07(月) 01:35:48
割り込み処理の中で何かをロックするというのはやめようよ

804 :デフォルトの名無しさん:2009/09/07(月) 07:16:58
>>801
longjump

805 :デフォルトの名無しさん:2009/09/07(月) 09:58:24
ロックって他のスレッドをロックしなければコスト低いのな
特定のクラスの関連のない処理を同じロックオブジェクト使ってすげー遅かったのが
処理ごとに別のロックオブジェクト使うようにしたら殆どコストが無くなった

当たり前だよな・・・


806 :デフォルトの名無しさん:2009/09/07(月) 11:44:54
>>805
では聞くが、それは本当にロックする必要があったのか?w

807 :デフォルトの名無しさん:2009/09/07(月) 11:54:40
あるし

808 :デフォルトの名無しさん:2009/09/07(月) 12:56:39
ロックの粒度は可能な限り小さくする派です
でもそれ以前になるべくロックしないでいいように設計します


809 :デフォルトの名無しさん:2009/09/07(月) 15:37:35
それが言いたかったんです
けど小さいロックを連続でするくらいなら少し大きなロックを1回の方が効率いい時もある

810 :デフォルトの名無しさん:2009/09/07(月) 15:47:31
以前ねえ、ロックの粒度を細かくしていったら
滅多に競合しないのに、オブジェクト毎に計数千個のロックが作られる事態になったことがある。
(rwlockのエミュレーションで、Win32でやってみたらHANDLEの使用量が跳ね上がったり)

で、こういう場合はどうするのが妥当?

1) そのまま数千個使う
2) ハッシュ等でロックを減らす
3) がんばってrease-releaseする形にする

まあ3)が一番まともかと思うんだけど
CASとかを使ってうまく解決できるのかな。

811 :デフォルトの名無しさん:2009/09/07(月) 15:55:47
>>809
> 少し大きなロックを1回の方が効率いい時もある

ロジック的に必須な少し大きなロックを洗い出して、ち
まちま小さなロックを作らないように設計するかな。

大抵他のものと絡めて排他する必要が多いから、部品単
位にロックを用意することはあまり無い。

「粒度を小さくする」っていうのはその上でロック期間
が短くなるようにすることだと思ってる。

812 :デフォルトの名無しさん:2009/09/07(月) 22:00:28
compare_exchange_strong
compare_exchange_weak

の違いってなんなんですか?



813 :801:2009/09/08(火) 01:50:20
割り込み中に重たい処理をやりたくないから、割り込みじゃない人に
重い処理をやらせようと思って、タスクキューみたいなのをこしらえて
せっかくだから処理を全部タスクキューにやらせようと思ったのよ
そしたらキューにタスクを積む処理で詰んだ

814 :デフォルトの名無しさん:2009/09/08(火) 02:16:44
頑張って、「キューに追加/取り出しの処理」をlock-freeにするんだ。
場合によってはキューのデータ構造から書き直して、な。

815 :デフォルトの名無しさん:2009/09/08(火) 07:56:26
単純にタスクキュー触る間だけ割り込み禁止に・・・

処理させたいタスクに対応するビットフラグ立てるだけでもよくない?

816 :デフォルトの名無しさん:2009/09/08(火) 09:53:40
割り込みで lock-free キューに詰んで、表側で適当な
ディスパッチタイミングで必要な処理を起こす、ってい
うのなら出来そう。キューの保持数が 0 → 1 のタイミ
ングで通知を送って…とかだと詰みそう。

817 :デフォルトの名無しさん:2009/09/08(火) 10:22:40
lock-free のほうが簡単では?
たとえば、A B Cの処理は衝突無し、順序関係無しだったら
3つのスレッドのキューに渡すだけでしょ?
なんで、マルチスレッドは、排他制御や、待ちの方が発展したのか不明。こっちの方が難しいだろ。

818 :デフォルトの名無しさん:2009/09/08(火) 10:37:33
lock-freeって、実際にどういうアトミック命令を組み合わせて実装すんだ
それっぽい紹介サイトがみつからねぇ・・・

819 :デフォルトの名無しさん:2009/09/08(火) 10:57:57
アトミック命令はアルゴリズム次第で不要だろ。
このようにしたら、メモリの共有部分は出ないから、失敗は出ない。
すべてこのような分割にしたらいい。

> 預金残高の書き換え処理をn並列で行いたいなら、n個Wait-freeキューを作り、
> 口座番号をnで割った余りでどのキューに入れるか決めるという方法で対応できる。

Lock-freeとWait-freeアルゴリズム - Wikipedia
http://ja.wikipedia.org/wiki/Lock-free%E3%81%A8Wait-free%E3%82%A2%E3%83%AB%E3%82%B4%E3%83%AA%E3%82%BA%E3%83%A0



820 :デフォルトの名無しさん:2009/09/08(火) 11:08:36
コンペア・アンド・スワップを使わないと
処理がうまくいかないケースを知りたい。


821 :デフォルトの名無しさん:2009/09/08(火) 11:16:06
なにこれむずい

822 :デフォルトの名無しさん:2009/09/08(火) 11:48:12
>>815
割禁は嫌だしビットは複数積めないよね

823 :デフォルトの名無しさん:2009/09/08(火) 14:47:46
>>820
俺は逆にCAS無しで上手くいくケースを教えて欲しい

824 :デフォルトの名無しさん:2009/09/08(火) 15:57:19
>>822
以下の方法なら、これなら(フラグの)ビットは1個あれば済むよ。
実際にUNIXのデバイスドライバ(STREAMS)で実装した。

タスクキューを複数のサービススレッドが共有する。
割り込み処理ではタスクキューにイベントを入れてフラグを立てる。
複数のサービススレッドが一斉に起きて、最初にスケジュールされた
スレッドだけがイベント取り出しに成功しフラグを落とす。
他のスレッドはタスクキュー空(から)なので、再び待ち状態に入る。
割禁の範囲はタスクキューとフラグを触る時だけ。

UNIXでハードなリアルタイム性は要求されないから、可能な手法だけどね。

825 :デフォルトの名無しさん:2009/09/08(火) 16:08:34
Mac OS X 10.6(Snow Leopard)の話題だけど、
こんなのはWindowsやUNIX/Linuxでは常識なのかな?

マルチコア時代の新機軸! Snow LeopardのGCD(Grand Central Dispatch)
http://ascii.jp/elem/000/000/455/455786/

826 :デフォルトの名無しさん:2009/09/08(火) 16:12:39
ぜんぜん常識じゃないよ。
Mac OS はいい意味で、ようやっとるなと思う。

827 :デフォルトの名無しさん:2009/09/08(火) 17:14:56
まだ途中までしか読んでないが

完全自動じゃないけど
IOCPでの、CPU数にあわせた同時実行数自動決定が、似たような仕組みなんじゃないか。
プールするスレッド数は(一般にCPU*2とか言われているが)自由なんだし。

ただ、ライブラリやフレームワークがそれを利用するように作られているか、といえば
答えは明らかにノーだけどね。

当然、言語仕様なんか触ってないから、
一つ一つのジョブは自分で切り分ける必要があるし、
手間は段違いだろうね。

828 :デフォルトの名無しさん:2009/09/08(火) 17:36:21
>>826
しかし、依存性のないブロックに分割するのは手作業なので、
その記事で絶賛されているほど楽になった感じはしないけどな。
結局自分でワーカースレッドを起こさなくてもいいってだけなので
windowsでいうと、ファイバを利用したスケジューリング用のライブラリがあって
それを利用してコードを書いてるような感じだ。


829 :デフォルトの名無しさん:2009/09/08(火) 17:51:51
斜め読みだけどOpenMPの発展系といった感じかな?
MSだとParallel LINQに近い気がする。

830 :デフォルトの名無しさん:2009/09/08(火) 17:58:20
>>823
819の預金処理は、同時にメモリにアクセスすることは無いだろうが。
口座番号 % n ごとに処理する。 それぞれのスレッドは独立していて
各スレッドが順次処理している限り、衝突など無い。

831 :デフォルトの名無しさん:2009/09/08(火) 18:17:30
>>828
依存性を判断してブロックに分割すれば、あとはフレームワークまかせなのだから、
設計者にとっては、かなり負担を減らせるのでは。Apple絶賛はさておき。

判断そのものの自動化は、副作用が前提な手続き型言語では非常に困難だから、
データフロー型言語が一般化する時代にならなければ実現しないと思われ。
今の流行ならHaskellやF#みたいな関数型言語が近い位置にいる。

あと、GUIライブラリとの連動が考慮されている点も設計者にとっては大きいね。
画像編集や3DCGみたいな分野で、Macの勢力が一気に増大する要因になるかも。

832 :デフォルトの名無しさん:2009/09/08(火) 18:42:19
>>824
割禁が使えないときはどうするよ

833 :824:2009/09/08(火) 19:15:59
>>832
(>>824の話は)割禁が使えるUNIXデバドラでの実装だから、
割禁が使えないときのことは分からない。

というか、割禁がまったく使用禁止な世界(ドライバ開発?)というのが想像つかないんだけど。
サービススレッドは定期的に(Lock-Freeな)キューをのぞきにいくのかな。
それほどレスポンス性能にシビアな世界で、ポーリング方式を採用するのは逆効果な気がする。

Lock-free/Wait-freeには全く詳しくないんだが、割禁が使えない世界というのを、
もしよければ教えてくれないか?

834 :デフォルトの名無しさん:2009/09/08(火) 20:03:26
>>819
>> 預金残高の書き換え処理をn並列で行いたいなら、n個Wait-freeキューを作り、

「Wait-freeキューを作り」の中で、アトミック命令が使われているんだが
そういう意味では無いのかな。
単に「自前で実装する必要があるか否か」という意味なら
いくらでも「○○は不要」なものがあるだろう。

>>833
「割り込み処理」というのはハード的にはまあ確かに割り込みだが
処理内容的には、「別スレッドからの非同期な処理要求を処理するか」に近い。
つまり、割り込み禁止とは「排他ロックを獲得してから処理を開始する」
ということと同様になる。
実際、あまりに長時間割り込みを禁止していると割り込み要求が破棄されるものがあったと思うが
これは、別スレッドからのtrylock要求が規定に達したのであきらめる、というのと同じかと思う。

だから何ってほどでもないけどね。
実際には、「割り込み処理の入り口でロックを獲得」という
(やってはいけない)やり方をせずに済むわけだから。
ただし、通常は競合が無い限りCAS2回で済むロックの獲得/解放の変わりに
システムコールにつながるであろう割り込み禁止処理を入れるというのは
普通のユーザーアプリケーションにとっては
コストが大きすぎて採用できないだろうけどね。
(x86のcli/stiも特権命令だしね)

835 :デフォルトの名無しさん:2009/09/08(火) 20:12:24
>>834
Wait-free関連のどんなライブラリも不要だろ。
このケースだとスレッドをn個つくって、
各スレッドは、渡された処理を順にこなすだけ。
どこにも衝突するところは無い。
( 同銀行間での送金処理があればぶつかるが。)

836 :デフォルトの名無しさん:2009/09/08(火) 20:20:46
要するに、メモリ共有のある部分を並列処理しなければ、何の問題も出ないって事だな。
メモリ共有しながら並列処理しなければ、出来ない(パフォーマンスが落ちる)
ケースってどんなのがあるの?
アルゴリズムの工夫で解消無理なの?

837 :デフォルトの名無しさん:2009/09/08(火) 20:20:56
>>835
そのスレッドに処理を渡す時点で、CASが必要だと思うが。

838 :デフォルトの名無しさん:2009/09/08(火) 20:24:45
>>837
そうか。
処理を渡す側が、マルチスレッドの場合があるか。 ATMは日本全国にあるからね。

839 :デフォルトの名無しさん:2009/09/08(火) 20:26:17
そりゃ、同期の必要が無い処理なら、CASもロックも不要。
当たり前すぎて笑えてくる。

840 :デフォルトの名無しさん:2009/09/08(火) 20:39:27
口座番号でスレッドに分けて、ATM毎に格納するメモリを確保しておいて
メモリの先頭から、順に処理すれば衝突は出ない。
後ろの番地のATMは番が回ってきにくいけど。
そこでさらにATM番号でスレッド分けて、一スレッドで処理するATM数を1000個とかにすればいいだろう。

841 :デフォルトの名無しさん:2009/09/08(火) 20:41:15
お前はスレッド(口座)に対するディスパッチに、同期処理が必要無いとでも思っているのか。
さては、ATMでの出金だけで、振込みとかやったことないだろ。

842 :デフォルトの名無しさん:2009/09/08(火) 20:43:29
で、まあ、実際のところ、処理によってはCASが不要なものも確かにあるよ。
少し前に書いたけど、RCUとか使ってね。
(>>819の書き込みがあまりにもアホっぽいから突っ込まれてるだけでね)

ただ、RCUはそれはそれで破棄のタイミングが問題になるし
破棄するものをキューに入れるとかする場合にはそっちでCASが必要になったりとか
適用できる範囲が限定されるんだけどね。

843 :デフォルトの名無しさん:2009/09/08(火) 20:46:51
口座間の送金処理ありの場合に、同期処理を不要にするアルゴリズムが存在するか考えてみる。

844 :デフォルトの名無しさん:2009/09/08(火) 20:49:53
>>841
むしろ、同じ口座に対する複数の処理があるからこそ、同期が必要と言える。
各口座がスレッドを持っていて、それぞれがwait-freeなキューを持っていたとしても
それに対しての追加/取り出しにはCASが不可欠。
少なくともwait-freeである限り。と
http://ja.wikipedia.org/wiki/Lock-free%E3%81%A8Wait-free%E3%82%A2%E3%83%AB%E3%82%B4%E3%83%AA%E3%82%BA%E3%83%A0#.E3.82.B3.E3.83.B3.E3.83.9A.E3.82.A2.E3.83.BB.E3.82.A2.E3.83.B3.E3.83.89.E3.83.BB.E3.82.B9.E3.83.AF.E3.83.83.E3.83.97
には書いてある。

845 :デフォルトの名無しさん:2009/09/08(火) 21:02:45
とりあえず、RCU的な使い方
いわゆる「volatileで充分」な処理は
「更新の競合が絶対に起こらない」というのが大前提だから。

更新が競合する可能性がある場合は、必ずCASが必要になるはず。

846 :843:2009/09/08(火) 21:11:45
2つ以上の口座から、一度に入金が来る場合が問題か。
841の様に、入金用に、口座毎にメモリを確保しておき、先頭から処理すれば衝突避けられる。
しかし、口座数×口座数だけのメモリが必要になり実用的でなさそう。


847 :デフォルトの名無しさん:2009/09/08(火) 21:13:41
トランザクショナルメモリないと
こんなのCASだけあっても意味ねージャン


848 :デフォルトの名無しさん:2009/09/08(火) 23:07:25
ドライバ開発で、割り込みハンドラでさわるリソースが、
通常コンテキストで触るリソースと競合するなら、
割り込み禁止以外ないと思ってたけど、そうでない
一般的なやり方があるなら教えてほしいのぉ。

マルチコアだと、単一CPUの割り込み禁止だけでは
不十分でspin_lockとかいったりするが。

849 :デフォルトの名無しさん:2009/09/08(火) 23:21:44
>>848
割込ハンドラは割込スレッドを起床させるだけ。
割込スレッドと通常コンテキストとの間の排他は優先度継承付きmutexで行なう。

てな感じで

850 :824:2009/09/08(火) 23:27:18
>>834
レスありがとうございます。
非同期な処理要求がガンガン発生するケースについては分かりました。

ただ、もし処理要求がまったく発生していないアイドル状態の時、
サービススレッドは処理要求の発生をどのように待っているのでしょうか?
たとえば、以下のようなループを組むとか考えたのですが、

while (queue.empty) yield(); /* yield()は他のスレッドへ制御を移す関数 */

システムはアイドル状態にもかかわらず、スレッドがCPUを浪費してしまいます。
Wait-freeライブラリ(?)の中で、新たな処理要求が発生するまで
サービススレッドをwaitさせてくれるような仕掛けが実装されているのでしょうか?

851 :824:2009/09/08(火) 23:31:28
>>849
え、ハード割り込みの延長でmutexを呼ぶのですか?
もし競合していたら割り込みがwaitする(?!)ことになるので、
一般的なドライバ開発ではあり得ないと思うのですが。

852 :デフォルトの名無しさん:2009/09/08(火) 23:44:55
>>851
だから「優先度継承付き」と言っているではないか。
Solaris Internalとかを読むべし。

853 :デフォルトの名無しさん:2009/09/09(水) 00:14:40
>>852
優先度継承したら、割り込みコンテキストぬけて通常コンテキストに
スイッチするん?Solarisは。んなことはないと思うが。

割り込みスレッドを起床するだけというのは普通だと思うが、
割り込みスレッドを起床している間は、通常大本のハードの
割り込みは禁止するよね。禁止するときにレジスタアクセスとか
あってwaitいったりすると、やっぱり通常コンテキストと
割り込みコンテキストで排他は必要になると思うのだが。

854 :デフォルトの名無しさん:2009/09/09(水) 01:00:18
>>853
> 優先度継承したら、割り込みコンテキストぬけて通常コンテキストに
> スイッチするん?Solarisは。んなことはないと思うが。

割込スレッドがmutexでブロックしたら、mutexの競合相手(これは通常コンテキストかもしれない)にコンテキストスイッチして、
mutexの排他区間を抜けさせる。
そしたら元の割込スレッドの処理を続行することができるよね。

855 :デフォルトの名無しさん:2009/09/09(水) 01:06:23
>>853
http://ja.wikipedia.org/wiki/%E5%89%B2%E3%82%8A%E8%BE%BC%E3%81%BF%E3%83%8F%E3%83%B3%E3%83%89%E3%83%A9
> 割り込みスレッド
> Solaris、Mac OS X、FreeBSD などのOSでは、割り込みスレッド(Interrupt thread)と
> 呼ばれる方式が採用されている。割り込みハンドラは高優先度のスレッドであり、割り
> 込みによって起動され、排他制御でブロックされるという重要な特徴がある。


856 :デフォルトの名無しさん:2009/09/09(水) 01:46:16
>>854>>855
だから、割り込みスレッドと、割り込みコンテキストはちゃうっつーのに。
2chで何かを期待した俺がアフォだったよ。

857 :824:2009/09/09(水) 01:56:56
>>852
Solarisは専門外なので書籍は持っておらず、Sunのサイトで
Writing Device Drivers という文書を斜め読みしてみました。
以下は第8章 Interrupt Handlers の節 Interrupt Handler Overview
からの引用です。
http://docs.sun.com/app/docs/doc/816-4854/interrupt-15678?l=ja&a=view

.... The job of the interrupt handler is to service the device and stop the device from interrupting. When the interrupt handler returns, the CPU resumes the work it was doing before the interrupt occurred.

ここには「割込ハンドラがデバイスからの割込を禁止し(stop)、ハンドラがリターンすると
CPUは以前の処理を再開(resume)する」とあります。これは割禁を指していると思うのですが....?

Solarisの場合には、デバイス構造体に「特殊な」優先度付きmutexが含まれているみたいですね。
割込ハンドラが、この特殊なmutexを操作することで割禁制御を実現しているように推測できます。
ただし、この優先度はハード割込の優先度であって、スレッド実行の優先度ではありません。
また、このmutexの操作対象はデバイス(の割込)であって、割込ハンドラとサービススレッドとの
間にあるリソースでもありません。

スレッド間の排他制御に用いられる「一般的な」優先度継承付きmutexと混同していませんか?


858 :824:2009/09/09(水) 02:22:51
>>854
たとえコンテクストスイッチしたとしても、その間に再度ハード割り込みが
次々に入ったらどうなりますか?それを避けるのが割禁の役目だと思います。

>>855
「割り込みスレッド」というブラックボックスな言葉を鵜呑みにしていませんか?
そのwikipediaからの引用部分の前段には、割り込みハンドラが第1レベルと
第2レベルの2つの部分に別れているとあります。Solarisの場合であれば、
カーネル(デバイス)内にあるのが第1レベルであり、その「実行中は割禁」される。
また、デベロッパが作る割り込みハンドラが第2レベルであり、
一般的には「割り込みスレッド」と呼ばれている、と自分は解釈しています。

結局、割り込みスレッド方式であっても「デバイスドライバにおいては、
割禁は避けられない」と思うのですが、間違っていますか?
Solarisの場合には、特殊なデバイスmutexによって割禁制御を抽象化しているから、
デベロッパは割禁を意識せずにデバドラを開発できる、という説明なら理解できますが。

859 :デフォルトの名無しさん:2009/09/09(水) 03:16:16
うーん、なんか論点がずれてきているような…
> ドライバ開発で、割り込みハンドラでさわるリソースが、
> 通常コンテキストで触るリソースと競合するなら、
> 割り込み禁止以外ないと思ってたけど、そうでない
> 一般的なやり方があるなら教えてほしいのぉ。
ってのに対して「少なくともSolarisは違うよ」と言いたいだけなんだけど…

>>857
> たとえコンテクストスイッチしたとしても、その間に再度ハード割り込みが
> 次々に入ったらどうなりますか?それを避けるのが割禁の役目だと思います。

たとえば、ディスクIOに関する割り込み処理を行なっているときに
クロック割り込みが発生したら、クロックの処理を優先させるべきだからそっちの割り込み処理を先におこなう。
でも、クロック割り込みを処理しているときにディスク割り込みが発生しても、ディスク割り込みの処理は後回しにされる。
そういう制御を行なうために「割り込みレベル」ってのはある。
# これは「割り込みスレッドの優先度」とは違うもの。
でも、これはリソースの排他のためのものじゃないよね。

> そのwikipediaからの引用部分の前段には、割り込みハンドラが第1レベルと
> 第2レベルの2つの部分に別れているとあります。Solarisの場合であれば、
> カーネル(デバイス)内にあるのが第1レベルであり、その「実行中は割禁」される。
> また、デベロッパが作る割り込みハンドラが第2レベルであり、
> 一般的には「割り込みスレッド」と呼ばれている、と自分は解釈しています。

第2レベルもカーネル内にあるものだよ。
というか、Solarisでは第1レベルと第2レベルが明確に分かれておらず、
割り込みハンドラは、最初のうちは割り込んだスレッドのコンテキストを「借りて」処理をおこなう。
で、mutexでブロックすることになった時点で、完全なカーネルスレッドとして設定され、コンテキストスイッチが起こるの。
ただ、このとき優先度逆転現象が起こって競合したmutexがいつまで経っても開放されなかったらマズいので、優先度継承の仕組みが働くってこと。

860 :デフォルトの名無しさん:2009/09/09(水) 03:47:59
調停スレッドを置く形態だとCASは別に必須じゃない。普通にwikipediaの記事が間違ってる。

861 :デフォルトの名無しさん:2009/09/09(水) 04:17:44
なんだいきなり

862 :デフォルトの名無しさん:2009/09/09(水) 10:18:21
>>825
スレッドプールとの何がちがうのかわからない・・・教えてエロイ人!

863 :デフォルトの名無しさん:2009/09/09(水) 10:30:12
記事を斜め読みしただけだけど、
ブロックの中から外側のローカル変数を見れるようになってるっぽいのは便利そう
どういう扱いなのかしらんけど

864 :デフォルトの名無しさん:2009/09/09(水) 11:03:00
>>862
スレッドプール+タスクキューってのは定番の仕組み(たとえばJavaのThreadPoolExecutorとか)だけど、
それを利用しやすくするためにClosureを言語拡張として用意したのは凄い。

865 :デフォルトの名無しさん:2009/09/09(水) 11:07:29
昔俺が作ったモニタだとハードウェア割り込みが入った
ら別の割り込みで失われる情報(割り込み要因とか)だ
け保存してまず enable interrupt してたな。

>>859 のいうようなレベル設定はハードウェアで実施さ
れてた。だから自動的に高いレベルのものが順次受け付
け可能だったよ。

>>857 は「じゃあ同じ要因の割り込みが割り込み処理中
に発生したら?」と思うかも知れないが、それはそもそも
処理が間に合ってないってことだ。

866 :デフォルトの名無しさん:2009/09/09(水) 11:09:11
> ブロックの中から外側のローカル変数を見れるようになってるっぽいのは便利そう

ていうかクロージャーってのは基本的にそういうもん。

867 :801:2009/09/09(水) 15:00:41
すまないですがデバイスドライバとかそういうのに限定した話ではないので
割り禁に相当するものはないという前提でおねがいします。

関係ないけど割り金って書くと玉がキュッとなるよね

868 :デフォルトの名無しさん:2009/09/09(水) 17:55:18
>>862
スレッドプールを使いこなせている人にはあんまり関係ない気もするが、
初めてマルチスレッドに触れる人にとっては敷居が低いと思うの

869 :デフォルトの名無しさん:2009/09/09(水) 17:57:37
>>867
>関係ないけど割り金って書くと玉がキュッとなるよね
女の子だからわからないわ

870 :デフォルトの名無しさん:2009/09/09(水) 20:24:24
> 昔俺が作ったモニタだとハードウェア割り込みが入った
> ら別の割り込みで失われる情報(割り込み要因とか)だ
> け保存してまず enable interrupt してたな。

ふつーのOSは、割り込みを発生させた割り込みだけ禁止して
他の割り込みを許可して割り込みハンドラをよびだすよね。
だから当然他の割り込みは受付可能。ハンドラ呼び出す前に
発生させた割り込みまで許可するような変態^H^H面倒くさい
実装はゆるさん。

> >>857 は「じゃあ同じ要因の割り込みが割り込み処理中
> に発生したら?」と思うかも知れないが、それはそもそも
> 処理が間に合ってないってことだ。

間に合ってないっつーか、割り込みコンテキストで割り込みを
発生させた要因をクリアもしくは禁止しないで、割り込み
コンテキスト抜けたら無限に割り込み入り続けるっつーことを
言ってるだけなんじゃね(レベル割り込みなら)

871 :デフォルトの名無しさん:2009/09/10(木) 00:10:55
言語本ではなくマルチスレッドプログラミングの基本を概念からわかりやすくまとめた本があれば売れると思う

872 :デフォルトの名無しさん:2009/09/10(木) 00:11:47
>>871
自作OS入門読めば解るだろ



873 :デフォルトの名無しさん:2009/09/10(木) 16:04:04
>>871
Win32マルチスレッドプログラミングがオススメ
コードはwindowsのapi使ってるけどスレッドの概念とか使い方とかわかりやすく書いてる
まぁ絶版になってるみたいだけどね

874 :デフォルトの名無しさん:2009/09/10(木) 16:41:09
>>871
「Java並行処理プログラミング」がオススメ。
絶讃している人も多い。
http://d.hatena.ne.jp/higepon/20090326/1238067284
入手が非常に困難だけど、復刊交渉も始まったらしいので、
興味があったら投票よろしく。
http://www.fukkan.com/fk/VoteDetail?no=46255
http://blog.book-ing.co.jp/fukkanrepo/2009/09/post-76fd.html

875 :デフォルトの名無しさん:2009/09/10(木) 17:04:39
>>870
> ハンドラ呼び出す前に 発生させた割り込みまで許可
> するような変態^H^H面倒くさい実装

これ、割り込みコントローラがカスケード接続されてる
場合は要るかも。

玄関から割り込みを受け付けて「本当は誰だったか」を
調べて、そのハンドラを呼び出す前に他のハンドラの為
にもういっぺん玄関を開けたりとか。

結局「本当の誰か」に EOI 発行するまでその人からの
再度の割り込みは来ないからマクロに見れば同じだけど、
ハンドラ実行から後を別スレッドでやるように考えれば
割とスマートなんじゃないだろうか。

876 :デフォルトの名無しさん:2009/09/10(木) 23:01:47
>>874
Java向けの本ではあるけど、確かにお薦めだと思う。


877 :デフォルトの名無しさん:2009/09/11(金) 18:27:02
>>871
言語に依存しない入門書は確かに欲しい
各言語での扱いは巻末にちょろっと載ってるぐらいでイナフ

878 :824:2009/09/11(金) 22:29:34
>>859
遅レスになりましたが、頭を冷やして考えまてみました。

>でも、これはリソースの排他のためのものじゃないよね。

古典的なOSでは、割り込みコンテクストとサービススレッドとの間にある
リソースの排他のために、割り込み禁止、あるいは割り込みレベルを(一時的に)上げることで
実現していたけど、「少なくともSolarisは違うよ」ということですね....

>第2レベルもカーネル内にあるものだよ。

より正確には、カーネル空間内にある、ですよね。

>割り込みハンドラは、最初のうちは割り込んだスレッドのコンテキストを「借りて」処理をおこなう。
>で、mutexでブロックすることになった時点で、完全なカーネルスレッドとして設定され、
>コンテキストスイッチが起こるの。

つまり、通常は(競合が発生しない場合は)、割り込みコンテクストとしてハンドラは動き、
その間は割り込みレベルを上げる事で、(同じレベルでの)新たなハード割り込みの発生を防ぐ。
ただし、競合が発生すると(mutexでブロックされると)、割り込みコンテクストは終了して(リターンして)、
カーネルスレッドへのコンテクストスイッチが発生し、残りの処理を継続するという訳ですね。

これなら割り込みコンテクスト内での処理オーバヘッドを最小限に押さえつつ、
同時に、ハンドラとサービススレッド間のリソース排他を実現できるような気がします。
STRAMSのput&srvエントリと同じ考え方ですね。

詳しい解説、ありがとうございました。よい勉強をさせてもらうことができました。
自分としては納得できたので、このデバイスドライバ実装に関する話題は、これで終わりにします。

879 :デフォルトの名無しさん:2009/09/12(土) 15:29:31
アトミック変数クラス(C++0xのstd::atomic<T>みたいなやつ)の
ソースとか作り方ってどこかにあります?

880 :デフォルトの名無しさん:2009/09/12(土) 15:31:50
>>879
あるけど教えない

881 :デフォルトの名無しさん:2009/09/12(土) 15:48:03
>>879
もしWindows使いなら、Win32APIのInterlockedIncrementなど、Interlockedから始まるAPIの使い方を調べればよい。


882 :デフォルトの名無しさん:2009/09/12(土) 15:56:27
「ソースとか作り方」って見た時、
一瞬、lock + cmpxchg とか lock + xadd のことかと思ってしまった。
そんなわけないよな。クラスって書いてるし。

883 :879:2009/09/12(土) 20:37:05
>>881 >>882
大体予想はつくし実の所もう作ってはあるんだけど、
キャッシュの整合性とか色々考え出すと生半可な知識ではどうしようもないので、
既存の検証された実装があればいいなと思って。

884 :デフォルトの名無しさん:2009/09/12(土) 20:55:54
ttp://www.dre.vanderbilt.edu/Doxygen/5.6.6/html/ace/a00029.html

885 :デフォルトの名無しさん:2009/09/13(日) 02:31:59
Art Of MultiProcessor本の10章
ABA問題Pragma10.6.1のところで
CompareAndSet(T expectedReference, T newReference, int expectedStamp, int newStamp)
ってなメソッドが定義されてる。

これってDCASっぽいのだが
質問は説明の後半
「C/C++でやるなら64bitアーキテクチャなら"stealing"bits from pointer,
32bitアーキテクチャでも間接参照?でできる(although a 32-bit architecture woild probably require a level of indirection.)」
ってあるがどうやるんだ?

わかる人、教えて。



886 :デフォルトの名無しさん:2009/09/13(日) 02:51:31
上の質問の追記

ReferenceとStampがどっちも小さい値なら
例えばintegerの上と下で16bitづつつかって
maskで値を取り出すとか工夫できるだろうけど、

例えば32bitマシンで
referenceもstampもどっちも32bitの値を使う場合にどうするんだろう
ってのが質問。



887 :デフォルトの名無しさん:2009/09/13(日) 09:02:36
そりゃペアで保持するオブジェクトの領域作って
そこへの参照をCompareAndSetするんじゃないの?


888 :デフォルトの名無しさん:2009/09/13(日) 11:05:39
>>887
cmpxchg使ったことある?


質問変えると
x86、Cでcmpxchgでどう書くか


889 :デフォルトの名無しさん:2009/09/13(日) 11:18:48
俺も普通に>>887としか思えないし>>885の英文もそう読めるしCASも理解してるが

890 :デフォルトの名無しさん:2009/09/13(日) 11:34:02
俺わかんねorz
具体的にCとgasで疑似サンプルコード書いてもらえると助かる


891 :デフォルトの名無しさん:2009/09/13(日) 11:58:41
>>890
金かかるよ?
高いよ?

いいの?

892 :デフォルトの名無しさん:2009/09/13(日) 12:01:27
いいよ。>>890にツケとけ。

893 :デフォルトの名無しさん:2009/09/13(日) 12:36:05
みんな
ほんとにできんの?

64ビットと32ビットのアーキテクチャのアプローチの違いもいわず
ただ「オブジェクトつくって...」って
分かった気しただけで実装したことないんちゃうか
cmpxchg使うんだよ



894 :デフォルトの名無しさん:2009/09/13(日) 12:46:12
>>893
cmpxchg直接使うってバカか勉強中の学生以外
使わないと思うけど?

キミいくつなの?レベル低すぎなんだよね〜

895 :デフォルトの名無しさん:2009/09/13(日) 14:31:59
x86前提ならそもそも64ビットCAS命令がネイティブでなかったっけ?


896 :デフォルトの名無しさん:2009/09/13(日) 17:11:34
>>x86前提ならそもそも64ビットCAS命令がネイティブでなかったっけ?

元の質問読んだ?
DCASっぽい動きをCAS命令でやるのってどうやるのって話。


誰も64ビット版ではstealing bits、
32ビット版ではindirectionの意味も語らず、
厨房よばわりしてるけど
誰も原著を読み込んでないし実装もできないじゃないか

>>cmpxchg直接使うってバカか勉強中の学生以外
>>使わないと思うけど?
>>キミいくつなの?レベル低すぎなんだよね〜

ようするに出来ないんだろ


897 :デフォルトの名無しさん:2009/09/13(日) 17:19:40
>>894

このメソッド、
x86の32ビットと64ビットの両アーキテクチャ上で
Cで実装してみ?
cmpxchg使わないでw



public boolean compareAndSet(V expectedReference,
V newReference,
boolean expectedMark,
boolean newMark)

「現在の参照 == 予想される参照」であり、現在のマークが予想されるマークに等しい場合、参照およびマークの値を指定された更新値に原子的に設定します。

パラメータ:
expectedReference - 参照の予想される値
newReference - 参照の新しい値
expectedMark - マークの予想される値
newMark - マークの新しい値
戻り値:
成功した場合は true



898 :デフォルトの名無しさん:2009/09/13(日) 17:20:42
IntelのTBBってどうですか
使える? これから主流になる?

899 :デフォルトの名無しさん:2009/09/13(日) 17:28:52
一部はC++0xに取り込まれるので、やっておいて損はないと思う。

900 :デフォルトの名無しさん:2009/09/13(日) 17:35:48
>>898
TBB使ったアルゴリズムが100%正しいのか
検証する手段がないから危険で使えないよ?



901 :デフォルトの名無しさん:2009/09/13(日) 17:42:44
原子的に、って訳は正直どうかと思う

902 :デフォルトの名無しさん:2009/09/13(日) 18:51:04
>>896

つttp://www.nagi.org/diary/?date=20090614#p01


903 :デフォルトの名無しさん:2009/09/13(日) 18:55:38
原子的に

quark的に

904 :デフォルトの名無しさん:2009/09/13(日) 19:40:00
不可分的に

905 :デフォルトの名無しさん:2009/09/13(日) 21:07:54
結局、ここの連中は自分じゃコードが書けない
知ったかばっかりなんだな

906 :デフォルトの名無しさん:2009/09/13(日) 21:14:41
>>905
まず金を払え
話はそれからだ

907 :デフォルトの名無しさん:2009/09/13(日) 21:31:47
>>906

馬鹿らしいが相手にしてやると
サンプルコードも書けない奴に先払いするやつなんていない。

slealing bitsってどういう意味だ?
せめてこれの意味くらいきっちり説明してみろ。

全然わかってねえじゃねえか、このスレの連中w


908 :デフォルトの名無しさん:2009/09/13(日) 21:58:35
>>907
キミってその解ってないと卑下する連中と同列なんじゃないの?
ちなみに、煽れば回答でてくると思ってるでしょ?



909 :デフォルトの名無しさん:2009/09/13(日) 22:15:16
>>907

キミってこんなのも書けないの?
template<typename T>
bool compareAndSet(T* const expPtr, T* const newPtr, const uint32_t expStamp, const uint32_t newStamp)
{
bool r = false;
if(v == expPtr && s == expStamp) {
TAS.lock();
if(v == expPtr && s == expStamp) {
v = newPtr;
s = newStamp;
r = true;
}
TAS.unlock();
}
return r;
}


TASぐらい実装できるよね?そこまでバカじゃないよね?
Javaの実装とVCかgccのcompareAndSwapのインラインアセンブラ
組み合わせれば実装ぐらいできるでしょ?それもできないってレベル低すぎるでしょ?

キミだめだわ



910 :デフォルトの名無しさん:2009/09/13(日) 22:47:13
えーとだな、
そもそもの質問はArtOfMultiProcessor本の
Lock-Free Queueの実装なんで

おお威張りでlock()使われると
失笑するしかないんだがなw

君は本当の馬鹿なんだね


911 :デフォルトの名無しさん:2009/09/13(日) 22:51:26
>>ちなみに、煽れば回答でてくると思ってるでしょ?

902に回答出てるじゃん。

できる人は出し惜しみしないで公開してるし回答もできるだろう。

ここに張りついてる連中は揚げ足とりばっかで
質問の本質も理解できない知ったかばっか


912 :デフォルトの名無しさん:2009/09/13(日) 22:53:20
>>887で終わってんのに何で続いてんの?

>誰も64ビット版ではstealing bits、
>32ビット版ではindirectionの意味も語らず、
当たり前すぎて説明する必要があるとも思わんわ。

64ビットではポインタのビットから一部拝借してスタンプに使う。
32ビットではポインタとスタンプをまとめて直接ではなく、
ペアの領域を作成してそのポインタで間接的にCASを行う。


913 :デフォルトの名無しさん:2009/09/13(日) 23:08:05
>>912
uint64_t expV = ((((uint64_t)expPtr) << 32) | ((uint64_t)expStamp));

uint64_t newV = ((((uint64_t)newPtr) << 32) | ((uint64_t)newStamp));

return (expV == CAS64(&ptr, expV, newV));

これでOK?

914 :デフォルトの名無しさん:2009/09/14(月) 00:17:59
>> 887で終わってんのに何で続いてんの?

909みたいなのが質問者を馬鹿にしたんで荒れたんじゃないの。
lock使ってCASを実装するような奴が威張り散らしてるのみて爆笑させてもらったよ。
いずれにしても知ったかが多いのが明らかになったのはよかったんじゃない。


>>912

当り前すぎたとしても、質問者みたいな初心者もいるから最初から説明してあげれば。


915 :デフォルトの名無しさん:2009/09/14(月) 00:39:43
どう見ても、キミが質問者で
煽って回答を引き出してるだけに見えるけど。

週末だしね。

916 :デフォルトの名無しさん:2009/09/14(月) 00:56:51
>>913
uint64_t expV = ((((uint64_t)&expPtr) << 32) | ((uint64_t)expStamp));

uint64_t newV = ((((uint64_t)&newPtr) << 32) | ((uint64_t)newStamp));


917 :デフォルトの名無しさん:2009/09/14(月) 01:00:27
>>894
>>908
>>909
>>915

煽ってる同一人物なんで
無視の方向で


918 :デフォルトの名無しさん:2009/09/14(月) 04:16:34
火元の人
 やり方が理解できない質問者
 俺に分からないならこのスレにも理解できる奴いないんじゃね、とか思っていて、
 それが態度にも滲み出ている

煽る人
 分かってるつもりだけど分かってないで煽り続ける
 こいつを見た火元は「やっぱり分かってる奴いないんじゃないか」と思いこむ

住人タイプA
 一目で分かるがお前の態度が気に入らないしコード示すのマンドクセ
 つーかこの説明で分かれボユゲ

住人タイプB
 みんな何言ってんだかわかんね

919 :デフォルトの名無しさん:2009/09/14(月) 09:46:05
エスパーA

エスパーB





920 :デフォルトの名無しさん:2009/09/14(月) 10:08:11
霊能者
 死んだ人物の正体が人狼か人間かを知ることが出来る
 村人と狂人の区別などは無理

921 :デフォルトの名無しさん:2009/09/14(月) 12:13:10
住人タイプBです
でもコミュニケーション能力では僕の勝ちみたいです

922 :デフォルトの名無しさん:2009/09/14(月) 13:40:35
エターナルフォースブリザード
 相手は死ぬ

923 :デフォルトの名無しさん:2009/09/14(月) 17:04:33
住人タイプBですが何か?

924 :デフォルトの名無しさん:2009/09/14(月) 17:08:08
住人タイプC
 住人タイプAのいう「ボユゲ」が解らない

925 :デフォルトの名無しさん:2009/09/15(火) 21:22:13
ペットA
 にゃー

926 :デフォルトの名無しさん:2009/09/16(水) 10:11:47
獣人タイプA
  グボァ゙ァ゙ァ゙ァ゙ァ゙ァ゙!!

927 :デフォルトの名無しさん:2009/09/16(水) 11:14:29
おまえら…

928 :デフォルトの名無しさん:2009/09/16(水) 14:17:45
Interlocked系の処理って32bit限定で使っても、
32bit互換動作させた場合は問題なく動くよな?

929 :デフォルトの名無しさん:2009/09/16(水) 21:41:37
??

930 :デフォルトの名無しさん:2009/09/17(木) 09:50:33
住人タイプBなりに色々調べてるんだが、間違いがあったら指摘してほしい

32bitOSだろうが64bitOSだろうが、4byte以下の変数はアトミック変数で、それより大きな変数はアトミックでない
C言語の場合、更新処理を行う場合、Interlocked系の関数を使用する

WinBase.hをのぞいてみると、
32bit環境でのInterlockedIncrement64等は、InterlockedCompareExchange64によるスピン実装されている
32bit用のInterlockedAnd等は実装されていない?

ターゲットIA64以外では、次のように定義されている
#define InterlockedIncrementAcquire InterlockedIncrement
#define InterlockedIncrementRelease InterlockedIncrement
つまり、InterlockedIncrementはAcquireの機能もReleaseの機能も持つ?

何言ってんだかわからなくなってきた
32bitで論理演算をアトミックにやる方法はないのか?
Interlocked系以外でメモリバリアっぽいことする方法がわからん
さらにWinBaseを調べてたらInterlockedPopEntrySListなるものを発見
これがお前らがずっと言ってたLock-Free Queueってやつか!?

もうちょっと調べてみるか

931 :デフォルトの名無しさん:2009/09/17(木) 10:48:30
>>930
> 32bitOSだろうが64bitOSだろうが、4byte以下の変数はアトミック変数で、それより大きな変数はアトミックでない

一般に
バスに1サイクルでアクセスできるのであれば, 少なくともロード/ストアは保証される

o 32bitマシンで, バス幅が 32bit あって 4n 番地に 32bit 以下のオペランドをアクセス
o 64bitマシンで, バス幅が 64bit あって 8n 番地に 64bit 以下のオペランドをアクセス

など

CAS 系の命令を持っている場合, ロード/コンペア/ストアの間バスをロックする様に
設計されてる. (x86の場合は, lock prefix つけるんだっけ?)
通常, このタイプの命令も上に書いた制限が付く

RISC 系のマシンの場合, CACHEがあること前提で, CAS 系の命令を実装しないで
Load-Linke/Store-Conditional 系の命令を実装していることもあるので,
アトミック処理の一番プリミティブな部分は CPU によってすべて異なると
思っておいた方が良い


932 :デフォルトの名無しさん:2009/09/17(木) 10:50:39
とりあえずここは必読。
http://msdn.microsoft.com/ja-jp/library/bb310595%28VS.85%29.aspx

で、
_ReadBarrier コンパイラに対するread-aquire
_WriteBarrier コンパイラに対するwrite-release
_ReadWriteBarrier コンパイラに対する完全なバリア
MemoryBarrier CPUに対する完全なバリア
こうなってるように見える。

InterlockedIncrementAcquireとInterlockedIncrementの関係は、Windows用の
VC++のライブラリとしてなら同一視しても構わない、ということだと思われ。
Xbox用のライブラリとかなら別のコードを吐いたりするんじゃないか?

933 :930:2009/09/17(木) 11:33:43
レスサンクス!

基本的に自動でアライメントされると言う事で、あとはバス幅が64bitあれば問題ないのか!
バス幅64bitなんて普及してたっけか

Cでもメモリバリア普通にあるのな。何で見つからなかったんだ・・・
移植性を考えたらちゃんとInterlockedIncrementAcquireとか使ったほうがよさそうですね

934 :デフォルトの名無しさん:2009/09/17(木) 14:20:22
>>930
>>730-731も嫁

935 :デフォルトの名無しさん:2009/09/18(金) 08:40:14
>>931
1バスサイクルは分割できないけどアトミックとは呼ばないんじゃないか?
CASなどでアトミックアクセスするところへ1バスサイクルだからといってもメモリ読み書きはするべきではなく、アトミック命令で読み書きするべきじゃないかな。

936 :デフォルトの名無しさん:2009/09/18(金) 09:38:38
だからお前ら>>731読めと…

937 :デフォルトの名無しさん:2009/09/18(金) 10:48:32
>>935 >>931はバス上での振る舞いの話しかしていないように読めるんだが


938 :デフォルトの名無しさん:2009/09/18(金) 18:52:17
住人タイプBですがlinuxでvolatile sig_atomic_tな大域変数はmutexロックなしで読み書きしても問題ないですよね?


939 :デフォルトの名無しさん:2009/09/18(金) 19:02:52
いいえまったく問題あります

940 :デフォルトの名無しさん:2009/09/18(金) 19:11:25
> いいえまったく問題あります
どのように?

941 :デフォルトの名無しさん:2009/09/18(金) 19:15:19
>>938
釣だろ? 頼むから釣だと言ってくれ


942 :デフォルトの名無しさん:2009/09/18(金) 19:15:52
> 釣だろ? 頼むから釣だと言ってくれ
釣りじゃないですよ

943 :デフォルトの名無しさん:2009/09/18(金) 19:27:43
volatile sig_atomic_t は signal ハンドラと通常のルーチン間での
不可分なアクセスを保証するだけ。thread とは何の関係もない。


944 :デフォルトの名無しさん:2009/09/18(金) 19:34:12
>>938
>>845

945 :デフォルトの名無しさん:2009/09/18(金) 19:40:39
>943-944
理解できました
ありがとうございます

滝に打たれて修行してきます

946 :デフォルトの名無しさん:2009/09/18(金) 19:42:18
>>938
CASとかの話はチンプンカンプンな住民タイプBだけど、
その大域変数へのアクセスがどんな機械語に展開されるかは
コンパイラの実装しだいだと理解してる。
1語であれば安全かもしれないけどそれは保証されないし、
数語に展開されればその実行途中で他のスレッドへの
コンテクストスイッチが起きる可能性があることは予測できる。
だから、>>938の読み書きは問題ありだと思うよ。

947 :946:2009/09/18(金) 19:44:52
リロードしとくんだった....orz

948 :デフォルトの名無しさん:2009/09/18(金) 20:02:17
>>947
リロードは戦闘に高揚をもたらすのでお勧め

949 :デフォルトの名無しさん:2009/09/18(金) 21:46:18
>>938
シングルプロセッサシングルコアなら問題ないかもね

950 :デフォルトの名無しさん:2009/09/18(金) 22:28:52
よく「シングルプロセッサなら」と言う人が居るけどさ
実際に変数を「読み書き」すると言っても
本当に「読む」と「書く」を完全に独立して行うことなど、あまり無いだろ。

つまり、数値変数を+したり、ポインタを進めたり
あるいはリンクリストを手繰って更新する場合などにしろ
一度読んでから、その値を元に書き込むケースが多いわけ。

つまり、この読んだ直後にコンテキストスイッチが入って別のスレッドに割り込まれたら
たとえシングルプロセッサであっても正常に動作しない。
(こうならないために、アトミック命令というのが存在するんだけど)
その辺をわかってない奴が「シングルプロセッサでは再現性の低いバグ」を混入させておいて
「マルチプロセッサだとうまく動かない」と騒いでいることも多い。

951 :デフォルトの名無しさん:2009/09/19(土) 02:08:56
ポカーン・・・?

952 :デフォルトの名無しさん:2009/09/19(土) 12:02:35
おちつけ


953 :デフォルトの名無しさん:2009/09/19(土) 22:58:56
>>950
gj

954 :デフォルトの名無しさん:2009/09/19(土) 23:07:49
yes, really excellent.
good joke!

955 :デフォルトの名無しさん:2009/09/20(日) 10:00:31
>>950は三行目の日本語がおかしい(逆の意味に見える)けど、そこ以外は
read-modifiy-writeの一般的な危険性を普通に語ってるだけじゃね?
特におかしなことは言ってないように見えるが。長い割に大したことも言って
ねーけど。

956 :950:2009/09/20(日) 10:09:45
高度すぎてお前らには理解できなかったか・・・

957 :デフォルトの名無しさん:2009/09/20(日) 10:50:04
高度でも何でもない基本だろw
バスロックとかキャッシュ整合性とかを絡めてくるなら、まぁ若干高度な話かな、と
思わなくもないかもしれないが

958 :デフォルトの名無しさん:2009/09/20(日) 10:58:52
>>950
「シングルプロセッサなら」、という人は、
まず前提として、普通、割り込み禁止にしてコンテキストスイッチが起こらないようにしてから、
共有変数の操作をしている。
だから、「シングルプロセッサなら」、というのは普通にありえる。

959 :デフォルトの名無しさん:2009/09/20(日) 11:12:27
>>958
スレの流れを読み直したほうがいいと思うよ。

まず>>938の「mutexロックなしで読み書きしても」という質問に対して、
>>949が「シングルプロセッサシングルコアなら」とレスし、
さらに>>950が「....と言う人が居るけどさ」とツッコミを入れてる。
だから、>>958の前提は(一般的には常識かもしれないけど、)
今のスレの流れでは的外れになってしまう。

960 :デフォルトの名無しさん:2009/09/20(日) 11:45:17
どうでもよくね?

961 :デフォルトの名無しさん:2009/09/20(日) 11:49:41
>>960
ダー

962 :デフォルトの名無しさん:2009/09/20(日) 12:16:33
>>959
なるほど、sig_atomic_tは唯のintのtypedefだからな。
volatileはマルチスレッドで役立たずだし、lockしなくていいわけないよな。

963 :デフォルトの名無しさん:2009/09/20(日) 13:10:44
そもそも何でそんな排他制御するのを嫌うんだろうなあ。
そんなにパフォーマンスクリティカルなプログラムを作ってる人ばかりなのかな?
もしそうだとしてもロックを局所化する方向で考えるのが現実的ですよね。
それとも排他制御するとコーディングが面倒くさいからかな?
でも、意味不明なバグに悩まされる方がもっと面倒くさいですよね。

何か他に理由があるのかな…

964 :デフォルトの名無しさん:2009/09/20(日) 13:35:57
「とりあえずやっとけ」がイヤなんじゃない?
「これはおまじないだから」みたいな感じでさ

正しく理由を知ろうと思ことはいいことだと思うよ


まあ俺はvolatile一本だけどね(笑)

965 :デフォルトの名無しさん:2009/09/20(日) 14:07:07
volatile はシングルプロセッサ/シングルスレッドでも必要な時は必要。
すれ違いも甚だしい。

966 :デフォルトの名無しさん:2009/09/20(日) 14:34:21
簡単なことを聞いてもいいでしょうか?
あるファイルに対して読み書きするプログラムがあります。
このプログラムは多重起動を許しており、同時にいくつものexeを実行できます。
この場合はマルチスレッドとはいいませんよね?
単一のプログラム内にて複数のスレッドを組む場合がマルチスレッドという考えでよろしいでしょうか?


967 :デフォルトの名無しさん:2009/09/20(日) 14:41:38
正しい

968 :デフォルトの名無しさん:2009/09/20(日) 14:54:19
一つの資源を食い合いするなら同等の考慮が必要
その場合はマルチプロセスになるのかな

969 :デフォルトの名無しさん:2009/09/20(日) 15:37:26
正しい

970 :デフォルトの名無しさん:2009/09/20(日) 15:41:39
メモリとかキャッシュとかレジスターとかバスとかマルチコア/プロセッサーが絡むと
どうなっているのかよくわからないからいつもmutex頼みです
これらのHW関連とマルチスレッドについて詳しく知りたい場合のよい方法を教えてください

971 :デフォルトの名無しさん:2009/09/20(日) 16:17:22
沢山ペーパーを読んで、沢山ソースコードを読んで、沢山テストコードを書く事。

972 :デフォルトの名無しさん:2009/09/20(日) 17:06:14
mutexで済むならmutexで行きたいし、行けるとこは行く。
ただ、マルチスレッドで書かなきゃならない状況だと、パフォーマンスへの要求が
厳しいことも多いし、粒度の細かい設計が必要になったらmutexのコストはマジで
でかくなる場合がある。
まぁ他にもABBA問題とか細かい話はあるけど、その辺は副次的な問題で、本当に
スレッド間通信コストが重要になることもそれなりに多いんじゃねーかな。
それに、ある意味アトミックオペレーションは最小の排他なんだし、低水準から
固める派としては押さえておきたいだろう。

973 :デフォルトの名無しさん:2009/09/20(日) 18:54:47
自分は低水準な(HW関連な)事柄は、ほとんど考えないな。
mutexのコスト(=オーバヘッド)を考えるよりは、
いかにmutexを減らすか、言い換えると、いかにスレッド間の
結合度(同期)の少ない並行/並列アルゴリズムを設計するかに関心がある。
UNIXだから移植性も大事で、それにはCPUアーキテクチャに依存した
設計は避けべきだから、できるだけ抽象的に考えるというのもある。
UNIXでもマルチスレッディングはそれほど特殊な技術ではなくなったしね。

ただ、それほどパフォーマンスクリティカルなプログラムは扱った経験が無いし、
正直言ってスレッディングには自信があるわけじゃないんで、参考程度かな。


974 :デフォルトの名無しさん:2009/09/20(日) 19:08:19
>>972
> 低水準から固める派

安心して使える道具を揃えてゴリゴリ書くという意味で
は俺も昔はそうだった。だけど最近はトップダウンだ。

低水準からだとどうしてもパフォーマンスを上げきらな
い。結局大域的な設計で排他すべき要件を洗い出してそ
こだけ排他する。細々したコンテナ単位とかでは逆に排
他しない(業務要件としては複数コンテナを扱うことが
多いのでコンテナ単位とか普通ありえないけど)。

時代に逆行してるんだろか…。

975 :デフォルトの名無しさん:2009/09/20(日) 19:17:41
ガチでぎりぎりの性能を引き出すことを求められる現場であればあるほど、低水準とか
ハックとかが出てくるようになる、という傾向は今も変わらないよ。
ただ、そういう現場は激しく減った。
MTはやっぱりパフォーマンスの為に必要になることが多いから、他のスレよりは割合
が多いだろうけど。

976 :973:2009/09/20(日) 19:25:56
>>973のパフォーマンスクリティカルな話を補足すると、
一応は性能要求/予測/設計/測定/改善といった開発プロセスはふむけど、
予測と改善(=チューニング)の段階で、mutexのオーバヘッドは定数として
計算することが許されるレベルのプログラムだということ。
言い換えると、定数だからmutexの発行回数(=係数)は考慮するけど、
mutexそのものを改善しなければならないほどのプログラムではない。
(少なくとも基幹業務処理のような単位時間あたりのトランザクション数や、
 科学計算のような絶対的な性能を要求されるプログラムじゃない。)

基本的には、各段階ごとにきちんと記録を設計書として残すことが
大切という考え方。もちろん予測と結果が大きく外れることはままあるけど、
記録を元に外れた原因を追求し、それを次の開発に生かそうという発想。
システムが複雑だから、なかなか上手くいかず、理想論に近いんだけどね。

977 :デフォルトの名無しさん:2009/09/20(日) 22:54:09
つーか、色々な用途に合わせたlock-free queueの安定した既製の実装が出回ってない、
ってことだけがlockを選ぶ理由になっていることも多い訳で。実装難度を考えないなら、
設計的には明らかにlock-free queueが一番適合するという事例は多い。ただ、自分で
組むほどじゃない、ということが多いだけで。
でも、自分で組むことでも何でもしなきゃならないこともありますよ、って人もいる
のに対して「自分は設計だけで何とかなる事例しか手掛けてこなかったよ」と語ろう
とする意図は分からないな。そういう事例が世の中に多いことくらいはほとんどみんな
分かってるんじゃないかと思うけど。
もちろん、単に趣味でlock-freeをやってみたいだけって人もいるだろうし、そういう
趣味の人を否定もしないけど。

978 :デフォルトの名無しさん:2009/09/20(日) 23:58:47
lock-free なキューくらいなら 20 年位前に自前で作っ
たことはあるよ。でも、そういったコンテナに付加情報
を色々付けようとしたら破綻しない? そういった単純な
仕組みで解決する問題の方が世の中珍しい気がするけど。

979 :973:2009/09/21(月) 00:51:43
>>977
うーん、何か気に触るような事を書いてしまったかな?
自分はlock-free queueの存在を否定なんかしていないよ。
lock-free queueについては全く知識がないから、それについては特に
触れなかった(触れられなかった)だけなんだけど。
逆に、パフォーマンスクリティカルな環境やハードウェアリソースが
ギチギチな環境であれば、lock-free queueを積極的に使うべきだろうし、
おそらく使わざるをえないケースも多いのだろうと思っている。

ただ、>>970の質問に関しては想定している環境は明記されていなかったから、
一般的なmutexで済む事例もあるし、もしも>>970がそういう環境であれば、
HWとの関連でアレコレ悩むよりも、いかに上手くmutexを使いこなせるかについて
設計技法に気を配るほうが前向きでは、と(長々としたレスで)助言しただけ。
(>>976のカキコは余計だったかもしれないが....。)

980 :973:2009/09/21(月) 01:11:24
(>>979の続き)
あと、>>977からは、lock-free queueを絶対的な物として
位置づけているように感じとってしまったのだけど、
>>977自身が語っているように実装は難しいものなんでそ。
CPUアーキテクチャには詳しくないから、lock-free queueに関連した
命令コード(CAS命令?)とかについてはずっとROMっていたけど、
結局、スレッディングの基礎知識はある(と思っていた)自分にとって、
分かりやすいと思える解説や紹介リンクは見つけられなかった。
あげくのはてにIntelの仕様書嫁(>>731)と言われるしまつだし。

そんなlock-free queueを(おそらく初心者だと思える)>>970に勧める
というのは、いかがなものかと思う。また、このスレは相談室スレなんだから、
質問主が「そういう事例が世の中に多いことくらいは分かってるんじゃないか」
という思い込み(前提)でレスするのも不親切じゃないかと考える。

981 :デフォルトの名無しさん:2009/09/21(月) 01:25:38
何レスまで行くと自動で落ちるんだっけ。そろそろ次スレの時期かな。

982 :デフォルトの名無しさん:2009/09/21(月) 02:12:39
メモリの共用が起きなければ、lock freeは簡単だろ。
目盛り多く確保しておけばいい。

983 :デフォルトの名無しさん:2009/09/21(月) 02:52:06
>>982
まったくそのとおりだ
メモリ共有がないのなら lock 操作すら不要なんだから
ただの queue を使えばいい

984 :デフォルトの名無しさん:2009/09/21(月) 04:46:23
この話が何処に向かっているのか分からん

985 :デフォルトの名無しさん:2009/09/21(月) 08:08:39
結局程度の差こそあれ誰も解っていないのではという気がしないでもない


986 :デフォルトの名無しさん:2009/09/21(月) 09:14:50
www
俺以外全員馬鹿www
wwwwwwwwwwwww

987 :デフォルトの名無しさん:2009/09/21(月) 09:19:18
あくまで初心者への回答としての話であるべきところが一般論のように拡張されていた
ことで、一般論としては言いすぎだろう、という意見が出て摩擦が起きたように見える

988 :デフォルトの名無しさん:2009/09/21(月) 09:23:57
誤謬

989 : ◆0uxK91AxII :2009/09/21(月) 09:47:07
lock-freeとか作れないけど、
ソレが有用な場面を挙げてみてほしいとか書いてみるテスト。

990 :デフォルトの名無しさん:2009/09/21(月) 09:49:58
マルチスレッドのほぼすべてで有効だろ。

991 :デフォルトの名無しさん:2009/09/21(月) 11:43:23
ASIOとか進捗表示とかのパフォーマンスの為じゃないお気楽MTなら不要かな
それらはmutexすら要らない気もするが

992 :デフォルトの名無しさん:2009/09/21(月) 14:25:35
>>990
「キュー内の要素数が 0 で無くなった時に読み出しス
レッドが待機状態であれば起こしたい」なんてよくある
要求だと思うけど、要素数とスレッド状態って atomic
に管理する必要あるよね?

そこに lock-free なキューを使うと何が嬉しいの?

993 :デフォルトの名無しさん:2009/09/21(月) 14:36:06
lock-freeをある程度かじれば分かるが、要素数もatomicじゃなくていいよ
スレッド状態は特権リング内の管理だろうから内部の挙動はシラネ
ユーザーレベルで言うなら、lock-free queueをスピン&スリープで待機するなら
スレッド状態も持つ必要なし

994 :デフォルトの名無しさん:2009/09/21(月) 14:48:14
>>993
「要素数とスレッド状態の組」のことを言ってるんだけど? > atomic 性

要するにキューみたいな部品と、その外側の状態を紐づ
けて管理したいときに「lock-free なキューでござい」って
何が嬉しいの? ってさんざっぱら聞いてるんですけど。

995 :デフォルトの名無しさん:2009/09/21(月) 14:49:13
>>993
> スピン&スリープ

…。

996 :デフォルトの名無しさん:2009/09/21(月) 14:53:18
>>994
スレッド状態要らないんだから組み合わせる必要も無いんじゃね?

997 :デフォルトの名無しさん:2009/09/21(月) 14:56:08
細粒度MTではスピンウェイトの使い分けは常識だが、粗粒度MTの常識しか知らない奴が
ずっと前から熱心に張り付いてね?

998 :デフォルトの名無しさん:2009/09/21(月) 14:57:15
>990
989じゃないけど、じゃあ何故lock-freeなライブラリーは一般的に出回っていないの?
俺的にはlock-freeは都市伝説でないかと睨んでいる

999 :デフォルトの名無しさん:2009/09/21(月) 14:58:06
要求によって全然組み方が変わるから

1000 :デフォルトの名無しさん:2009/09/21(月) 14:59:01
>>998
Javaは普通にlock-free queueあるぞ

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

256 KB
★スマホ版★ 掲示板に戻る 全部 前100 次100 最新50

read.cgi ver 05.04.00 2017/10/04 Walang Kapalit ★
FOX ★ DSO(Dynamic Shared Object)