1 名前:デフォルトの名無しさん mailto:sage [2007/08/13(月) 21:35:32 ] マルチスレッドプログラミングについて語るスレ。 その1 pc3.2ch.net/tech/kako/997/997345868.html その2 pc5.2ch.net/test/read.cgi/tech/1037636153/ その3 pc8.2ch.net/test/read.cgi/tech/1098268137/ その4 pc8.2ch.net/test/read.cgi/tech/1130984585/ その5 pc11.2ch.net/test/read.cgi/tech/1157814833/ OS・言語・環境は問わないが、それゆえ明記すべし。 テンプレ 【OS】 【言語】 【実行環境】 【その他突起する事項】
2 名前:デフォルトの名無しさん mailto:sage [2007/08/13(月) 21:37:27 ] > 関連スレ > > 【マルチコア】並列化について語る【使いこなせ】 > pc8.2ch.net/test/read.cgi/tech/1137540671/ > > pthread地獄 (UNIX板) > pc8.2ch.net/test/read.cgi/unix/1010933537/ > > > 関連しやすいので一応 > > ネットワークプログラミング相談室 Port17 > pc8.2ch.net/test/read.cgi/tech/1148944560/l50 > > 書籍とかはもういいでしょ コピペ ちなみに俺はマルチスレッドプログラミングなんてやらない 非ブロッキングとポーリング推奨派だ
3 名前:デフォルトの名無しさん mailto:sage [2007/08/14(火) 00:05:04 ] >>2 最新のスレはこちら pthread地獄 part 2 pc11.2ch.net/test/read.cgi/unix/1166620307/ ネットワークプログラミング相談室 Port20 pc11.2ch.net/test/read.cgi/tech/1186418855/
4 名前:デフォルトの名無しさん mailto:sage [2007/08/14(火) 14:16:43 ] 2チャンネルもマルチスレッドですね!
5 名前:デフォルトの名無しさん [2007/08/14(火) 18:31:20 ] Symbianケータイで初めて、同期/非同期ってのやったけど、 わけわからんかったなぁ・・・
6 名前:デフォルトの名無しさん mailto:sage [2007/08/14(火) 18:40:15 ] マルチスレッドアプリの設計パターンを学ぶのに良い本orサイトありませんか できれば対象言語はC++/Posixでおねがいします
7 名前:デフォルトの名無しさん mailto:sage [2007/08/14(火) 19:20:17 ] 設計を学ぶのに言語なんか関係ないと思うが。 それとも実装を学びたいの?
8 名前:デフォルトの名無しさん mailto:sage [2007/08/14(火) 20:48:20 ] >>6 Java言語で学ぶデザインパターン入門 マルチスレッド編 結城 浩 (著) Java並行処理プログラミング ―その「基盤」と「最新API」を究める Brain Goetz (著), Joshua Bloch (著), Doug Lea (著) どちらもJavaだけど、現時点でマルチスレッドを学ぶのに 一番適した環境はJavaだと思うので、この辺がオススメ。 C++で使いたいならC++の水準に落とすだけなので損はない。 後者は必ずしも必要ではない情報だと思うけど、 Javaではpthreadより低水準も高水準もカバーできる環境で、 その詳細な内容まで触れられているので参考になると思う。
9 名前:デフォルトの名無しさん mailto:sage [2007/08/15(水) 00:43:26 ] >>7 いや他の言語知らないのでサンプルソースとかが読めないと辛いかなと >>8 レスありがとう。やっぱりJavaになってしまうのか 本屋で手にとって確認してみます
10 名前:デフォルトの名無しさん mailto:sage [2007/08/15(水) 10:44:23 ] 下のやつは、かなりおすすめ。
11 名前:デフォルトの名無しさん mailto:sage [2007/08/15(水) 13:24:39 ] つかさ、やっぱ推薦図書テンプレ化した方がいいんでね?
12 名前:デフォルトの名無しさん mailto:sage [2007/08/15(水) 22:10:23 ] >>6 プログラムデザインのためのパターン言語 ソフトバンク刊
13 名前:デフォルトの名無しさん mailto:sage [2007/08/16(木) 00:26:07 ] ねぇねぇ メモリブロックとCASの順序ってどうすればいいの? mb() CAS() mb() って感じでいいの? あと、マルチスレッドでアルゴリズムが正しいか検証する場合って みんなどうしてる?長い時間動かして動いてるor正しそうだからオケって 感じ?それともなんかtool使ってるの?
14 名前:デフォルトの名無しさん mailto:sage [2007/08/16(木) 01:04:34 ] 競合がおこりそうな状況を作ってぶん回すのはやる それ以上はどうだろう・・・
15 名前:デフォルトの名無しさん mailto:sage [2007/08/16(木) 02:29:15 ] CASやるときはメモリバリア要らないと思う でもまぁ環境分からないし、プロセッサのマニュアルを確認してくれとしか 検証はどうするんだろうねぇ・・・
16 名前:デフォルトの名無しさん mailto:sage [2007/08/16(木) 03:12:35 ] >>13 CASの対象にメモリバリアが必要だったら意味がないと思う。 事前の読み込み前に同期させたいなら話は別だが。
17 名前:デフォルトの名無しさん mailto:sage [2007/08/16(木) 21:25:12 ] mutexのロック回数とか計測したいときってみんなどうしてるの? 目視w?
18 名前:デフォルトの名無しさん mailto:sage [2007/08/16(木) 21:50:45 ] なんらかの監視機構を利用する。
19 名前:デフォルトの名無しさん mailto:sage [2007/08/16(木) 22:10:02 ] いまどきのJVMでの競合のないロックって、 CAS2回程度だったりするってどっかで聞いたけど。 ぶっちゃけ下手なことするくらいならロックのがましじゃね?
20 名前:デフォルトの名無しさん mailto:sage [2007/08/16(木) 22:17:52 ] >>19 競合の可能性が高くなければlock freeにするメリットは低い。 ほとんどの場合はロックの方が検証の意味で安全、確実。
21 名前:デフォルトの名無しさん mailto:sage [2007/08/16(木) 22:50:57 ] いまどきのJVMがどのような実装になってるもんなのか知らないけど、 たとえば.NETだと、標準のlockはCASとスピンウェイトでそれでも競合したときだけ スレッドの切り替えが起こるような実装になってると読んだ。 で競合がない場合はlock取得と開放でCAS2回だと。 これだとlock内での操作が非常に少ない場合、ほとんどlockでいい気がする。
22 名前:デフォルトの名無しさん mailto:sage [2007/08/16(木) 22:53:14 ] ああ、要は、下手にlockフリーにしようとしてCAS操作を何回もやってしまうような実装だと、 何も考えずにlockしたほうがましってことね。
23 名前:デフォルトの名無しさん mailto:sage [2007/08/16(木) 23:11:24 ] 吉野家コピペと一緒。 両刃の剣。素人(ry STMが一般的になれば話は変わってくるんだろうね。
24 名前:デフォルトの名無しさん mailto:sage [2007/08/17(金) 07:50:21 ] ___ / \ クスクスッ /ノ \ u. \ !? / (●) (●) \ | (__人__) u. | \ u.` ⌒´ / ____ / \!?? / u ノ \ クスクスッ / u (●) \ | (__人__)| \ u .` ⌒/ ____ / \ /\ キリッ . / (ー) (ー)\ / ⌒(__人__)⌒ \ | |r┬-| | \ `ー'´ /
25 名前:デフォルトの名無しさん mailto:sage [2007/08/17(金) 21:11:28 ] using System; using System.Threading; public class CyclicBuffer<T> where T : class { private static readonly bool s_multiProcsessors = Environment.ProcessorCount > 1; private volatile int m_head; private int m_reserve; private int m_tail; private readonly T[] m_buffer; CyclicBuffer(int capacity) { m_buffer = new T[capacity + 1]; } public bool Enqueue(T value) { int current; int next; do { Thread.MemoryBarrier(); current = m_reserve; next = NextIndex(current); if (next == m_tail) return false; } while (Interlocked.CompareExchange(ref m_reserve, next, current) != current); while (m_head != current || m_buffer[next] != null) Wait(); m_buffer[next] = value; m_head = next; return true; }
26 名前:デフォルトの名無しさん mailto:sage [2007/08/17(金) 21:11:58 ] 続き public T Dequeue() { int current; int next; do { Thread.MemoryBarrier(); current = m_tail; if (current == m_reserve) return null; next = NextIndex(current); } while (Interlocked.CompareExchange(ref m_tail, next, current) != current); while (m_head < current) Wait(); T value = m_buffer[current]; m_buffer[current] = null; Thread.MemoryBarrier(); return value; } private int NextIndex(int current) { return ++current == m_buffer.Length ? 0 : current; } private static void Wait() { if (s_multiProcsessors) Thread.SpinWait(400); else Thread.Sleep(0); } }
27 名前:デフォルトの名無しさん mailto:sage [2007/08/17(金) 21:13:09 ] ああそうそう、超未検証なのであしからず。 ついでに.NETだが。
28 名前:デフォルトの名無しさん mailto:sage [2007/08/17(金) 21:48:14 ] バグだらけだったよママン Enqueueは下の間違いわはは たぶんまだバグだらけだなこれは public bool Enqueue(T value) { int current; int next; do { Thread.MemoryBarrier(); current = m_reserve; next = NextIndex(current); if (next == m_tail) return false; } while (Interlocked.CompareExchange(ref m_reserve, next, current) != current); while (m_head != current || m_buffer[current] != null) Wait(); m_buffer[current] = value; m_head = next; return true; }
29 名前:デフォルトの名無しさん mailto:sage [2007/08/17(金) 22:03:14 ] ちょっとおおぼけかましてたので再度 using System; using System.Threading; public class CyclicBuffer<T> where T : class { private static readonly bool s_multiProcsessors = Environment.ProcessorCount > 1; private int m_head; private int m_tail; private readonly T[] m_buffer; public CyclicBuffer(int capacity) { m_buffer = new T[capacity + 1]; } public bool Enqueue(T value) { int current; int next; do { Thread.MemoryBarrier(); current = m_head; next = NextIndex(current); if (next == m_tail) return false; } while (Interlocked.CompareExchange(ref m_head, next, current) != current); while (m_buffer[current] != null) Wait(); m_buffer[current] = value; return true; }
30 名前:デフォルトの名無しさん mailto:sage [2007/08/17(金) 22:04:00 ] 続き public T Dequeue() { int current; int next; do { Thread.MemoryBarrier(); current = m_tail; if (current == m_head) return null; next = NextIndex(current); } while (Interlocked.CompareExchange(ref m_tail, next, current) != current); T value; while ((value = m_buffer[current]) == null) Wait(); m_buffer[current] = null; Thread.MemoryBarrier(); return value; } private int NextIndex(int current) { return ++current == m_buffer.Length ? 0 : current; } private static void Wait() { if (s_multiProcsessors) Thread.SpinWait(400); else Thread.Sleep(0); Thread.MemoryBarrier(); } } もうだめかもorz
31 名前:デフォルトの名無しさん mailto:sage [2007/08/17(金) 22:16:41 ] そしてlockと比べて30%かせいぜい40%程度しか変わらんかったw まあシングルコア、シングルプロセッサの環境だからそもそもまともに試せんがw
32 名前:デフォルトの名無しさん mailto:sage [2007/08/17(金) 22:53:59 ] メモリバリアやめて変数自体volatileにしたら lockと比べて3〜4倍速くなったバロス。
33 名前:デフォルトの名無しさん mailto:sage [2007/08/17(金) 23:16:37 ] つまらないからどうでもいいんだが 性能比べるなら最低4CPUで 4から128スレッドまで生成してテストしてくれないかな?
34 名前:デフォルトの名無しさん mailto:sage [2007/08/17(金) 23:24:10 ] そんなマシンねーんだよ誰かくれ暮れ。 まあそれを言うなら前すれのjavaのを見てみたいがな。 VMのバージョン依存が大きそうだが 新しい環境ならたぶんsynchronizedのが早いんじゃね?
35 名前:デフォルトの名無しさん mailto:sage [2007/08/18(土) 00:34:54 ] CAS利用したアルゴリズム扱ってる洋書しらん? 和書クソいらん。
36 名前:デフォルトの名無しさん mailto:sage [2007/08/18(土) 00:41:12 ] 和書→(excite)→
37 名前:デフォルトの名無しさん mailto:sage [2007/08/18(土) 11:21:58 ] using System; using System.Threading; public class CyclicBuffer<T> where T : class { private volatile int m_head; private volatile int m_tail; private volatile T[] m_buffer; public CyclicBuffer(int capacity) { m_buffer = new T[capacity + 1]; } public bool Enqueue(T value) { if (value == null) throw new ArgumentNullException("value"); int current; int next; do { current = m_head; next = current + 1 == m_buffer.Length ? 0 : current + 1; if (next == m_tail || m_buffer[current] != null) return false; } while (Interlocked.CompareExchange(ref m_head, next, current) != current); m_buffer[current] = value; return true; }
38 名前:デフォルトの名無しさん mailto:sage [2007/08/18(土) 11:22:38 ] public T Dequeue() { int current; int next; do { current = m_tail; if (current == m_head || m_buffer[current] == null) return null; next = current + 1 == m_buffer.Length ? 0 : current + 1; } while (Interlocked.CompareExchange(ref m_tail, next, current) != current); T value = m_buffer[current]; m_buffer[current] = null; return value; } }
39 名前:デフォルトの名無しさん mailto:sage [2007/08/18(土) 11:47:32 ] 今度こそ最後、汎用化バージョン(structでもOK) using System; using System.Threading; public class CyclicBuffer<T> { private volatile int m_head; private volatile int m_tail; private readonly Entry[] m_buffer; public CyclicBuffer(int capacity) { m_buffer = new Entry[capacity + 1]; } public bool Enqueue(T value) { if (value == null) throw new ArgumentNullException("value"); int current; int next; do { current = m_head; next = current + 1 == m_buffer.Length ? 0 : current + 1; if (next == m_tail || m_buffer[current].Stored) return false; } while (Interlocked.CompareExchange(ref m_head, next, current) != current); m_buffer[current].Value = value; m_buffer[current].Stored = true; return true; }
40 名前:デフォルトの名無しさん mailto:sage [2007/08/18(土) 11:48:16 ] public bool Dequeue(out T value) { int current; int next; do { current = m_tail; if (current == m_head || !m_buffer[current].Stored) { value = default(T); return false; } next = current + 1 == m_buffer.Length ? 0 : current + 1; } while (Interlocked.CompareExchange(ref m_tail, next, current) != current); value = m_buffer[current].Value; m_buffer[current].Value = default(T); m_buffer[current].Stored = false; return true; } private struct Entry { public T Value; public volatile bool Stored; } } しつこくてすまんのう
41 名前:デフォルトの名無しさん mailto:sage [2007/08/18(土) 12:29:09 ] C#には詳しくないのであれだが, >public bool Dequeue(out T value) なんとなく使いにくそう (´・ω・`)
42 名前:デフォルトの名無しさん mailto:sage [2007/08/18(土) 13:09:23 ] うん、使いにくい。 でもintとかの値型が対象のときはこうなってないと対応できないんだよね。 まあ、デフォルト値をパラメータで指定するとかって方法もあるにはあるが。
43 名前:デフォルトの名無しさん mailto:sage [2007/08/18(土) 13:14:40 ] これでCAS操作一回ずつと後はvolatileアクセスだけなので マルチプロセッサ環境でもうまくスケールするかな… シングルの環境では、lockよりも4〜5倍程度速い感じ。
44 名前:デフォルトの名無しさん mailto:sage [2007/08/18(土) 14:58:22 ] ネタにマジレスするのはどうかと思うが これ整合性とれてねーじゃんw 不完全だろw
45 名前:デフォルトの名無しさん mailto:sage [2007/08/18(土) 15:02:59 ] 整合性ってなあに…?(´・ω・`)
46 名前:デフォルトの名無しさん mailto:sage [2007/08/18(土) 16:35:10 ] 不完全ってなあに…?(´・ω・`)
47 名前:デフォルトの名無しさん mailto:sage [2007/08/18(土) 17:22:59 ] マジネタにネタレスしたんだろ
48 名前:デフォルトの名無しさん mailto:sage [2007/08/18(土) 17:57:25 ] こういうの微妙に不思議なんだけど、 シングルプロセッサ環境でも複数スレッドの方が速くなるのな。 なんでだろ?.NET環境特有の現象? 1スレッドと10スレッドでトータルの実行時間は3倍くらいにしかならない。 100スレッドだとせいぜい20倍くらい、つまり5倍くらいスループットが上がる。
49 名前:デフォルトの名無しさん mailto:sage [2007/08/18(土) 18:05:22 ] それどんなプログラム?
50 名前:デフォルトの名無しさん mailto:sage [2007/08/18(土) 18:20:44 ] 上のやつとか。 CPU(とメモリ)依存処理ばかりなのになんでだろう。
51 名前:デフォルトの名無しさん mailto:sage [2007/08/18(土) 18:43:55 ] ソースアップしてくれんとわからんね。起動やJITにかかってる時間も含んでる?
52 名前:デフォルトの名無しさん mailto:sage [2007/08/18(土) 19:00:11 ] 計測は、できるだけ実際の実行部分だけになるように 一応注意してやってはいるんだけどねぇ。 今外なのでソースは出せんが、ゲートとカウントダウンラッチ使って 間の時間を計測してる。計測精度は問題ないものを使ってる。StopWatchね。 ラッチは自作だけど、100万回ループの最初と最後だから 実装がいまいちでもまあそれほど大きな影響はないはず。 スレッドが多いほど処理スレッドに割り当てられるCPU時間が ある程度は増えるかも知れないが、5倍てのはそういう問題の範囲じゃないと思うんだよね。
53 名前:デフォルトの名無しさん mailto:sage [2007/08/18(土) 19:06:12 ] >>39-40 物凄くレアなケースだが、いわゆるABA問題にハマる可能性があるよね。 キューが空のときに、Enqueue()の > if (next == m_tail || m_buffer[current].Stored) return false; の行の実行が終わった直後にコンテキストスイッチが入るなどして、次の > } while (Interlocked.CompareExchange(ref m_head, next, current) != current); が実行されるまでの間に別スレッドがcapacity + 1回のEnqueue()と1回のDequeue()を行ったとすると、 キューが満杯なのにCompareExchangeが成功してしまう。 同じことはDequeue()側でも起こりうるね。(キューが満杯のとき、Dequeue()内のif文と CompareExchangeの間で別スレッドがcapacity + 1回のDequeue()と1回のEnqueue()を行った場合とか) こういう問題への対策法としては、capacityを十分大きくしておくくらいしか 思いつかないけど……
54 名前:デフォルトの名無しさん mailto:sage [2007/08/18(土) 19:08:40 ] windowsアプリでやってるので、後でコンソールでも試してみよう。 あとは、スレッド1このときにメインスレッドで直接実行してどうなるか、かな。
55 名前:デフォルトの名無しさん mailto:sage [2007/08/18(土) 19:12:59 ] >>53 なるほど、ちゃんと考えてないけど確かになりそうだ。 やっぱ更新バージョンが必要になるのかなぁ…
56 名前:デフォルトの名無しさん mailto:sage [2007/08/18(土) 19:24:54 ] いや、更新バージョンじゃだめだな。 インデックスの扱いを工夫、かな。
57 名前:デフォルトの名無しさん mailto:sage [2007/08/18(土) 20:01:55 ] つーかみんな論文とか読んで先人はどう工夫した かぐらい考えてからソースコードかけよなぁ
58 名前:デフォルトの名無しさん mailto:sage [2007/08/18(土) 23:11:48 ] Advanced Windows ttp://www.amazon.co.jp/Advanced-Windows-改訂第4版-ジェフリー-リッチャー/dp/4756138055 この本、よんだことある人いる? C,C++でマルチスレッド組むのに有用な本なんだそうなんだが、いかんせん値段が・・・
59 名前:デフォルトの名無しさん mailto:sage [2007/08/18(土) 23:19:18 ] >>53 変数は配列長の整数倍でできるだけ長い周期でループするようにして、 インデックス使用時に配列長で剰余をとるようにしたら、結構遅くなったw インデックスで必要なビット長を求めて、残りの上位ビットを サイクル数のカウンタとして使用するようにしたらだいぶ速くなった。 前のよりは1割程度遅くなったが、ここらでいっぱいいっぱいかな。
60 名前:デフォルトの名無しさん mailto:sage [2007/08/18(土) 23:22:14 ] >>59 そんな申し訳ないことして実際どれぐらい役に立つのw オナニーバイナリ生成ぐらいがいいとこだよね?
61 名前:デフォルトの名無しさん mailto:sage [2007/08/18(土) 23:24:52 ] 日本語でOK お前さんは役に立たないことは一切やらないのかね?
62 名前:デフォルトの名無しさん mailto:sage [2007/08/18(土) 23:26:20 ] まあいろんなものを実装する練習になるから まったく役に立たないわけでもないんだけどな。
63 名前:デフォルトの名無しさん mailto:sage [2007/08/18(土) 23:29:52 ] >>62 中途半端にかじった奴が糞コード晒すのとどうか思うのだが? 使えるならまだしも危険すぎだろwこんな糞コードしかかけないんだから 止めろよ。ゆとり夏房は本当に困る
64 名前:デフォルトの名無しさん mailto:sage [2007/08/18(土) 23:33:46 ] どしたん?
65 名前:デフォルトの名無しさん mailto:sage [2007/08/18(土) 23:37:30 ] >>63 「これこれの理由で危険だから使わないように」とでもコメントすれば済むことではないかと。
66 名前:デフォルトの名無しさん mailto:sage [2007/08/18(土) 23:41:35 ] 糞なとこを指摘してやれば役にも立つのに。 >使えるならまだしも危険すぎだろw いや誰も実際に使おうなんてやつはいないだろw
67 名前:デフォルトの名無しさん mailto:sage [2007/08/18(土) 23:45:42 ] >>66 こういうものは指摘しても理解できないだろ? 俺はこんなコード書くやつがまともな姿をした 人間だとはとても思えないんだよ。
68 名前:デフォルトの名無しさん mailto:sage [2007/08/18(土) 23:52:36 ] >>59 ていうか配列長を2の冪乗に切り上げておけば、 ビットマスクとのAND演算だけで済むでしょ。
69 名前:デフォルトの名無しさん mailto:sage [2007/08/19(日) 00:01:21 ] それは思ったが、無駄が多かったのと、キャパとの兼ね合いで 空もしくは一杯の判定が微妙にややこしくなりそうなのでやめた。 でも確かにサイクルカウントを上位ビットに持つよりはずっと単純だったかも試練。
70 名前:68 mailto:sage [2007/08/19(日) 00:10:34 ] >>69 いや、capacityも配列長に合わせて切り上げちゃっていいんじゃない? どうせパフォーマンス重視なんだから、capacityなんて厳密に扱う必要はないと思うが。
71 名前:デフォルトの名無しさん mailto:sage [2007/08/19(日) 00:21:34 ] うーん、容量固定のキューだったからね、今回はこれは変えたらだめかなって勝手に。 まあ、実際にこんなものを作ることがあったらそうすると思う。
72 名前:デフォルトの名無しさん mailto:sage [2007/08/19(日) 05:21:55 ] >>67 >こういうものは指摘しても理解できないだろ? ここは相談室なんだから、相談相手になる気がないなら他へどうぞ
73 名前:デフォルトの名無しさん mailto:sage [2007/08/19(日) 09:11:12 ] >>58 マルチスレッドに限らず、Windowsプログラミング全般においてその本は とても有用なので、買って損はないよ。 ただし、各種オブジェクト単体での深い説明が中心で、スレッドの作法だとか そんな話は皆無で、マルチスレッドの入門書として期待しているなら やめた方がいい。 例えば、クリティカルセクションが他の同期オブジェクトよりも軽いという点について、 OS内部でどう実装されているのかという話が書いてある。 マルチスレッドの話が読みたいなら「Win32マルチスレッドプログラミング」の方が いいと思う。(俺は見たことないが)
74 名前:デフォルトの名無しさん mailto:sage [2007/08/19(日) 19:00:00 ] >>67 なにまともなフリをしてんだおまえはw
75 名前:デフォルトの名無しさん mailto:sage [2007/08/19(日) 19:04:25 ] でどの辺が糞コードでどの辺が中途半端にかじったぽいのか早く教えて
76 名前:デフォルトの名無しさん mailto:sage [2007/08/20(月) 14:15:47 ] この絡み方厨房の典型だなw
77 名前:デフォルトの名無しさん mailto:sage [2007/08/20(月) 14:18:42 ] そうやってすぐ厨房扱いする奴も大して変わらん
78 名前:デフォルトの名無しさん mailto:sage [2007/08/20(月) 16:45:02 ] 厨房に厨房が返してるだけだろ
79 名前:デフォルトの名無しさん mailto:sage [2007/08/22(水) 22:21:13 ] mutexが永田ロックかけてるのか まだロックかけないで痛めつけてるのか 計測するほうほうないですか? pthreadでお願いします。
80 名前:デフォルトの名無しさん mailto:sage [2007/08/26(日) 21:42:55 ] C言語歴15年とかいう人が ローカルにコピーすれば以下のような コードがOKだと主張するのですが本当なのw? struct data{ int len; char buf[128]; } struct data[6]; int index; これをグローバルで定義しておいて void *thread_1(void *arg){ data[index]; //データ書き込み処理 index++; } void *thread_2(void *arg){ int l_index = index; //データ読み込み処理 } 絶対 indexをローカル変数に代入して 順番考慮してないから2回処理しそうな 気がするんだけどさー なんかこんな人のプログラム見るのやだ 逃げたいタスケテ
81 名前:デフォルトの名無しさん mailto:sage [2007/08/26(日) 21:48:16 ] >>80 実はスレッドでなくファイバだったとか。
82 名前:デフォルトの名無しさん mailto:sage [2007/08/26(日) 21:50:26 ] HPの鯖でpthread使って書いてますけど ファイバってことはありえないですよねw? まじ釣りとかじゃなくて本気でこんなコード生成 するんですよ。困ってる
83 名前:デフォルトの名無しさん mailto:sage [2007/08/26(日) 21:53:21 ] >>80 オマエの日本語やコードの貼り方も相当なもんだ。困ってる
84 名前:デフォルトの名無しさん mailto:sage [2007/08/26(日) 21:53:47 ] ごめん許してくれ
85 名前:デフォルトの名無しさん mailto:sage [2007/08/26(日) 21:55:27 ] マ板向けの話題かな
86 名前:デフォルトの名無しさん mailto:sage [2007/08/26(日) 21:56:49 ] これって絶対ネタだよな 馬鹿でも考えりゃ排他必要な事解かると
87 名前:デフォルトの名無しさん mailto:sage [2007/08/26(日) 22:03:55 ] 満を持してvolatileの登場だな
88 名前:デフォルトの名無しさん mailto:sage [2007/08/26(日) 22:06:04 ] >>87 それもネタだろw
89 名前:デフォルトの名無しさん mailto:sage [2007/08/26(日) 22:51:08 ] >>80 悪いがそのコードの意味がわからなくてなんとも胃炎。
90 名前:デフォルトの名無しさん mailto:sage [2007/08/26(日) 23:06:45 ] >>89 文脈から想像して、 int l_index = index; このようにindexをローカル変数にコピーしてから、そのコピーを使って 配列参照すればロックとかいらない、とC言語歴15年さんが主張している。 と読んだ。 ただ、コードは明らかに抜粋なので、状況によってはOKなのかも知れない可能性はある。 thread_1がデータの更新処理で、thread_2は現在の最新データを取得するだけ、 配列は十分に大きく、データの空チェックは別にあるとか。 あるいは、thread_1とthread_2でキューを実現しようとしているなら問題だけど、その場合も コードが断片すぎるので、前後の記述によっては問題ないかもしれず。 それを含めて>>80 が明らかな問題であることを認識した上で書き込んでいるなら、 最初からマ板に行くべきかと。
91 名前:デフォルトの名無しさん mailto:sage [2007/08/26(日) 23:14:21 ] >>90 SMPなんかでCPU入れ替わったら 問題おきないかなぁ?
92 名前:デフォルトの名無しさん mailto:sage [2007/08/26(日) 23:22:06 ] >>90 キューなどの順序性保証が必要なものだとあきからにやばいけど、 掲示板などに書き込まれたデータの最新の1レコードを定期的に 表示更新っていうパターン(厳密な意味での最新版にはこだわらないもの) なら、volatileのレベルで妥協できる場合もあるんじゃないかって 思ったんだけど。 thread_2の例が現状のindexをいじらずに現時点のindexのレコード参照 しているだけみたいだから。
93 名前:デフォルトの名無しさん mailto:sage [2007/08/26(日) 23:26:28 ] 絶対2回読む可能性捨てきれないし こんな実装商用レベルでしないよなぁ きっとどっかの研究室だろうなぁ。 教授が書いたコードだから絶対だみたいな感じなんだろうなぁ
94 名前:デフォルトの名無しさん mailto:sage [2007/08/27(月) 11:03:22 ] それならまさに発見的手法だな
95 名前:デフォルトの名無しさん mailto:sage [2007/08/28(火) 22:57:45 ] 【OS】 WinXP SP2 【言語】 VC8 【実行環境】 2000以降、可能であれば9x以降 【その他突起する事項】 C++ソースコード上での解決が望ましい TerminateThreadだと、終了させたいスレッドのハンドルがあればスレッドを終わらせる事ができますが、 これは基本的に最終手段としてスレッドを終わらせる為の物で、初期のスタック割り当てを解除する機会がなかったり、色々問題があるようです。 なので、スレッド外部からExitThreadの様にスレッドを終わらせるにはどうすればいいんでしょうか。 対象のスレッド内で、終了される"かもしれない"タイミングは把握可能です。
96 名前:デフォルトの名無しさん mailto:sage [2007/08/28(火) 23:10:34 ] 終了フラグを用意して、スレッドが終わって欲しくなったらフラグを立てる。 対象スレッド内で、今だったら別に終了してやってもいいというタイミングで、フラグをチェックして自主的に終了する。 フラグの読み書きは、ちゃんとクリティカルセクションやミューテックスで囲むか、インターロック関数を使うか、メモリバリアを張ること。
97 名前:デフォルトの名無しさん mailto:sage [2007/08/28(火) 23:11:47 ] ・終われフラグなりイベントなりを用意 ・要所要所でフラグ/イベントをチェックしてオレオレ例外をthrow ・スレッドの開始点でtry〜catch でとりあえずできる 他のやり方でも結局こうなると思う コールスタックにC関数が挟まるとダメな場合もあるので注意
98 名前:.95 mailto:sage [2007/08/28(火) 23:18:11 ] Sleepしてる間に終わらせるフラグが立つので、待ち時間が長いです...
99 名前:デフォルトの名無しさん mailto:sage [2007/08/28(火) 23:25:03 ] >>95 メッセージなり何なりを対象スレッドに投げて、対象スレッドに自ら涅槃の道に旅立ってもらう。
100 名前:デフォルトの名無しさん mailto:sage [2007/08/28(火) 23:44:30 ] >>98 Sleepを細かく分ければいい。 for (int i=0; i < 10; ++i) { Sleep(100); check_exit_flag(); } こういうポーリングがいやならEventつかって待機関数で待つとか
101 名前:デフォルトの名無しさん mailto:sage [2007/08/29(水) 08:59:33 ] 【OS】 Xp sp2 【言語】 VBA 【実行環境】 Q6600 VBAってマルチスレッドできないともできるとも明記されていないんです。 質問なんですが、VBAにかかわらずマルチスレッド化によって、『比較的発生しやすい障害』というのは何でしょうか? C等ならPUSH、POP等のメモリ操作がいちばん気をつかいそうなところですよね。 VBAでは、適所に Do Eventを2つ入れること(実験により1つではエラー起きやすい)、変数のグローバル宣言にきをつけること(2つのスレッドで同じ変数を呼ばない)ことくらいですかね。プロシージャーは同時に使っても今のところ問題ありません。 どうぞよろしくお願いします。
102 名前:デフォルトの名無しさん mailto:sage [2007/08/29(水) 10:07:45 ] >【言語】 VBA >VBAにかかわらず どっちだよ