マルチスレッドプログラミング相談室 その6at TECH
マルチスレッドプログラミング相談室 その6 - 暇つぶし2ch2:デフォルトの名無しさん
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ヶ月くらい休みクレ!

202:デフォルトの名無しさん
07/10/12 23:27:18
>>>200
いや、今の状況はさー、
のんびりすべきだ、のんびりしよう、
とか言って急ブレーキ掛けてた頃からは、
実はもうだいぶ経っててさ、逆にのんびりしすぎてるんじゃ?
って密かに周りが焦り始めてるんだけど、
具体的な問題が出てくるまでは、それにあえて気付かない
フリをしていよう、ってところなんだよ。
ほんとうは、そろそろ歩きださないと。いそがないと!
って時なんだよ?
一度怠けると元に戻れなくなるって言うけど、それ以前に
元がどうだったかなんて忘れてるもんだからさ、
フリじゃなくてほんとうに気付いてないのかもしれないね。
日本ヤバイよー。
おれは海外に移住する予定です。

203:デフォルトの名無しさん
07/10/21 20:33:43
SolarisでpthreadでC++です。

C* c;
int main() {
  c = new C;

と、mainの先頭で生成したオブジェクトを、N個のスレッド(実際は8個固定)から使っています。

スレッドが順次終了してゆき、最後のN個目が終了した直後、あるいはN-1個目が終了した
後かつN個目が終了する直前にdelete c;をしたいのですが、うまい方法はあるでしょうか。
リファレンスカウントでしょうか。

N個のスレッドすべてをpthread_join()するような、親スレッドはいません。
なお、Cのメンバ関数はすべてスレッドセーフに作られています。

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

204:デフォルトの名無しさん
07/10/21 20:36:29
>>203
リファレンスカウントで何か不満なの?
boost::shared_ptr ですぐに実装できそうだし。

205:203
07/10/21 20:41:02
>>204
boostやSTLが使用禁止なので、一から手書きする場合の例をいただけたらと。。
テンプレートは使用可です。

206:デフォルトの名無しさん
07/10/21 20:47:33
>>204
スレッドをまたいでshared_ptrを渡すのって例えばどうやるの?

207:デフォルトの名無しさん
07/10/21 21:24:12
> boostやSTLが使用禁止なので

ぬふぅ

208:デフォルトの名無しさん
07/10/21 21:24:57
>>203
代入系の演算子をoverrideしまくればそれっぽいの出来るけど、
用途をみてるとそれだけのためにshared_ptrを実装するのはもったいないな。


209:デフォルトの名無しさん
07/10/21 21:45:00
>>205
boost の実装見ればいいじゃん。

210:デフォルトの名無しさん
07/10/21 21:46:15
>>206
スレッドごとに shared_ptr のコピーを持てばいい。

211:デフォルトの名無しさん
07/10/21 23:17:11
>>210
boostのshared_ptrの参照カウントの上げ下げってスレッドセーフだっけ?
最新のstableでもなにもしてなかったような。

212:203
07/10/21 23:58:41
みなさまどうも。

>>210

shared_ptr<C> g;
int main() {
 g.reset(new C);
 // スレッドを8つ生成
 cond_wait; // スレッドがgをコピーするのを待つ
 g.reset(0);
 ...
}

void* thr(void* data) {
  shared_ptr<C> local = g;
  cond_signal;
  ...
}

とかですか。

213:デフォルトの名無しさん
07/10/22 04:26:17
チラシの裏で悪いけど、g++のbits/atomicity.hの__exchange_and_add()とか使うと、
libstdc++.soの関数を呼びに行くんだね。おそそー。

214:デフォルトの名無しさん
07/10/22 08:13:39
>>211
スレッドセーフではないとすると、参照カウントを上げる方は、
>>212のやりかたでも、一個ずつスレッドを作って、
cond_waitすればいいけど、下げる方は排他制御しないと
駄目って事かな?

単純な実装にするなら、
全スレッドが共用するカウンタを作って、上げ下げすればいいんじゃないのか?
最初と最後だけなら、速さとかは気にせずに、適当な実装でも問題なさそうだし、
atomicな操作ができるなら、それこそカウンタだけ渡せば済むし。

Cがいじれるなら、自分自身でカウントしても良さそうだけど。

どうでもいいけど、>>212は、グローバル以外の渡し方はないのか?

215:デフォルトの名無しさん
07/10/22 16:47:54
>>214
void* data 経由で渡して、スレッド側でstatic_cat<shared_ptr<C*>* >することは可能。
スマートポインタへのポインタを渡すことになって気持ち悪いけど。

216:デフォルトの名無しさん
07/10/22 18:27:07
どのみちmainは生きてるんだから
mainでjoinで待って削除すればいいのでは

217:デフォルトの名無しさん
07/10/22 18:53:14
>>216

>>203
>N個のスレッドすべてをpthread_join()するような、親スレッドはいません。

218:デフォルトの名無しさん
07/10/22 21:44:40
クラスCをsingletonにするのは無し?

219:デフォルトの名無しさん
07/10/22 21:55:54
>>214
そうですね。スマートポインタは使わず、単純なカウンタ+アトミック操作でいこうとおもいます。

>>218
決してdeleteされないsingletonにするのはNGです。threadが全部いなくなったら、deleteしないとまずい
事情があります。

ありがとうございました。

220:デフォルトの名無しさん
07/10/22 22:05:42
スレッドの調停者が居ない=全てのスレッドが終了時にアプリケーションが終了

なら,singletonでも別にもんだいねーよーな気がする

221:デフォルトの名無しさん
07/10/22 22:12:26
>>220
スレッドが全部終了した段階では、アプリケーションは終了しません。
また、その段階で~C()をよばないと、いろいろまずいことがあります。




222:デフォルトの名無しさん
07/10/22 22:19:30
>>220
誰がスレッドを最終的に所有してるの?

223:デフォルトの名無しさん
07/10/22 22:22:45
素直にスレッドのマネージャを作れば

224:デフォルトの名無しさん
07/10/22 22:25:30
>>222
メインスレッドaを起点として、ツリー状に生成・所有されています。

a-b-c-N1
   -d-N2
  e-f-g-N3
      -N4
   -h-N5-N6
   -N7
 -N8

みたいなひどい感じです。Nxが、今回興味のあるスレッド群。
何でこんなことになってるのかの経緯は、私にはちょっとわかりません。。。



225:デフォルトの名無しさん
07/10/22 22:27:37
>>224

こんなはちゃめちゃになるんだったら
マネージャ作れよ

GCとかみたいに自分で管理したくないものは
誰か権限のあるやつだけに委譲しろよ

226:デフォルトの名無しさん
07/10/22 22:28:56
>>225
managerとは、具体的には何をするものでしょうか?

227:デフォルトの名無しさん
07/10/22 22:38:42
スレッドのリソースの管理

228:デフォルトの名無しさん
07/10/22 23:06:01
>>227
ありがとうございます。

>>214
参照カウントは、URLリンク(www.open-std.org) あたりを参考にすればいいのかな。
4-8個程度はCPUの乗ったSPARCが相手だと、atomic_inc/decだけでは実装できないよね。このあたりに詳しいかた、コメント
いただけませんか?


229:デフォルトの名無しさん
07/10/22 23:11:23
>>228
アトミックなカウンタ操作があっても実装できない理由って何?

230:デフォルトの名無しさん
07/10/22 23:11:56
アトミック云々以前にスレッドの管理が出来てないんじゃ意味ないだろ

231:デフォルトの名無しさん
07/10/22 23:15:43
>>229
複数のCPUが同時にatomic_incを実行すると破綻するから


232:デフォルトの名無しさん
07/10/22 23:18:14
そんなのはアトミックじゃねぇ

233:デフォルトの名無しさん
07/10/22 23:19:53
>>231
その atomic_inc はアトミックじゃないのかい?

234:デフォルトの名無しさん
07/10/22 23:26:06
っSMP

235:デフォルトの名無しさん
07/10/22 23:27:42
>>232-233
そういうCPUもあるし、そうでないCPUもある。

236:デフォルトの名無しさん
07/10/22 23:35:39
そうでないCPUでは、それはただの x++ とどう違うの?

237:デフォルトの名無しさん
07/10/22 23:47:52
>>236
横から。わたしもよくわかってないが
1.コンパイラやlibcが提供するatomic_inc/dec関数だけでは、単一CPUでのアトミックな演算しか保証されない
2.適切な命令(バリア)と一緒に使えば、複数のCPUを相手にatomicなinc/decができる (memory visibilityがどーたら)
3.どういうバリアが必要かは場合によって異なるから、コンパイラやlibcが提供するatomic_inc/dec関数にはバリアが入っていないことがある
こんなところじゃない?詳しい人フォローよろ。

238:237
07/10/22 23:52:39
>>237
1と2の末尾にも「ことがある」を追加

239:デフォルトの名無しさん
07/10/23 00:24:36
あー、そういう実装の既存の関数があるのね。

そこまで分かってるなら前後にメモリバリア足せばおしまいじゃね?

240:デフォルトの名無しさん
07/10/23 00:29:35
つーかvolatileで十分w

241:デフォルトの名無しさん
07/10/23 00:30:04
atomic_inc/readはlinuxのカーネル系の関数のようだね。
pthreadのような高位のAPIを使わない理由はなんだろう?
パフォーマンスを気にするようなアプリなのか。

242:203
07/10/23 00:31:23
>>241
pthreadにします。

243:デフォルトの名無しさん
07/10/23 09:00:33
>>240
キタ━━━(゚∀゚)━━━ !!!!!

244:デフォルトの名無しさん
07/10/23 09:41:51
SPARCv9なら、CASがあるよ。

245:デフォルトの名無しさん
07/10/23 17:58:33
linuxのCでスレッドの排他制御をしたいのですが、
なにぶんPONIX?っていうんですか?での開発は初めてなので
ご質問させてください。

pthread_mutex_t mutex;
pthread_mutex_init( &mutex, NULL );
pthread_mutex_lock( &mutex );
pthread_mutex_unlock( &mutex );
PONIXではこのようにpthread_mutex_lockを使うようですが
この引数pthread_mutex_t*をWin32のCreateThread()のように
ある共通の識別子を持っているスレッド同士のみが排他制御を
するにはどのようにすればよいのでしょうか?

例えば同じ親から4つ子のスレッドが生まれたとします。
スレッド長男と次男は排他関係
スレッド長女と次女も排他関係
でもスレッド男兄弟とスレッド女姉妹は排他関係ではない
という場合です。

246:デフォルトの名無しさん
07/10/23 18:11:09
必要なだけ mutex を作って、自分で識別子と mutex の対応付けを管理する

247:デフォルトの名無しさん
07/10/23 19:33:13
>>246 ありがとう。

248:デフォルトの名無しさん
07/10/23 21:15:18
自分でご質問とか言うなよ

249:デフォルトの名無しさん
07/10/23 21:29:36
なぜ?

250:デフォルトの名無しさん
07/10/23 21:40:30
自分がする質問だから

「あなたのご質問には答えられません」
なら、相手を持ち上げている
「私のご質問に答えてください」
なら、自分を持ち上げている

日本人として変であることに気づくべき

251:デフォルトの名無しさん
07/10/23 21:42:00
あほか
美化語を知らんのか

252:デフォルトの名無しさん
07/10/23 21:47:44
おトイレならわかるがご質問はないな。
「ご質問はありますか」は当然あり。

253:デフォルトの名無しさん
07/10/23 21:50:16
尊敬と謙譲の概念しか無いようだな。

254:デフォルトの名無しさん
07/10/23 21:51:34
板違い
よそでやれ

255:デフォルトの名無しさん
07/10/23 21:52:09
使い方が間違っているんだよ。
それを気づくことができないのか?

256:デフォルトの名無しさん
07/10/23 21:54:16
>>255
>>254

257:デフォルトの名無しさん
07/10/23 21:57:17
>>254
いやいや、質問する上でのマナーの話だからここで良い
マナーを守れない方がどっか行くべき

258:デフォルトの名無しさん
07/10/23 22:00:35
>>257
いやいや、ご質問する上でのマナーのお話だからここで良い
おマナーをお守りできない方がどっかへ行くべき


259:デフォルトの名無しさん
07/10/23 22:36:01
いや、マナーってほどの話ではないとおもう
変な日本語を使ってるけど、意味は理解できるから問題ない

てなわけで、おスレち

260:デフォルトの名無しさん
07/10/23 22:41:30
やっぱ誰でもアクセスできるローレベルな話のほうが伸びるなw

261:デフォルトの名無しさん
07/10/23 22:42:45
すまんなw
おれも、なんか参加しちゃってるよw

262:デフォルトの名無しさん
07/10/23 22:44:37
しょうがねーな
俺も参加してやろうか

263:デフォルトの名無しさん
07/10/23 22:46:22
僕もご参加していいですか?

264:デフォルトの名無しさん
07/10/23 23:25:29
どうぞ、ご参加ください。

265:デフォルトの名無しさん
07/10/23 23:36:57
珍しく盛り上がってると思ったら・・・

>>244
コード例


266:デフォルトの名無しさん
07/10/24 01:46:21
ひさびさに来ましたよー
相変わらずスレ違いにはレス多いね。

267:デフォルトの名無しさん
07/10/24 01:59:52
スレッドの呼び出しコストってどうやってはかるの?

組込み用でmutexとかの関数の呼び出しコスト一覧
表作り単位んだけどどうしたらいいん?

268:デフォルトの名無しさん
07/10/24 02:27:13
>スレッドの呼び出しコスト
具体的にどういう意味と受け取ったらよいのだ?


269:デフォルトの名無しさん
07/10/24 02:38:38
適当なタイマーで挟んではかr

270:デフォルトの名無しさん
07/10/24 08:11:41
>>265
URLリンク(developers.sun.com)
Standard Library, STL and Thread Safety
Atomic updates for reference counting

URLリンク(www.sparc.com)
J Programming With the Memory Modelsにいろいろ
J.6 Spin Locks(Example 8―Lock and Unlock Using CAS)
J.11 Fetch_and_Add(Example 15―Fetch and Add Using CAS)
J.12 Barrier Synchronization(Example 17―Barrier Synchronization Using CAS)
J.13 Linked List Insertion and Deletion(Example 18―List Insertion and Removal)

271:デフォルトの名無しさん
07/10/24 09:27:41
>>270
ktkr

272:デフォルトの名無しさん
07/10/25 08:14:03
C++でのマルチスレッドに関する質問です
class sample{
private:
 int i;
 HANDLE hEvent;
public:
 sample(){
  hEvent = CreateEvent(NULL, TRUE, TRUE, L"sample");
 }
 ~sample(){
  CloseHandle(hEvent);
 }
 void fSetdate(int _i){
  WaitForSingleObject(hEvent, INFINITE);
  ResetEvent(hEvent);//ロック開始
  this->i = _i;
  SetEvent(hEvent);//ロック解除
 }
 int fGetdate(){
  WaitForSingleObject(hEvent, INFINITE);
  ResetEvent(hEvent);//ロック開始
  int _i = this->i;
  SetEvent(hEvent);//ロック解除
  return _i;
 }
}

273:272の続き
07/10/25 08:17:17
上記のクラスをひとつだけインスタンス化して、
複数のスレッドがそれを呼び出した場合、データの同期化は成立しますか?

274:デフォルトの名無しさん
07/10/25 09:08:53
何が死体のこれ?


275:デフォルトの名無しさん
07/10/25 09:18:17
別々のスレッドがfSetdateのResetEventに同時に到達した場合どうすんの?

276:272の続き
07/10/25 09:39:20
あべし

クラス内部でイベントによってデータの同期をとろうと思ったんですよー。


277:デフォルトの名無しさん
07/10/25 10:03:47
何でCriticalSection使わんの?

278:272
07/10/25 10:27:32
>>277
イベントと違いがわからんっす

279:デフォルトの名無しさん
07/10/25 11:26:21
イベントを理解しとらんからだろ。
それで同期ってなにが目的なのよ?

280:デフォルトの名無しさん
07/10/25 11:44:13
正解を書きたいけど、それをコピペして終了されると悲しいので
ここは是非MSDNのドキュメントを読むなりして頑張って欲しい。

281:デフォルトの名無しさん
07/10/25 13:10:53
>>278
イベントとクリティカルセクションがどう違うかなんて、腐るほど説明があるから
いちいち書きたくないが、簡単に言うと

・イベント
遅い
プロセス間の同期に使える

・クリティカルセクション
速い&簡単
スレッド間の同期にしか使えない

あと、その目的でイベントを使うなら自動リセットイベントを使う。
そのコードだと275の懸念していることが、起こるかもしれないという
レベルではなく、確実に起こる。

282:デフォルトの名無しさん
07/10/25 13:20:09
何をどう同期したいのか分からんから起こっても変わらん気がするw

283:デフォルトの名無しさん
07/10/25 15:43:08
>>281
初心者に、あまり適当なこと教えるなよ。
それはどちらかというと、MutexとCRITICAL_SECTIONの違いだろ。

EventとCRITICAL_SECTIONの違い、あるいはpthreadにおけるcondとmutexの違いは
同期(実行をコントロールする)か排他(データを保護する)か。

284:272
07/10/25 18:24:31
みなさんどうもっす。
同期について根本的に勘違いしてました。
データの保護ではCriticalSectionを使うのですね。

でもEnterCriticalSection()が同時に
実行されるということはありませんか?


285:デフォルトの名無しさん
07/10/25 18:31:20
そんな質問が出るってことは
まだCriticalSectionについてググってすらいないようだな…。

286:デフォルトの名無しさん
07/10/25 20:26:43
>>284
>でもEnterCriticalSection()が同時に
>実行されるということはありませんか?
わらった。
そりゃ同時に実行されるさ。そのためのものだもん。

287:デフォルトの名無しさん
07/11/12 14:38:05
質問。
今のところはlinuxのpthreadのみを使っていますが、
なるべく一般のスレッドで使えるようにしたいと考えています。

複数のスレッド(X,Y,...)があってそれぞれが独立に動き、
読み込みアクセスrdと書き込みアクセスwrをします。
排他の条件は
1) XのrdとYのrd =>排他しない
2) XのrdとYのwr =>排他する
3) XのwrとYのwr =>排他する
4) XのwrとXのrd => 排他しない(wrの中からrdすることがあるので)
となっています。

自力で考えた手法はrwlockを使っています。
4)の条件を満たすためにrでロックする際はtryrdlock()して
・返り値がEDEADLKなら自スレッドがwrlockしているとみなしてロックせずに通す
・それ以外なら他スレッドがwrlockしているとみなして待機する
としています。
この手法で移植性は十分でしょうか?

288:デフォルトの名無しさん
07/11/12 14:58:54
移植性っても、どの程度を考えてるかによるけど、例えば Windows には reader writer lock がそもそもなかったような…

289:デフォルトの名無しさん
07/11/12 22:10:34
visutaから追加された。

290:デフォルトの名無しさん
07/11/12 22:15:25
びじゅた?


291:デフォルトの名無しさん
07/11/12 22:25:14
一般のスレッドって何だよ

292:デフォルトの名無しさん
07/11/12 22:38:23
なんで4)でrdロックする必要あるの?


293:デフォルトの名無しさん
07/11/12 23:47:18
ぴゅうた以来
プログラムかいてねーから
鈍ってしまって困った

294:デフォルトの名無しさん
07/11/13 09:52:33
返答ありがとうございます。

>>288
Windowsのスレッドは触ったことがなく、rwlockがないことを知りませんでした。

>>292
rwlockの状態を知るためにtrylock()しています。
pthreadに現在の状態を問い合わせる関数が見付からなかったのでこのようにしました。
(一般には現在の状態を問い合わせても
次のステップまでその状態が持続するとは限らないことは承知しています)

mutexからrwlockを実装するというのを本で読んだことがあるので
それを参考に実装してみます。

295:デフォルトの名無しさん
07/11/15 00:30:34
Linuxでpthreadを使用しているのですが
valgrindで実行するとfopenとfcloseの箇所で以下のエラーが大量に出ます。

==25540== Possible data race reading variable at 0x1D52238C
==25540== at 0x674CB5: _IO_un_link_internal (in /lib/tls/libc-2.3.4.so)
==25540== by 0x668A5D: _IO_fclose@@GLIBC_2.1 (in /lib/tls/libc-2.3.4.so)
==25540== Address 0x1D52238C is 52 bytes inside a block of size 352 alloc'd by thread 1
==25540== at 0x1D4A8090: malloc (vg_replace_malloc.c:131)
==25540== by 0x66935E: __fopen_internal (in /lib/tls/libc-2.3.4.so)
==25540== by 0x66941C: _IO_fopen@@GLIBC_2.1 (in /lib/tls/libc-2.3.4.so)

Webで調べるとglibcはすべてスレッドセーフだと書かれているのですが
同期とかしないといけないのでしょうか?
詳しいかた教えてください。


296:デフォルトの名無しさん
07/11/15 03:10:57
helgrind使ってるって事?
あとさ、glibc-2.3.4って偉い古いな。


297:デフォルトの名無しさん
07/11/15 03:13:19
関数がスレッドセーフであるかと同期が必要かは別問題

298:デフォルトの名無しさん
07/11/15 03:40:30
>>295
同じdescriptorを同時にopen/closeしにいったらまずいわな。歯痛汁。

299:295
07/11/15 12:29:07

>>296
CentOS4.5でhelgrind(valgrindは2.2)です。
yumしてみましたがglibcのバージョンは2.3.4が最新でした。

>>297
すみません、語弊がありました。
glibcがスレッドセーフでないならなにか回避策がないと
スレッドでは使用できなくなってしまうので一般的にはどうするのかなと。

>>298
すみません、説明が足りませんでした。
ファイルのオープン、リード、クローズは
すべて同一のスレッド内で行っています。


300:295
07/11/15 12:30:35
みなさん遅くにありがとうございます。
もう少し調べてみます。

301:デフォルトの名無しさん
07/11/15 22:26:00
valgrind3.3まで待ったら?

302:デフォルトの名無しさん
07/11/17 00:08:19
同僚に嫌がらせするだけのために

valgrind --tool=erogrindって
オプション作って

オワタって表示されるようにしたんだけど
さっきめっさ怒られたw

303:デフォルトの名無しさん
07/11/17 20:28:57
思いつきだが、最新のvalgrindのsupression fileを使ってhelgrindしてみるのはどうだろうか。


304:デフォルトの名無しさん
07/12/18 09:21:07
Linuxを使った組込機器の開発に、NPTLではなくLinuxThreadsというのを使うことになりました。
これは聞くところによると、あまりOSに頼らずに実装されたスレッドライブラリということですが、
たとえばpthread_mutex_lock関数はどのように実装されているのでしょうか?OSのシステムコール
を呼ばない形で実装されているのでしょうか?

ソース嫁かもしれませんが、詳しい方いらっしゃいませんか?


305:デフォルトの名無しさん
07/12/18 09:55:20
URLリンク(www.linux.or.jp)

306:デフォルトの名無しさん
07/12/18 11:18:26
アトミックオペレーションができるインストラクションをインラインアセンブラーで記述する事で実現している

307:デフォルトの名無しさん
07/12/18 21:23:24
しばらくspinしてもロック獲得できなかったらRTシグナル街に入るんだっけ?
それはともかく、俺は完全ユーザ空間な1:Nスレッドの実装方法、特にどうスレッドをスケジュールするのかがさっぱりわからない。


308:デフォルトの名無しさん
07/12/18 21:48:30
green thread

309:デフォルトの名無しさん
07/12/18 21:49:42
>>308
解説よろ

310:デフォルトの名無しさん
07/12/19 23:15:10
pthread規格で、
・端末で^CしたときのSIGINTシグナルは、どのスレッドに届くのか(あるいは全スレッドに届くのか)
・メインスレッドがexit()するとその他のスレッドは終了するのか
・メインでないスレッドがexit()したときはどうか
がわかりません。規格上どうなっているか、あるいは最近のLinuxでどうなるか教えていただけないでしょうか?
手元にSolarisしかなくて困ってます。

あ、main関数を実行したスレッドを勝手にメインスレッドと呼びました。


311:デフォルトの名無しさん
07/12/19 23:39:05
>>310
プロセス宛てのシグナルは、どれか一つのスレッドに届く。どれに届く
かは決められていないので、受け取りたいスレッド以外ではそのシグナ
ルをブロックするようにしておく。

exit()でプロセスが終了する。スレッドは関係ないはず。



312:デフォルトの名無しさん
07/12/19 23:39:21
スレッドセーフレベルの統一的な呼称ってあります?
引数がスレッドセーフじゃないとか条件付の状態とかあるよね。

313:デフォルトの名無しさん
07/12/20 11:07:35
シグナル受け専用スレッドって作る?

314:デフォルトの名無しさん
07/12/22 20:32:00
waitして何かあったらコールバックしてる。


315:デフォルトの名無しさん
07/12/23 19:58:10
pthread_cond_wait()でspurious wakeupが起こるのって具体的にはどういうときでしょうか?
どういう順番で、各スレッドの実行や切り替えが起こった場合でしょうか?

316:デフォルトの名無しさん
07/12/23 20:05:52
.NETのMonitor.Waitでもおこるかどうか知ってる人いませんか?

317:デフォルトの名無しさん
07/12/23 20:14:35
3000円ちらつかせると
解ってくるかもしれないw

318:デフォルトの名無しさん
08/01/01 20:48:11
>>315,316
マルチスレッドプログラムは基本的に非同期なので、何がおきても対応できるように冗長に作っておいたほうがいいと思う。



319:デフォルトの名無しさん
08/01/01 23:44:58
>>318
何も言ってないのと同じw

「基本的に」「何がおきても」「冗長に」って.....いかにも何も判ってない奴が使いそうなワードを連発されてもなぁ。

320:デフォルトの名無しさん
08/01/02 00:04:00
代わりに君が内容の有る事を言ってもいいんだよ

321:デフォルトの名無しさん
08/01/02 00:20:32
そんなものが書けると思っている段階でダメダメ

322:319
08/01/02 00:24:53
>>315 >>320
まず、cond_waitしているスレッドがシグナルを受信し、cond_waitがEINTRで戻った場合。

もうひとつ、これをspurious wakeupと呼ぶかは語の定義によるが、cond_wait中のスレッドがwakeさせられた際、
mutexをlockする前に別のスレッドがmutexを先にlockし、条件を偽にした場合。

どちらも、POSIXでは起きてよいことになっているけど、本当に起こり得るかどうかは実装による。

>>316
知らん


323:デフォルトの名無しさん
08/01/02 00:34:36
>>316
URLリンク(research.microsoft.com)
これの5.2

324:デフォルトの名無しさん
08/01/02 00:38:35
>>295
去年の12月にhelgrindの新しいの出たらしいよ。


325:デフォルトの名無しさん
08/01/03 09:46:44
>>295
複数のスレッドからアクセスすれば
"Possible" data race
になるのは当然なような
俺はそういう作り方はしない

326:デフォルトの名無しさん
08/01/05 01:33:19
>>295
ファイル操作用のスレッドかなにかに
終了通知送って閉じさせろよ

資源の管理はよほどの事情ないかぎり
一括にしろ
いいなわかったか?反論するなら
お前の家にそれは末恐ろしいものを
いくつかぶちまけて逃走するからな?

いいかわかったか?

327:デフォルトの名無しさん
08/01/06 23:38:52
C言語でマルチスレッドに挑戦していまして、
複数の子スレッドを途中停止させ、また再開できるような状態にしたいのですが、
いい方法はありませんか?

328:デフォルトの名無しさん
08/01/06 23:41:50
>>327
Cでどうやるのか忘れたけど、イベントなりセマフォなりミューテックスなりで待たせるのが
一般的。

329:デフォルトの名無しさん
08/01/06 23:47:25
>>327
pthread_barrier_wait()
とエスパー。

330:デフォルトの名無しさん
08/01/07 02:21:07
>>327

C言語にスレッドという概念はない。
環境書かないとわかんないよ。


331:デフォルトの名無しさん
08/01/07 09:38:37
WindowsXPです。

332:デフォルトの名無しさん
08/01/07 10:22:58
>>331

Winなら、MFC使ってUIスレッド作って、メッセージで動かすのが簡単だが。
Win32APIだけでやりたかったら、↓のマルチスレッドの章を一通り読んでみ。87章から。
URLリンク(www.kumei.ne.jp)

WaitForSingleObject() あたりを使うことになるだろうな。89章から先に載ってる。


333:デフォルトの名無しさん
08/01/07 11:51:27
レスありがとうございます。
調べましたところ、
WaitForSingleObjectはスレッドがシグナル状態になるまで待ち合わせを行うものだとありましたが、
これをどのように使えばスレッドを途中停止出来るのでしょうか?

334:デフォルトの名無しさん
08/01/07 11:55:26
>>333
スレッドで考えるんじゃなくて二人以上の作業者による連携プレーを考えろ
で、ひんとはミューテックスオブジェクトかセマフォオブジェクト

335:デフォルトの名無しさん
08/01/07 13:15:18
スレッドを止めたいって書いてあるのが読めないのか?
答えられないならレスするんじゃねぇよ。

336:デフォルトの名無しさん
08/01/07 13:25:13
>>335 をつつくとSuspendThread使えとか言い出しそうだな(笑

337:デフォルトの名無しさん
08/01/07 13:30:41
「いい方法はありません」ってことで。

338:デフォルトの名無しさん
08/01/07 15:08:45
>WaitForSingleObjectはスレッドがシグナル状態になるまで待ち合わせを行うものだとありましたが、

調べが足りてないね。

339:デフォルトの名無しさん
08/01/07 15:13:49
Windowsなんて使ってるやつは馬鹿です

340:デフォルトの名無しさん
08/01/07 15:21:29
>>339
なぜですか?

341:デフォルトの名無しさん
08/01/07 19:32:15
「ATOK使うやつは馬鹿」と何かの関係が!?

342:デフォルトの名無しさん
08/01/07 19:33:09
ここは良心的な釣堀か。入れ食いだな。

343:デフォルトの名無しさん
08/01/07 19:44:14

なぜ止めたいかを説明してケロ。
他のスレッドを強制的に止めたいのか、何かを待ちたいのか。
スレッドを止める方法はいろいろあるので、目的を説明して。

344:デフォルトの名無しさん
08/01/08 03:46:58
個人中傷スレだったので・・・

345:デフォルトの名無しさん
08/01/12 13:01:16
スレッドじゃないけど

fork()類って実行間隔って
あまりにも短いとダメなのかな?

346:デフォルトの名無しさん
08/01/12 14:11:33
>>345
なんで?


347:デフォルトの名無しさん
08/01/12 14:21:25
>>30msに一度呼ぶと
失敗するような気がするw



348:デフォルトの名無しさん
08/01/12 14:27:36
>>347
それシステム資源食い潰してるしwww


349:デフォルトの名無しさん
08/01/12 14:28:09
そもそもなんでそんなにfork()しなきゃならんのかと。
設計から見直せ。

350:デフォルトの名無しさん
08/01/12 14:31:43
>>349
fork()する回数は10回なのですが
なるべく速くfork()を10回完了させたいだけですw

351:デフォルトの名無しさん
08/01/12 14:33:43
OSくらいさらせや


352:デフォルトの名無しさん
08/01/12 14:34:37
>>350
exec

353:デフォルトの名無しさん
08/01/12 14:43:39
ちなみにSolaris 10 で
のことです

354:デフォルトの名無しさん
08/01/12 17:20:58
errno は?

355:デフォルトの名無しさん
08/01/12 17:30:49
ダメって何がダメだったのか・・・

356:デフォルトの名無しさん
08/01/12 22:41:41
>>350
preforkしろ

357:デフォルトの名無しさん
08/01/13 08:22:40
アセンブリでマルチスレッド
これ最速

358:デフォルトの名無しさん
08/01/13 13:26:49
同期とかも全部asmでやるの?

359:デフォルトの名無しさん
08/01/13 19:16:03
spin lock

360:デフォルトの名無しさん
08/01/13 20:38:31
>>359
fairnessの問題はどうする?

361:デフォルトの名無しさん
08/01/14 13:48:04
fairlock

362:デフォルトの名無しさん
08/01/14 18:00:45
【OS】Windows Vista Ultimate

【言語】C++

【実行環境】Visual C++ 2005 Professional, C++ Boost Library 1.34.1

【その他突起する事項】なし

bool shouldExit_;
istream &is;

void handler()
{
while(!shouldExit_)
{
string str;
is >> str;
}
}

handler関数がthreadのコールバック関数になるのですが
この関数を終了させようとしてshouldExit_にtrueを代入しても
入力が内場合、入力演算子を使用しているところでずっと待機してしまいます。
このスレッドを安全に終了させる方法はないでしょうか?

363:デフォルトの名無しさん
08/01/14 18:06:54
>>362
volatile bool shouldExit_=false;


364:306
08/01/14 18:08:38
すみません。
漏れていました。
本来のコードには書いてあるのですが、shouldExit_を評価するところまで処理を持って行けません・・・。

365:デフォルトの名無しさん
08/01/14 18:09:13
>>363
をいをい w
is>>str; でブロックされてるんだからこの場合フラグは関係ないだろ。

とりあえず入力をタイムアウト付きでやるか(C++でどうやるかは知らん)、
可能なら入力ストリームをクローズしてしまえ。

366:デフォルトの名無しさん
08/01/14 18:51:35
入力を待つけどキャンセルとか強制終了出来るようにしたいんだろ?

367:361
08/01/14 19:55:45
>>365
istreamの実態はネットワークなので
まさにその方法でうまくいきました。
ありがとうございます。

>>366
もしそれができればそうしたいです。
なるべくstreamに影響を与えたくないです。

368:デフォルトの名無しさん
08/01/14 22:15:59


【OS】 linux fedora 7
【言語】 C
【実行環境】 えー?何て書けばいいのかな?
【その他突起する事項】 特になし

質問ですが、何故pthread_createの第4引数はvoidでキャストするの?
argを入れるんだし。たとえば、整数 2を入れる場合も
(void *)2
みたいに渡しますよね。
構造体に渡すと言ってもポインタで渡したら良いだけのような....

そのまま入れたらダメな理由は何ですか?
教えてえろい人

369:デフォルトの名無しさん
08/01/14 22:29:32
なにをやろうとしているかを理解してからやれ、ということ

370:デフォルトの名無しさん
08/01/14 22:31:38
そういう関数作って
そのままいれてみろ


371:デフォルトの名無しさん
08/01/14 22:32:38
>>368
日本語でおkだよ

372:デフォルトの名無しさん
08/01/14 22:34:33
>>368
32bitで済むなら、キャストして無理やり渡したほうが楽ジャン

373:デフォルトの名無しさん
08/01/14 22:35:30
>>369-370
あ、ありがとう。

理解が足りないかもですね。

(int *)でも良いんじゃないですか?って思うんです。

やってみたけど、ダメだよー
なんです。orz

374:デフォルトの名無しさん
08/01/14 22:36:23
あ、64bit環境 gccです

375:368
08/01/14 22:37:13
373,374も私です。

376:デフォルトの名無しさん
08/01/14 22:39:18
LP64環境か。なら、(void*)2ULLじゃねーの?


377:デフォルトの名無しさん
08/01/14 22:40:18
void* argを数値に戻すときは、int i = (int)(unsigned long long)arg;

378:368
08/01/14 22:47:29
>376
(void*)2
で動きます。
プリプロセッサがそのように直しているのかも知れません。

>>377
ん?
pthread_create(&th , arg2 , arg3, (void *)2);
みたいに渡しますが
pthread_create(&th , arg2 , arg3, (int *)2);
ではダメな理由は何ですか?


379:デフォルトの名無しさん
08/01/14 22:47:42
uint64_tって書けよw

380:368
08/01/14 22:50:20
uint64_tもダメでした
キチンとかかず、ごめんなさい

381:デフォルトの名無しさん
08/01/14 22:53:52
>>380
お前だめだわ

pthread_create()のmanみて
引数の定義どうなってるか調べたか?

そこは何でも受け取れるようにvoid *になってるから
そう渡せやって定義に書いてあるだろボケ
東京湾に沈めるぞドあほ

382:368
08/01/14 22:57:43
>>381
man見てますよ。

なぜvoidでキャストするの?int*とかでも良いでしょ?ポインタで渡すだけでしょ?
ってことなんです。


383:368
08/01/14 22:59:01
ポインタで渡す限りintもcharもvoidも関係ないでしょ?って質問です

384:デフォルトの名無しさん
08/01/14 23:00:55
>>382
なんでint *なの? 汎用ポインタならvoid *が判りやすくていいじゃん。
# それとも、qsort()も使ったことがない人?

385:デフォルトの名無しさん
08/01/14 23:01:29
C言語の型って何のためにあるかわかる?

386:デフォルトの名無しさん
08/01/14 23:06:28
関係ないけどC99では整数⇔ポインタ変換する場合はintptr_tを使った方がよくて、
それやらないと最悪strict aliasingの最適化でバグっちゃうケースがあるらしい。

387:368
08/01/14 23:08:43
>>384
>汎用ポインタならvoid *
大抵、そうですね。
昔、voidに型は無い、という話だったけど、void型という型になっていて浦島
状態です。

>>385
話の流れから、メモリ確保の為。
intのサイズは小さく、他に大きなサイズの時困るって事でしょうけど。

今回は、pthread_create(&th , arg2 , arg3, (int *)2);
のように、サイズが小さくても、不整合は出ないような...
出るのかな?

388:デフォルトの名無しさん
08/01/14 23:13:41
いや、Cにはvoid型はないけどvoid*型はあるの。

389:デフォルトの名無しさん
08/01/14 23:17:11
void型はあるよ。
void型へのキャストもできるし。

390:デフォルトの名無しさん
08/01/14 23:17:48
>>387
サイズ云々はかんけーねーだろ
8byteの汎用アドレス渡すことに
何一々屁理屈こねてるんだアスペル房?



391:デフォルトの名無しさん
08/01/14 23:20:22
>>368
あるよ

392:368
08/01/14 23:20:31
>>390
>385は何のため?

>>389
void型って、出来てますよね?

393:デフォルトの名無しさん
08/01/14 23:20:42
>>387
考えがアセンブラだなぁ。
ひょっとして今時オブジェクト指向を理解できてない人?

394:368
08/01/14 23:22:59
>>393
確かに gcc -Sのコード見たほうがデバッグ早いです。

オブジェクト指向は、時々する程度です

395:デフォルトの名無しさん
08/01/14 23:23:51
>>392
厳密に型が決まってる言語だから
その場合に曖昧さを表現するには
C言語の場合、簡単な解決方法は
void *で表現すること
理解できないみたいだし四ねw

396:デフォルトの名無しさん
08/01/14 23:27:08
void hoge(void) {
return (void)0;
}

規格にも void type とかいう用語は出てくる。

397:デフォルトの名無しさん
08/01/14 23:27:48
>>395
理解しますが
>簡単な解決方法void *で表現
ならば、他に方法は有るのですか?無いのですか?

398:デフォルトの名無しさん
08/01/14 23:31:34
値は同じでも意味が違うものってあるでしょ。
C言語でいうなら同じ0でも、数学の0と、ポインタのNULLでは意味が違う。
それらを区別するために型という概念がある。
で型があることでコンパイル時に型チェックが可能となって意味の混同が起こってないかを調べられるわけ。

399:デフォルトの名無しさん
08/01/14 23:35:53
引数に int* ってあるなら、それは32bitの値へのアドレスを渡すということではなくて
intの意味を持ったものへのポインタを渡すって理解すべきなの。
だからそこへとある構造体へのポインタを渡すなんてのは設計も使い方も分裂症気味におかしいわけ。

400:368
08/01/14 23:43:00
>>398,399
なるへそ。分かりました。

けど、別の疑問が、**(ポインタのポインタ)で渡したら型の意味もないような

401:デフォルトの名無しさん
08/01/14 23:45:46
どうでもいいけど、(void *)2はともかく、(int *)2はきもい

402:デフォルトの名無しさん
08/01/14 23:51:41
*が何個付こうが話は同じ

403:368
08/01/14 23:59:01
了解。
皆さんありがとうーーーーー。
関数作ってみようか考えていましたが、しなくて良いみたいですね

404:デフォルトの名無しさん
08/01/15 00:31:43
やけにスレが伸びてるなと思ったらC言語講習会かよ・・・

405:デフォルトの名無しさん
08/01/15 00:34:54
じゃ、pthread_atfork関係でもする?


406:デフォルトの名無しさん
08/01/15 00:37:40
pthread_yield()で頼む。
NPだけど。

407:デフォルトの名無しさん
08/01/15 00:44:56
なんで?

408:デフォルトの名無しさん
08/01/16 01:36:25
スレッドで thread1 thread2の2つを走らせている場合
正常狩猟、異常終了両方で2つのthread1 thread2とも同時に終了させて
再度、起動したいのですが、どのようにして終了させたら安全ですか?

pthread_cancel(),ptrhread_join,pthread_exit


409:デフォルトの名無しさん
08/01/16 02:31:14
>>408
スレッドを抜ける

410:デフォルトの名無しさん
08/01/16 04:51:33
>>409
そりゃそうだ。
cancel-join
exit-joinが良いのかな?
どうしたら良いかな?
mutexは無しです

411:デフォルトの名無しさん
08/01/16 11:27:19
thread10個起動して、全部待ちたいときはどうすればいいの?

412:デフォルトの名無しさん
08/01/16 11:33:00
forでjoin回せば。Win32なら64個までの限定だけどWaitForMultipleObjectsとかあるけど

413:デフォルトの名無しさん
08/01/16 11:37:22
>>411
pthread_barrier_wait()

414:デフォルトの名無しさん
08/01/16 21:02:03
あざーす。

415:デフォルトの名無しさん
08/01/17 00:19:01
すみません
スレッドでがんがん動く関数がるけど、この関数は起動字にも動いて処理します。
起動字はスレッド起こしてないんだけどpthread_関係が入っている関数を使っていいの?
具体的にはpthread_atporkです

416:デフォルトの名無しさん
08/01/17 00:58:36
誤時がおおおいな

417:デフォルトの名無しさん
08/01/17 01:38:20
あっとぽーくなんてマニアックな関数、何に使うんだか。

418:デフォルトの名無しさん
08/01/18 01:50:30
deadbeefと関連がありそうだな
なさそうでもあるな

419:デフォルトの名無しさん
08/01/18 22:47:59
>>413

411じゃないけど、pthread_barrier_wait() はlinuxでは無いようです。
どうようの効果を期待できる関数は何ですか?あるいは、その組み合わせは?
教えてちゃんですまそん

420:デフォルトの名無しさん
08/01/18 23:57:18
>>419
あんたの使ってるディストリビューションが古いだけ。
もっと新しいglibcを積んでるやつを使え。

421:デフォルトの名無しさん
08/01/19 00:46:44
LinuxThreadsの頃からあったと思うんだがな。。。
何使ってんだ??

422:デフォルトの名無しさん
08/01/19 00:48:06
>>419
ほんとにないなら、mutexと条件変数の組み合わせで実現できるけど、結構難しいよ。
NPTLのpthread_barrier_waitの実装を読んで、真似するのが良いと思う。


423:419
08/01/19 02:35:01
>>420,421
cg-linuxていうらしいです。manで無かったんです
かえたらダメだと思います。多分。
kernel=2.4.17?みたいなことします。

pthread.hを見て本当にないか見てみます。

>>422
そんなドキュメントあるんですか、本当になかったら探します。

424:デフォルトの名無しさん
08/01/19 06:58:09

私が小学生の頃、
日本中でノストラダムスの予言が大流行していた。
「1999年の7月に人類は滅亡する!」
という例のお騒がせ終末予言である。

大人になって社会に出て働きだして、
あくせくと忙しく日々を過ごしながら、
1999年は、
ありふれた日常の中であっさりと過ぎていった。
人類は滅ばなかった。

これからここで、
1999年に起こるかもしれなかった人類の壊滅的破局を、
誰にも知られずにこっそりと回避させた人たちがいた...
という設定で、
荒唐無稽なストーリーを描いてみたい。
無論、100%完全なフィクションである。

URLリンク(www5.diary.ne.jp)


425:デフォルトの名無しさん
08/01/20 00:09:05
>>423
URLリンク(www.google.co.jp)
とかのことね。

426:デフォルトの名無しさん
08/01/23 02:29:53
>>425
くーーー、64bitなんですーーー
探してみますーーーー
こんなサービスもあっ短だメモメモ

427:デフォルトの名無しさん
08/01/23 05:25:11
bit数関係あんの?

428:デフォルトの名無しさん
08/01/23 14:35:26
cglinuxってキャリアグレード?

429:デフォルトの名無しさん
08/01/24 00:25:00
そうだろうね。カーネルバージョン見ると MontaVista っぽい。
だとするなら、サポートしてるかどうかはもんたに聞いた方が良いね。

というか、419が欲しい機能は本当にpthread_barrier_waitで合ってるんだよね?
>>411 を素直に読むと >>412 で FA だと思うんだが。
(まあ419がちゃんとわかってて聞いてるなら余計なお世話だけど)


430:デフォルトの名無しさん
08/01/24 15:23:46
matrix * matrixをpthread_createとpthraed_joinだけで、
ぶん回してみたけど(quad core)普通にthread無しで
やるほうがはるかに早かった。

pthread_createのコストが高いのかなあ?
threadを最初に作っておいてpthraed_cond_wait待っておいてスレッドを使いまわす
方式で再実装してみる。

431:デフォルトの名無しさん
08/01/24 15:55:51
スレッド数4にしてる?

432:デフォルトの名無しさん
08/01/24 16:25:48
している/いろいろやってみだ。
4,10,,12,16,32

32だと、たまーにtopでみていると2000%とかになっていた。
それでも、遅い。

433:デフォルトの名無しさん
08/01/24 16:27:54
×みだ
○みた

あと、スレッド数8が抜けていた。

434:デフォルトの名無しさん
08/01/24 19:28:15
コアが4個なんだからそれより多くしてもほとんどメリットはないだろ

435:デフォルトの名無しさん
08/01/24 19:31:44
プロセス生成に比べるとマシってだけで、
スレッドの作成(と終了)はそれなりにコスト高いよ。

436:デフォルトの名無しさん
08/01/24 19:36:38
並列化効率とかアムダールの法則とかでググれ

437:デフォルトの名無しさん
08/01/24 23:34:00
DualCoreXeon*2で実験した限りでは、core辺り処理量は(殆ど)変わらなかったけどなぁ。
分割の仕方が悪いんで内科医?

438:デフォルトの名無しさん
08/01/25 06:20:13
>>436
そんなの、スレッド本の第一章に書いてあるだろ。


439:デフォルトの名無しさん
08/01/26 13:54:13
Windowsで
4つのスレッドを開始させ、
一つのスレッドが終了次第、
ほかのスレッドも全て終了させる方法ってありますか?

440:デフォルトの名無しさん
08/01/26 14:02:01
>>439
そのように作ればそうなります。

441:デフォルトの名無しさん
08/01/26 14:07:17
>>440
すみません。
私の聞き方が曖昧でした。
手段を教えて下さい。

442:デフォルトの名無しさん
08/01/26 14:31:08
終了すると終了させるは微妙だが大きな違い

443:デフォルトの名無しさん
08/01/26 14:37:11
>>439
4人の子供のうち、誰か一人でも死んだという通知が来たなら、他の三人に死亡要求を掛ければよろしいかと。
子供が死亡要求を聞き届けてくれない仕様ならば、殺すしかありませんが。
いずれにしても、APIレベルで実装したいならAPIスレ、.Netでやりたいなら.Netスレ、そうでないならVSスレなり
初心者スレなり適当にどうぞ。


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