マルチスレッドプログラミング相談室 その6
at TECH
1:デフォルトの名無しさん
07/08/13 21:35:32
マルチスレッドプログラミングについて語るスレ。
その1 URLリンク(pc3.2ch.net)
その2 スレリンク(tech板)
その3 スレリンク(tech板)
その4 スレリンク(tech板)
その5 スレリンク(tech板)
OS・言語・環境は問わないが、それゆえ明記すべし。
テンプレ
【OS】
【言語】
【実行環境】
【その他突起する事項】
2:デフォルトの名無しさん
07/08/13 21:37:27
> 関連スレ
>
> 【マルチコア】並列化について語る【使いこなせ】
> スレリンク(tech板)
>
> pthread地獄 (UNIX板)
> スレリンク(unix板)
>
>
> 関連しやすいので一応
>
> ネットワークプログラミング相談室 Port17
> スレリンク(tech板)l50
>
> 書籍とかはもういいでしょ
コピペ
ちなみに俺はマルチスレッドプログラミングなんてやらない
非ブロッキングとポーリング推奨派だ
3:デフォルトの名無しさん
07/08/14 00:05:04
>>2
最新のスレはこちら
pthread地獄 part 2
スレリンク(unix板)
ネットワークプログラミング相談室 Port20
スレリンク(tech板)
4:デフォルトの名無しさん
07/08/14 14:16:43
2チャンネルもマルチスレッドですね!
5:デフォルトの名無しさん
07/08/14 18:31:20
Symbianケータイで初めて、同期/非同期ってのやったけど、
わけわからんかったなぁ・・・
6:デフォルトの名無しさん
07/08/14 18:40:15
マルチスレッドアプリの設計パターンを学ぶのに良い本orサイトありませんか
できれば対象言語はC++/Posixでおねがいします
7:デフォルトの名無しさん
07/08/14 19:20:17
設計を学ぶのに言語なんか関係ないと思うが。
それとも実装を学びたいの?
8:デフォルトの名無しさん
07/08/14 20:48:20
>>6
Java言語で学ぶデザインパターン入門 マルチスレッド編
結城 浩 (著)
Java並行処理プログラミング ―その「基盤」と「最新API」を究める
Brain Goetz (著), Joshua Bloch (著), Doug Lea (著)
どちらもJavaだけど、現時点でマルチスレッドを学ぶのに
一番適した環境はJavaだと思うので、この辺がオススメ。
C++で使いたいならC++の水準に落とすだけなので損はない。
後者は必ずしも必要ではない情報だと思うけど、
Javaではpthreadより低水準も高水準もカバーできる環境で、
その詳細な内容まで触れられているので参考になると思う。
9:デフォルトの名無しさん
07/08/15 00:43:26
>>7
いや他の言語知らないのでサンプルソースとかが読めないと辛いかなと
>>8
レスありがとう。やっぱりJavaになってしまうのか
本屋で手にとって確認してみます
10:デフォルトの名無しさん
07/08/15 10:44:23
下のやつは、かなりおすすめ。
11:デフォルトの名無しさん
07/08/15 13:24:39
つかさ、やっぱ推薦図書テンプレ化した方がいいんでね?
12:デフォルトの名無しさん
07/08/15 22:10:23
>>6
プログラムデザインのためのパターン言語
ソフトバンク刊
13:デフォルトの名無しさん
07/08/16 00:26:07
ねぇねぇ
メモリブロックとCASの順序ってどうすればいいの?
mb()
CAS()
mb()
って感じでいいの?
あと、マルチスレッドでアルゴリズムが正しいか検証する場合って
みんなどうしてる?長い時間動かして動いてるor正しそうだからオケって
感じ?それともなんかtool使ってるの?
14:デフォルトの名無しさん
07/08/16 01:04:34
競合がおこりそうな状況を作ってぶん回すのはやる
それ以上はどうだろう・・・
15:デフォルトの名無しさん
07/08/16 02:29:15
CASやるときはメモリバリア要らないと思う
でもまぁ環境分からないし、プロセッサのマニュアルを確認してくれとしか
検証はどうするんだろうねぇ・・・
16:デフォルトの名無しさん
07/08/16 03:12:35
>>13
CASの対象にメモリバリアが必要だったら意味がないと思う。
事前の読み込み前に同期させたいなら話は別だが。
17:デフォルトの名無しさん
07/08/16 21:25:12
mutexのロック回数とか計測したいときってみんなどうしてるの?
目視w?
18:デフォルトの名無しさん
07/08/16 21:50:45
なんらかの監視機構を利用する。
19:デフォルトの名無しさん
07/08/16 22:10:02
いまどきのJVMでの競合のないロックって、
CAS2回程度だったりするってどっかで聞いたけど。
ぶっちゃけ下手なことするくらいならロックのがましじゃね?
20:デフォルトの名無しさん
07/08/16 22:17:52
>>19
競合の可能性が高くなければlock freeにするメリットは低い。
ほとんどの場合はロックの方が検証の意味で安全、確実。
21:デフォルトの名無しさん
07/08/16 22:50:57
いまどきのJVMがどのような実装になってるもんなのか知らないけど、
たとえば.NETだと、標準のlockはCASとスピンウェイトでそれでも競合したときだけ
スレッドの切り替えが起こるような実装になってると読んだ。
で競合がない場合はlock取得と開放でCAS2回だと。
これだとlock内での操作が非常に少ない場合、ほとんどlockでいい気がする。
22:デフォルトの名無しさん
07/08/16 22:53:14
ああ、要は、下手にlockフリーにしようとしてCAS操作を何回もやってしまうような実装だと、
何も考えずにlockしたほうがましってことね。
23:デフォルトの名無しさん
07/08/16 23:11:24
吉野家コピペと一緒。
両刃の剣。素人(ry
STMが一般的になれば話は変わってくるんだろうね。
24:デフォルトの名無しさん
07/08/17 07:50:21
___
/ \
クスクスッ /ノ \ u. \ !?
/ (●) (●) \
| (__人__) u. |
\ u.` ⌒´ /
____
/ \!??
/ u ノ \ クスクスッ
/ u (●) \
| (__人__)|
\ u .` ⌒/
____
/ \ /\ キリッ
. / (ー) (ー)\
/ ⌒(__人__)⌒ \
| |r┬-| |
\ `ー'´ /
25:デフォルトの名無しさん
07/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:デフォルトの名無しさん
07/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:デフォルトの名無しさん
07/08/17 21:13:09
ああそうそう、超未検証なのであしからず。
ついでに.NETだが。
28:デフォルトの名無しさん
07/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:デフォルトの名無しさん
07/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:デフォルトの名無しさん
07/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:デフォルトの名無しさん
07/08/17 22:16:41
そしてlockと比べて30%かせいぜい40%程度しか変わらんかったw
まあシングルコア、シングルプロセッサの環境だからそもそもまともに試せんがw
32:デフォルトの名無しさん
07/08/17 22:53:59
メモリバリアやめて変数自体volatileにしたら
lockと比べて3〜4倍速くなったバロス。
33:デフォルトの名無しさん
07/08/17 23:16:37
つまらないからどうでもいいんだが
性能比べるなら最低4CPUで
4から128スレッドまで生成してテストしてくれないかな?
34:デフォルトの名無しさん
07/08/17 23:24:10
そんなマシンねーんだよ誰かくれ暮れ。
まあそれを言うなら前すれのjavaのを見てみたいがな。
VMのバージョン依存が大きそうだが
新しい環境ならたぶんsynchronizedのが早いんじゃね?
35:デフォルトの名無しさん
07/08/18 00:34:54
CAS利用したアルゴリズム扱ってる洋書しらん?
和書クソいらん。
36:デフォルトの名無しさん
07/08/18 00:41:12
和書→(excite)→
37:デフォルトの名無しさん
07/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:デフォルトの名無しさん
07/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:デフォルトの名無しさん
07/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:デフォルトの名無しさん
07/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:デフォルトの名無しさん
07/08/18 12:29:09
C#には詳しくないのであれだが,
>public bool Dequeue(out T value)
なんとなく使いにくそう (´・ω・`)
42:デフォルトの名無しさん
07/08/18 13:09:23
うん、使いにくい。
でもintとかの値型が対象のときはこうなってないと対応できないんだよね。
まあ、デフォルト値をパラメータで指定するとかって方法もあるにはあるが。
43:デフォルトの名無しさん
07/08/18 13:14:40
これでCAS操作一回ずつと後はvolatileアクセスだけなので
マルチプロセッサ環境でもうまくスケールするかな…
シングルの環境では、lockよりも4〜5倍程度速い感じ。
44:デフォルトの名無しさん
07/08/18 14:58:22
ネタにマジレスするのはどうかと思うが
これ整合性とれてねーじゃんw
不完全だろw
45:デフォルトの名無しさん
07/08/18 15:02:59
整合性ってなあに…?(´・ω・`)
46:デフォルトの名無しさん
07/08/18 16:35:10
不完全ってなあに…?(´・ω・`)
47:デフォルトの名無しさん
07/08/18 17:22:59
マジネタにネタレスしたんだろ
48:デフォルトの名無しさん
07/08/18 17:57:25
こういうの微妙に不思議なんだけど、
シングルプロセッサ環境でも複数スレッドの方が速くなるのな。
なんでだろ?.NET環境特有の現象?
1スレッドと10スレッドでトータルの実行時間は3倍くらいにしかならない。
100スレッドだとせいぜい20倍くらい、つまり5倍くらいスループットが上がる。
49:デフォルトの名無しさん
07/08/18 18:05:22
それどんなプログラム?
50:デフォルトの名無しさん
07/08/18 18:20:44
上のやつとか。
CPU(とメモリ)依存処理ばかりなのになんでだろう。
51:デフォルトの名無しさん
07/08/18 18:43:55
ソースアップしてくれんとわからんね。起動やJITにかかってる時間も含んでる?
52:デフォルトの名無しさん
07/08/18 19:00:11
計測は、できるだけ実際の実行部分だけになるように
一応注意してやってはいるんだけどねぇ。
今外なのでソースは出せんが、ゲートとカウントダウンラッチ使って
間の時間を計測してる。計測精度は問題ないものを使ってる。StopWatchね。
ラッチは自作だけど、100万回ループの最初と最後だから
実装がいまいちでもまあそれほど大きな影響はないはず。
スレッドが多いほど処理スレッドに割り当てられるCPU時間が
ある程度は増えるかも知れないが、5倍てのはそういう問題の範囲じゃないと思うんだよね。
53:デフォルトの名無しさん
07/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:デフォルトの名無しさん
07/08/18 19:08:40
windowsアプリでやってるので、後でコンソールでも試してみよう。
あとは、スレッド1このときにメインスレッドで直接実行してどうなるか、かな。
55:デフォルトの名無しさん
07/08/18 19:12:59
>>53
なるほど、ちゃんと考えてないけど確かになりそうだ。
やっぱ更新バージョンが必要になるのかなぁ…
56:デフォルトの名無しさん
07/08/18 19:24:54
いや、更新バージョンじゃだめだな。
インデックスの扱いを工夫、かな。
57:デフォルトの名無しさん
07/08/18 20:01:55
つーかみんな論文とか読んで先人はどう工夫した
かぐらい考えてからソースコードかけよなぁ
58:デフォルトの名無しさん
07/08/18 23:11:48
Advanced Windows
URLリンク(www.amazon.co.jp)改訂第4版-ジェフリー-リッチャー/dp/4756138055
この本、よんだことある人いる?
C,C++でマルチスレッド組むのに有用な本なんだそうなんだが、いかんせん値段が・・・
59:デフォルトの名無しさん
07/08/18 23:19:18
>>53
変数は配列長の整数倍でできるだけ長い周期でループするようにして、
インデックス使用時に配列長で剰余をとるようにしたら、結構遅くなったw
インデックスで必要なビット長を求めて、残りの上位ビットを
サイクル数のカウンタとして使用するようにしたらだいぶ速くなった。
前のよりは1割程度遅くなったが、ここらでいっぱいいっぱいかな。
60:デフォルトの名無しさん
07/08/18 23:22:14
>>59
そんな申し訳ないことして実際どれぐらい役に立つのw
オナニーバイナリ生成ぐらいがいいとこだよね?
61:デフォルトの名無しさん
07/08/18 23:24:52
日本語でOK
お前さんは役に立たないことは一切やらないのかね?
62:デフォルトの名無しさん
07/08/18 23:26:20
まあいろんなものを実装する練習になるから
まったく役に立たないわけでもないんだけどな。
63:デフォルトの名無しさん
07/08/18 23:29:52
>>62
中途半端にかじった奴が糞コード晒すのとどうか思うのだが?
使えるならまだしも危険すぎだろwこんな糞コードしかかけないんだから
止めろよ。ゆとり夏房は本当に困る
64:デフォルトの名無しさん
07/08/18 23:33:46
どしたん?
65:デフォルトの名無しさん
07/08/18 23:37:30
>>63
「これこれの理由で危険だから使わないように」とでもコメントすれば済むことではないかと。
66:デフォルトの名無しさん
07/08/18 23:41:35
糞なとこを指摘してやれば役にも立つのに。
>使えるならまだしも危険すぎだろw
いや誰も実際に使おうなんてやつはいないだろw
67:デフォルトの名無しさん
07/08/18 23:45:42
>>66
こういうものは指摘しても理解できないだろ?
俺はこんなコード書くやつがまともな姿をした
人間だとはとても思えないんだよ。
68:デフォルトの名無しさん
07/08/18 23:52:36
>>59
ていうか配列長を2の冪乗に切り上げておけば、
ビットマスクとのAND演算だけで済むでしょ。
69:デフォルトの名無しさん
07/08/19 00:01:21
それは思ったが、無駄が多かったのと、キャパとの兼ね合いで
空もしくは一杯の判定が微妙にややこしくなりそうなのでやめた。
でも確かにサイクルカウントを上位ビットに持つよりはずっと単純だったかも試練。
70:68
07/08/19 00:10:34
>>69
いや、capacityも配列長に合わせて切り上げちゃっていいんじゃない?
どうせパフォーマンス重視なんだから、capacityなんて厳密に扱う必要はないと思うが。
71:デフォルトの名無しさん
07/08/19 00:21:34
うーん、容量固定のキューだったからね、今回はこれは変えたらだめかなって勝手に。
まあ、実際にこんなものを作ることがあったらそうすると思う。
72:デフォルトの名無しさん
07/08/19 05:21:55
>>67
>こういうものは指摘しても理解できないだろ?
ここは相談室なんだから、相談相手になる気がないなら他へどうぞ
73:デフォルトの名無しさん
07/08/19 09:11:12
>>58
マルチスレッドに限らず、Windowsプログラミング全般においてその本は
とても有用なので、買って損はないよ。
ただし、各種オブジェクト単体での深い説明が中心で、スレッドの作法だとか
そんな話は皆無で、マルチスレッドの入門書として期待しているなら
やめた方がいい。
例えば、クリティカルセクションが他の同期オブジェクトよりも軽いという点について、
OS内部でどう実装されているのかという話が書いてある。
マルチスレッドの話が読みたいなら「Win32マルチスレッドプログラミング」の方が
いいと思う。(俺は見たことないが)
74:デフォルトの名無しさん
07/08/19 19:00:00
>>67なにまともなフリをしてんだおまえはw
75:デフォルトの名無しさん
07/08/19 19:04:25
でどの辺が糞コードでどの辺が中途半端にかじったぽいのか早く教えて
76:デフォルトの名無しさん
07/08/20 14:15:47
この絡み方厨房の典型だなw
77:デフォルトの名無しさん
07/08/20 14:18:42
そうやってすぐ厨房扱いする奴も大して変わらん
78:デフォルトの名無しさん
07/08/20 16:45:02
厨房に厨房が返してるだけだろ
79:デフォルトの名無しさん
07/08/22 22:21:13
mutexが永田ロックかけてるのか
まだロックかけないで痛めつけてるのか
計測するほうほうないですか?
pthreadでお願いします。
80:デフォルトの名無しさん
07/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:デフォルトの名無しさん
07/08/26 21:48:16
>>80
実はスレッドでなくファイバだったとか。
82:デフォルトの名無しさん
07/08/26 21:50:26
HPの鯖でpthread使って書いてますけど
ファイバってことはありえないですよねw?
まじ釣りとかじゃなくて本気でこんなコード生成
するんですよ。困ってる
83:デフォルトの名無しさん
07/08/26 21:53:21
>>80
オマエの日本語やコードの貼り方も相当なもんだ。困ってる
84:デフォルトの名無しさん
07/08/26 21:53:47
ごめん許してくれ
85:デフォルトの名無しさん
07/08/26 21:55:27
マ板向けの話題かな
86:デフォルトの名無しさん
07/08/26 21:56:49
これって絶対ネタだよな
馬鹿でも考えりゃ排他必要な事解かると
87:デフォルトの名無しさん
07/08/26 22:03:55
満を持してvolatileの登場だな
88:デフォルトの名無しさん
07/08/26 22:06:04
>>87
それもネタだろw
89:デフォルトの名無しさん
07/08/26 22:51:08
>>80悪いがそのコードの意味がわからなくてなんとも胃炎。
90:デフォルトの名無しさん
07/08/26 23:06:45
>>89
文脈から想像して、
int l_index = index;
このようにindexをローカル変数にコピーしてから、そのコピーを使って
配列参照すればロックとかいらない、とC言語歴15年さんが主張している。
と読んだ。
ただ、コードは明らかに抜粋なので、状況によってはOKなのかも知れない可能性はある。
thread_1がデータの更新処理で、thread_2は現在の最新データを取得するだけ、
配列は十分に大きく、データの空チェックは別にあるとか。
あるいは、thread_1とthread_2でキューを実現しようとしているなら問題だけど、その場合も
コードが断片すぎるので、前後の記述によっては問題ないかもしれず。
それを含めて>>80が明らかな問題であることを認識した上で書き込んでいるなら、
最初からマ板に行くべきかと。
91:デフォルトの名無しさん
07/08/26 23:14:21
>>90
SMPなんかでCPU入れ替わったら
問題おきないかなぁ?
92:デフォルトの名無しさん
07/08/26 23:22:06
>>90
キューなどの順序性保証が必要なものだとあきからにやばいけど、
掲示板などに書き込まれたデータの最新の1レコードを定期的に
表示更新っていうパターン(厳密な意味での最新版にはこだわらないもの)
なら、volatileのレベルで妥協できる場合もあるんじゃないかって
思ったんだけど。
thread_2の例が現状のindexをいじらずに現時点のindexのレコード参照
しているだけみたいだから。
93:デフォルトの名無しさん
07/08/26 23:26:28
絶対2回読む可能性捨てきれないし
こんな実装商用レベルでしないよなぁ
きっとどっかの研究室だろうなぁ。
教授が書いたコードだから絶対だみたいな感じなんだろうなぁ
94:デフォルトの名無しさん
07/08/27 11:03:22
それならまさに発見的手法だな
95:デフォルトの名無しさん
07/08/28 22:57:45
【OS】 WinXP SP2
【言語】 VC8
【実行環境】 2000以降、可能であれば9x以降
【その他突起する事項】 C++ソースコード上での解決が望ましい
TerminateThreadだと、終了させたいスレッドのハンドルがあればスレッドを終わらせる事ができますが、
これは基本的に最終手段としてスレッドを終わらせる為の物で、初期のスタック割り当てを解除する機会がなかったり、色々問題があるようです。
なので、スレッド外部からExitThreadの様にスレッドを終わらせるにはどうすればいいんでしょうか。
対象のスレッド内で、終了される"かもしれない"タイミングは把握可能です。
96:デフォルトの名無しさん
07/08/28 23:10:34
終了フラグを用意して、スレッドが終わって欲しくなったらフラグを立てる。
対象スレッド内で、今だったら別に終了してやってもいいというタイミングで、フラグをチェックして自主的に終了する。
フラグの読み書きは、ちゃんとクリティカルセクションやミューテックスで囲むか、インターロック関数を使うか、メモリバリアを張ること。
97:デフォルトの名無しさん
07/08/28 23:11:47
・終われフラグなりイベントなりを用意
・要所要所でフラグ/イベントをチェックしてオレオレ例外をthrow
・スレッドの開始点でtry〜catch
でとりあえずできる
他のやり方でも結局こうなると思う
コールスタックにC関数が挟まるとダメな場合もあるので注意
98:.95
07/08/28 23:18:11
Sleepしてる間に終わらせるフラグが立つので、待ち時間が長いです...
99:デフォルトの名無しさん
07/08/28 23:25:03
>>95
メッセージなり何なりを対象スレッドに投げて、対象スレッドに自ら涅槃の道に旅立ってもらう。
100:デフォルトの名無しさん
07/08/28 23:44:30
>>98
Sleepを細かく分ければいい。
for (int i=0; i < 10; ++i) {
Sleep(100);
check_exit_flag();
}
こういうポーリングがいやならEventつかって待機関数で待つとか
101:デフォルトの名無しさん
07/08/29 08:59:33
【OS】 Xp sp2
【言語】 VBA
【実行環境】 Q6600
VBAってマルチスレッドできないともできるとも明記されていないんです。
質問なんですが、VBAにかかわらずマルチスレッド化によって、『比較的発生しやすい障害』というのは何でしょうか?
C等ならPUSH、POP等のメモリ操作がいちばん気をつかいそうなところですよね。
VBAでは、適所に Do Eventを2つ入れること(実験により1つではエラー起きやすい)、変数のグローバル宣言にきをつけること(2つのスレッドで同じ変数を呼ばない)ことくらいですかね。プロシージャーは同時に使っても今のところ問題ありません。
どうぞよろしくお願いします。
102:デフォルトの名無しさん
07/08/29 10:07:45
>【言語】 VBA
>VBAにかかわらず
どっちだよ
103:デフォルトの名無しさん
07/08/29 10:54:17
>マルチスレッド化によって、『比較的発生しやすい障害』
>101のような香具師が手を出してプロジェクトを台無しにする可能性が高まること。
104:デフォルトの名無しさん
07/08/29 10:55:09
日本語でおk
105:デフォルトの名無しさん
07/08/29 11:36:22
> VBAってマルチスレッドできないともできるとも明記されていないんです。
M$に問い合わせろよ
106:デフォルトの名無しさん
07/08/29 12:51:30
煽る人ばっかりで、本日はまともな人いないんですねー。><
失礼しました!
107:デフォルトの名無しさん
07/08/29 22:41:29
>C等ならPUSH、POP等のメモリ操作がいちばん気をつかいそうなところですよね。
お前はいったい何を言っている?
108:デフォルトの名無しさん
07/08/29 22:47:28
>>101
お前の居場所はこっちだ
スレリンク(tech板)
109:デフォルトの名無しさん
07/08/29 22:50:49
Cカップの子を触るのにおもいっきり触るのか
それともソフトタッチでいくのかこれは結構気を使うって
ことなんだな
110:デフォルトの名無しさん
07/08/29 22:58:17
PUSH,POPは気を使わない。それぞれ単純に排他制御するだけだ。
気を使うのは、例えば何かの目的のために一つの処理の中で
pop,pushを続けて行おうとたらその間に別スレッドが実行されて
意図せず状態が変わってしまうようなことが発生すること。
排他制御していない箇所はどんなタイミングでどのスレッドが
実行されるかわからないことを肝に銘じておく必要がある。
『実験により1つではエラー起きやすい』
こんなこと言ってるようじゃ駄目だ。なぜ1つでエラーと
なったのか論理的に分かるまで追え。まあDoEventを愛用
する奴にはマルチスレッドは剥いていない
111:デフォルトの名無しさん
07/08/29 23:15:46
VBAってCOMオブジェクト主体じゃないのか
マルチスレッドの意味あんのかな
112:デフォルトの名無しさん
07/08/30 00:43:06
>101
VBA単独でスレッドを起こす手段がないからな。明記する必要もないだろ。
VBAだけじゃMutexとか同期用のオブジェクトをどうやって扱ったらいいものか、
スレッドを起こす手段がないので同期に関する記述もないからなぁ。
それにCOMだし意味がないかもな。
113:デフォルトの名無しさん
07/09/08 01:29:00
適当なスレが判断できないのでここで質問させて下さい。
msvcrt.dllやスタティックなVC6以降のmallocとfreeの動作についてですが、
_beginthreadexで作成した各スレッドで、あるスレッドがmallocしたメモリを
違うスレッドでfreeする事は合法でしょうか?
過去の自分の書いたコードで見つけてしまいました。
なんかやばそうな気はするんですが。
114:デフォルトの名無しさん
07/09/08 01:35:12
>>113
何を知りたいの?もうちょっと明確に話まとめろよ
このインキン野郎が
115:デフォルトの名無しさん
07/09/08 01:51:13
>>113
スレッドが異なることは問題ない。
メモリ管理で問題になるのはモジュール(EXEやDLL)が異なる場合。
ただし、この場合でもすべてのモジュールのCランタイムを
動的リンク(msvcrXX.dllを使う)にしておけば、問題は発生しないはず。
116:デフォルトの名無しさん
07/09/08 21:25:21
ありがとうございました。
一応きちんと動いてはいるみたいなので放置します。
117:デフォルトの名無しさん
07/09/08 23:20:00
マルチスレっ
118:デフォルトの名無しさん
07/09/09 03:22:50
合法か違法かで言えば合法だろうし、(問題でてないのに)直すってのもアレだけど、
行儀わるいよな。
119:デフォルトの名無しさん
07/09/09 03:47:08
>>118
アプリ全体のログを採る処理で、printfみたいな書式文字列を
mallocやreallocでメモリに貯めていって、ある程度溜まった段階で
清書してファイルに吐き出して、使った分をfreeしてくという仕組みなんですが、
CriticalSectionの排他で順番だけ決めてるだけで、どのスレッドが
メモリ管理をする、というのを決めてないんです。
まあ、最初と最後の破棄とかはメインスレッドがするんですが。
試しにスレッド間通信したらパフォーマンスが悪かったので
こんな仕様にしたような記憶があります。
どうしたらいいでしょうかね。
120:デフォルトの名無しさん
07/09/09 11:39:09
きちんと管理できてるんなら問題ないでしょ。
C++ならstd::stringとか使ってくれた方が楽そうだけど
121:デフォルトの名無しさん
07/09/09 15:29:38
マニアックにboost ropeで
122:デフォルトの名無しさん
07/09/10 07:56:13
boost? STLportじゃなくて?
123:デフォルトの名無しさん
07/09/16 18:00:27
XP/2000のスレッドで質問です。
親子関係にあるスレッドで、親をなるべくブロックさせずに、
毎秒数KB程度のデータを子に送信したいと考えています。
(子は1つで、子の応答はいくら遅れてもかまわない)
クリティカルセクションでデータの排他をに試したら、
子供の処理が長引くだけ親がブロックされてしまうので、
別の方法を検討しています。
こういった場合、スレッド同士の同期オブジェクトを介さずに
データをバッファに溜めておける名前付きパイプが良いかなと
思ったのですが、こういった用途に使えるでしょうか。
124:デフォルトの名無しさん
07/09/16 18:16:31
パイプの長さは必ず確保するという話ではなかった気がするなあ
>クリティカルセクションでデータの排他をに試したら、
>子供の処理が長引くだけ親がブロックされてしまうので
通常、
バッファへの追加
バッファからの取り出し
以外は排他する必要はないと思うんだが、違うのか?
125:デフォルトの名無しさん
07/09/16 18:25:19
>>123
子スレッドが処理終わるまでロックさせっぱなしにしないで、
さっさと必要なデータをコピーしてクリティカルセクションから抜けたら?
126:デフォルトの名無しさん
07/09/16 18:38:07
>>123
子供2つにすればいいだろボケシネカス
127:デフォルトの名無しさん
07/09/17 00:55:31
10ヶ月かかるし。
128:デフォルトの名無しさん
07/09/18 20:48:36
処理が終わるまで待ってたらスレッドの意味が無い。
129:デフォルトの名無しさん
07/09/19 20:55:43
【OS】
Debian Etch Linux kernel 2.6.18
【言語】
C pthread
【実行環境】
GNU gdb 6.4.90-debian
gdbでのマルチスレッドのデバッグ中、任意のスレッドでステップ実行をしていると
とつぜんカレントスレッドが切り替わり、
ステップ実行していたスレッドの実行位置が失われる現象に遭遇します。
デバッグ対象のプログラムは、動作確認がとれているオープンソースのプログラムです。
原因、回避法等ご存知のかた、ご教示いただけないでしょうか
130:デフォルトの名無しさん
07/09/19 21:12:16
gccスレにも行っとけ
131:デフォルトの名無しさん
07/09/19 22:58:11
>>129
250万でサポートしてやるけどどうよ?
132:デフォルトの名無しさん
07/09/20 23:06:29
250万の内訳を教えてくダサイ
133:デフォルトの名無しさん
07/09/20 23:24:38
サンドバック料:200万
治療代:50万
134:デフォルトの名無しさん
07/09/20 23:28:49
>>132
年間保守契約費 200万
登録費 30万
事務手数料 20万
だが?
135:デフォルトの名無しさん
07/09/21 23:17:41
ずいぶんと安いね
136:デフォルトの名無しさん
07/09/23 04:16:06
これからはsignalfdだな
137:デフォルトの名無しさん
07/09/24 14:05:07
ロックしたら負けかな、と思ってる
138:デフォルトの名無しさん
07/09/24 18:56:19
erlangマンセー
139:デフォルトの名無しさん
07/09/29 12:41:04
malloc(), free()ってスレッドセーフなんですか?
140:デフォルトの名無しさん
07/09/29 15:01:14
お前が使っているライブラリのマニュアル嫁
141:デフォルトの名無しさん
07/09/29 18:07:16
>>140
man malloc
ってやってもスレッドセーフに関する記述がないんです...
142:デフォルトの名無しさん
07/09/29 18:41:26
使っているOSの名前、バージョンを言わないのは初心者気取りか?
143:デフォルトの名無しさん
07/09/29 20:23:28
対応してる。大丈夫だ。
144:デフォルトの名無しさん
07/09/29 22:14:38
>>143
安心しました。ありがとうございます。
145:デフォルトの名無しさん
07/09/29 23:24:04
藻前詐欺にあい易いタイプだろ
146:デフォルトの名無しさん
07/09/29 23:39:03
ワロタ
147:デフォルトの名無しさん
07/09/30 01:06:02
昔おれ衝動買いの時によくやった
店員に騙されるパターン
信じてたのに・・・・
148:デフォルトの名無しさん
07/09/30 01:20:45
マルチスレッドでcoutを使うと表示がぐちょぐちょになって醜いです。
どうしたらいいでしょうか?
149:デフォルトの名無しさん
07/09/30 01:21:34
C++の仕様。
printf使いなさい。
150:デフォルトの名無しさん
07/09/30 01:27:17
すみませんprintfでも同じです
151:デフォルトの名無しさん
07/09/30 01:31:42
coutという一つの資源を複数のスレッドで取り合うからそうなる。
排他機構を使ってひとつのスレッドが使っているときに他のスレッドが使うことが無いようにしろ。
152:デフォルトの名無しさん
07/09/30 01:33:10
出力スレッドでも作って、そいつに全部押しつけろ。
153:デフォルトの名無しさん
07/09/30 10:08:32
pthreadつかってマルチスレッドのプログラム作ってるんだけど.
なぜか特定のタイミングでピタッと動かなくなる(デッドロックというのか?)
それ以降プログラムがうんともすんともいわなくなる.
デバッグする際にみんなどういうことやってる?gdbは使い物にならないし...ltraceも使えない...
やっぱりソースコードを目で追っていってるわけ?
154:148
07/09/30 10:48:06
>>151-152
そんな事したらめんどくさくないですか?
もうちょっと簡単な方法でお願いします
155:デフォルトの名無しさん
07/09/30 10:56:45
>>154
諦めろ
156:デフォルトの名無しさん
07/09/30 10:58:21
ソースを追うっていうか、どんなケースが起こりえて、
すべてのケースの組み合わせに対応できているか検証する。
大体は、止まりそうな場所はわかるから、そこを調べて、
次に、ブロックするかもしれない操作を洗い出して調べる。
止まる場所は突き止めたけど、どうして止まってしまうかわからない場合は、
状態をログに出したりするかな。
デッドロックより、最適化とかOoOでの実行順序の入れ替わりとか、
可視性が関わるバグの方が、調べるの大変だと思う。
157:デフォルトの名無しさん
07/09/30 11:12:22
coutやprintfがMT-safeでも、
出力が崩れるのはどうにもならないと思うので、
出力処理全体を1セットとして、ちゃんと排他しないと駄目だろう。
158:デフォルトの名無しさん
07/09/30 12:22:06
>>148
スレッドごとに出力先を分ける。
159:デフォルトの名無しさん
07/09/30 13:23:05
>>154
マルチスレッドプログラミングが「面倒くさい」ものでないならば
そもそもこんなスレは存在して無いだろうよ。
160:デフォルトの名無しさん
07/09/30 13:40:06
>>154
ぐちょぐちょにならないっていうことの意味をもっとはっきりしないとだめだね
一番綺麗なのは、スレッドAの表示がすべて終わってからスレッドBの表示をすることだが、それならシングルスレッドにするのが一番簡単
つまりマルチスレッドやめれば解決
161:デフォルトの名無しさん
07/09/30 13:43:19
>>154
ドトネトのSystem.Consoleクラスならマルチスレッドセーフ。w
162:デフォルトの名無しさん
07/09/30 13:50:16
>>161
素朴な疑問なんだが、そのマルチスレッドセーフとは出力が混ざらないことまで保障してくれるのかね。
# だとしたら、逆に激しく不便なんだが。
163:デフォルトの名無しさん
07/09/30 14:03:37
>>158のは、言われてみれば当たり前なんだが、
簡単だし、間違いないな。
変数/オブジェクトの持ち回りとかが、複雑になってたら、
スレッドローカルな変数を使えばいいし。
164:デフォルトの名無しさん
07/09/30 14:04:48
メソッド一発分が安全に動くだけだろ。
165:デフォルトの名無しさん
07/09/30 14:07:48
>>162
Console.WriteLineはアトミックに実行されて出力は混ざらないね。
ReadLineは1つのスレッドが入力実行中は他はブロックされるかな?
混ざらないとどの辺りが激しく不便なのでしょうか?
166:デフォルトの名無しさん
07/09/30 14:09:34
>>164
それ以外に何を求めると?
167:デフォルトの名無しさん
07/09/30 14:12:41
行単位でも混ざって欲しくなかったら>164では不十分だろ。
行単位で適宜出力して欲しかったら混ざらなかったら不便だろ。
168:デフォルトの名無しさん
07/09/30 14:15:25
まず、「混ざる」の定義からはじめろ。
バイト単位なのか、
マルチバイト、ワイドキャラクタ等の文字単位なのか、
出力ストリームのメソッド単位なのか、
複数の出力ストリーム書き込みをまとめた、プログラムの中で定めたオレ単位なのか。
169:デフォルトの名無しさん
07/09/30 14:19:52
初心者なオレのためにライブラリ、クラスのスレッドセーフの
定義を騙ってください。
170:デフォルトの名無しさん
07/09/30 14:28:21
>>166
何も求めてねーよ。
>>162に答えただけだ。
171:デフォルトの名無しさん
07/09/30 14:34:16
>>170
メソッド一発分が安全に動くだけ以外のことをされると
マルチスレッドでは激しく使い辛いですな。。
172:デフォルトの名無しさん
07/09/30 17:35:19
>マルチスレッドでは激しく使い辛いですな。
わかんねー奴に俺が翻訳してやる。
せっかく並列に動くのに余計なロックするなや
別に使い方が面倒になるわけじゃないよ
いじょ
173:148
07/09/30 18:12:10
もういいです。わたしが馬鹿でした
もうあきらめます。
174:デフォルトの名無しさん
07/09/30 18:20:52
なんだ、学習意欲のないやつだな
175:148
07/09/30 19:21:43
すみませんが、本当にわかる方、回答をお願いします。
176:デフォルトの名無しさん
07/09/30 19:28:32
残念だったね。
177:デフォルトの名無しさん
07/09/30 19:36:20
自分でマルチスレッド対応のストリームつくればいいじゃん
178:148
07/09/30 19:44:05
>>177
そんな事したらめんどくさくないですか?
もうちょっと簡単な方法でお願いします
179:デフォルトの名無しさん
07/09/30 19:49:11
そもそもプログラミング自体めんどくさくないですか?
ありあわせのフリーソフト探してくる方法が簡単だと思います
180:デフォルトの名無しさん
07/09/30 20:50:56
そもそも生きてるってめんどくさくないですか?
氏ねば簡単ですよ
181:デフォルトの名無しさん
07/09/30 20:56:18
>>180
どうやったら楽に死ねますか?
簡単そうな方法にはちょっと勇気が必要だし、そうでないのは簡単じゃないし
182:デフォルトの名無しさん
07/09/30 21:09:17
>>180
旅立ちパックの中に
連単はいってるからつかえ
以上
183:デフォルトの名無しさん
07/09/30 22:14:37
>181
死ねばすべてが楽になるんだ
楽したいなら、死ぬ努力ぐらいはしてもいいだろ
俺は死にたくないから、努力して生きるよ
184:デフォルトの名無しさん
07/09/30 23:11:03
>>178
ストリーム出力だけロックすれば済む話だろうが〜
どこが面倒なんじゃ〜?
185:デフォルトの名無しさん
07/10/01 01:35:10
マルチスレッドプログラミングは初心者には無理だよ
面倒=やり方がよくわからない という事であればこの先できるようになる見込みもなし
厳しいけどこれ現実なのよね
186:デフォルトの名無しさん
07/10/01 03:15:20
スレッガーさん!
187:デフォルトの名無しさん
07/10/03 20:59:05
スレッドセーフじゃない場合はどうするつもりだったのかと・・・
スレッドセーフだったらどうしたかったのかと・・・
まぁいいや、どうせネタでしょ?
188:デフォルトの名無しさん
07/10/08 15:51:11
次世代ゲーム機のCPUみたいにレジスタが山ほどあるCPUて
コンテキストスイッチのオーバーヘッドも比例して増えてるんかな
189:デフォルトの名無しさん
07/10/08 16:02:08
一部しか保存しなくてすむようにしてあんじゃね?IA64とかそうだべ。
190:デフォルトの名無しさん
07/10/08 17:01:20
64bitのレジスタ32本あるのじゃまんぞくしねーのか?
191:デフォルトの名無しさん
07/10/08 19:38:15
高速なキャッシュがたくさんあれば満足する
192:デフォルトの名無しさん
07/10/08 20:11:01
IA64とかって確かコンテキストが2500バイトくらいいくんだよなw
193:デフォルトの名無しさん
07/10/09 21:36:08
おれはレジスタの数よりも、1次キャッシュに乗ってるメモリとの
演算やアクセス速度が、レジスタと同程度であれば良いと思ってる。
結局それが最強でしょ?
194:デフォルトの名無しさん
07/10/09 22:04:14
命令セットの問題じゃね
195:デフォルトの名無しさん
07/10/09 22:47:19
だよね。
RISC系の、メモリアクセスは基本的にロード/ストアのみで
演算はレジスタに対してしか出来ない、ってアーキテクチャだと
キャッシュの速度だけじゃなく、レジスタの数も欲しいはず。
196:デフォルトの名無しさん
07/10/09 22:58:57
そんなことできたら苦労は無いわ。
メインメモリにレジスタと同程度でアクセスできれば最強だな。
197:デフォルトの名無しさん
07/10/09 23:43:09
>>196
補助記憶装置含めて光速の99%で処理できたらおk
198:デフォルトの名無しさん
07/10/10 00:46:35
発想を逆にするんだ。
レジスタへのアクセスがメインメモリと同程度に遅(ry
199:デフォルトの名無しさん
07/10/10 13:37:41
じゃあ、みんながのんびりすればよくね?
200:デフォルトの名無しさん
07/10/10 18:07:14
俺も思う。
CPUだけじゃなくて、日本人がもっとのんびりスベキナンダヨ
201:デフォルトの名無しさん
07/10/10 21:55:40
1ヶ月くらい休みクレ!
次ページ最新レス表示スレッドの検索類似スレ一覧話題のニュースおまかせリスト▼オプションを表示暇つぶし2ch
5389日前に更新/193 KB
担当:undef