[表示 : 全て 最新50 1-99 101- 201- 301- 2chのread.cgiへ]
Update time : 07/22 01:51 / Filesize : 97 KB / Number-of Response : 333
[このスレッドの書き込みを削除する]
[+板 最近立ったスレ&熱いスレ一覧 : +板 最近立ったスレ/記者別一覧] [類似スレッド一覧]


↑キャッシュ検索、類似スレ動作を修正しました、ご迷惑をお掛けしました

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



1 名前:デフォルトの名無しさん mailto:sage [2006/09/10(日) 00:13:53 ]
マルチスレッドプログラミングについて語るスレ。
OS・言語・環境は問わないが、それゆえ明記すべし。

その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/

231 名前:デフォルトの名無しさん [2007/03/01(木) 11:14:25 ]
やべーvolatile最強すぎる

「volatileが最強でない環境って存在するの?」
「現存しないからvolatile最強wwwwwwwwwwwwwwwwwwww」

>>161 でFA出てるしwww

232 名前:デフォルトの名無しさん mailto:sage [2007/03/01(木) 11:18:50 ]
2000年問題に通じるものがあるな

233 名前:デフォルトの名無しさん [2007/03/01(木) 12:28:10 ]
[すれ立てるまでもない質問はここで]
で聞いてたんだが、此処で聞いた方が良いかと思ったので、
再質問させてもらいます。

Windows MFCでマルチスレッドは止めておいた方が良い
と、良く聞くんだけど、具体的にどんな問題が発生するのか
掲示しているところが無いんだけど、どうしてMFCでの
スレッドは嫌われるのか教えてもらえないでしょうか。
単なる好奇心なので、仮説でもうれし。


234 名前:デフォルトの名無しさん mailto:sage [2007/03/01(木) 12:42:43 ]
誰が言ってんだ、そんなこと。

235 名前:デフォルトの名無しさん [2007/03/01(木) 12:48:10 ]
>>233
それま色々なスレで同じ質問をしないほうが良いと言われただけでは?

236 名前:デフォルトの名無しさん mailto:sage [2007/03/01(木) 12:50:14 ]
>>233
とりあえず移動元に誘導書いておけよ、マルチ扱いされるぞよ。
俺も聞いたことない。

237 名前:デフォルトの名無しさん mailto:sage [2007/03/01(木) 13:27:04 ]
MFCに限らず、マルチ(複数の)スレッドで質問するのは良くない。

238 名前:デフォルトの名無しさん mailto:sage [2007/03/01(木) 14:21:41 ]
ワロタ

239 名前:デフォルトの名無しさん mailto:sage [2007/03/01(木) 16:05:38 ]
>>224
support.microsoft.com/kb/254956/




240 名前:233 mailto:sage [2007/03/01(木) 16:17:27 ]
>>234
>MFC のシステムそのものがマルチスレッドに向いていない。
ttp://www.kab-studio.biz/Programing/PragmaTwice/Main/292.html
さすがにどこで見たかを思い出せなかったので検索して
出てきたのが例えばこれとか。

>>236
>>237
移動元に書いてきたよ。
ごめんよ。


241 名前:デフォルトの名無しさん mailto:sage [2007/03/01(木) 17:05:31 ]
>>240
WaitForSingleObjectで待つんじゃなくて自イベントで通知
MFC関係なくないか?
読みづらいし会話式がアレだな

242 名前:デフォルトの名無しさん mailto:sage [2007/03/01(木) 17:17:57 ]
UIスレッドは確かに使わないかもしれない。向いてないとか難しいとかいうより必要性が薄い。
ワーカースレッドについては特にMFC特有の問題じゃないな。

243 名前:デフォルトの名無しさん mailto:sage [2007/03/01(木) 18:03:52 ]
>>240
じゃあ、そのサイトが間違い。
いや間違いというか、MFCがマルチスレッドに対して便利な機構を用意しているかというとNoだけど、
マルチスレッドを意識してないわけじゃない。つまり、ユーザーからロックできないグローバル変数、
クラス変数はロックしてる。
なんで、ユーザーからロックできる部分については、勝手にロックして、スレッドセーフにしろよ、
ってスタンス。それを「向いてない」と表現するかどうかは人による。
・MFCとマルチスレッドの関係 (Afx...でのMFCグローバル情報へのアクセス等)、
・Win32とマルチスレッドの関係 (SendMessageがらみのウィンドウループの把握、WinSockでのWM_を使った非同期処理等)、
・一般的なGUIシステムにおけるマルチスレッドの作法 (GUIスレッドを止めない、長時間処理は別スレッド、非同期化等)
を分けて考えるべき。


244 名前:デフォルトの名無しさん mailto:sage [2007/03/01(木) 18:24:21 ]
まぁMFCはガベコレがないという致命的欠点を持っているなんて
Wikipediaに書かれるほど挫折した連中に嫌われているってことだな。

245 名前:デフォルトの名無しさん [2007/03/01(木) 18:47:00 ]
> それを「向いてない」と表現するかどうかは人による。
「俺はマルチスレッドなプログラムなんかできないから、ライブラリか何かでどうにかしてくれよ」という人?
「これさえ使えばあら不思議。マルチスレッドなプログラムが簡単に!」とか。

>まぁMFCはガベコレがないという致命的欠点を持っているなんて
これは笑いどころですか?


246 名前:243 mailto:sage [2007/03/01(木) 19:03:59 ]
>> それを「向いてない」と表現するかどうかは人による。
>「俺はマルチスレッドなプログラムなんかできないから、ライブラリか何かでどうにかしてくれよ」という人?
>「これさえ使えばあら不思議。マルチスレッドなプログラムが簡単に!」とか。

いや、俺に言われても。

247 名前:244 mailto:sage [2007/03/01(木) 19:38:14 ]
>>245
> これは笑いどころですか?

いや、俺に言われても。

248 名前:244 mailto:sage [2007/03/01(木) 19:57:04 ]
>>247
いや、そこで騙られても。

249 名前:デフォルトの名無しさん mailto:sage [2007/03/01(木) 21:02:37 ]
MFCにガベコレを求めるとかバカとしか思えない



250 名前:デフォルトの名無しさん mailto:sage [2007/03/01(木) 21:11:36 ]
244はそんなことを言ってるわけじゃないんだが。
改行位置のせいで勘違いするのも分からんでもないが。

251 名前:デフォルトの名無しさん mailto:sage [2007/03/01(木) 21:27:35 ]
このスレのガベージをコレクトしたい

252 名前:デフォルトの名無しさん mailto:sage [2007/03/01(木) 22:08:15 ]
       / ____ヽ           /  ̄   ̄ \
       |  | /, −、, -、l           /、          ヽ
       | _| -|  ・|< ||           |・ |―-、       |
   , ―-、 (6  _ー っ-´、}         q -´ 二 ヽ      |
   | -⊂) \ ヽ_  ̄ ̄ノノ          ノ_ ー  |     |
    | ̄ ̄|/ (_ ∧ ̄ / 、 \        \. ̄`  |      /
    ヽ  ` ,.|     ̄  |  |         O===== |
      `− ´ |       | _|        /          |
         |       (t  )       /    /      |
「>1からマークスイープでGCするよ!」   「コンパクションも忘れずにね」

1時間後…

      ,-――-、                         ___
      { , -_−_−                        /  _   _ ヽ
     .(6( /),(ヽ|                       /  ,-(〃)bヾ)、l
     /人 ー- ソヽ _                    | /三 U  |~ 三|_
  /  /  |  ̄_∧/   ヽ                   |(__.)―-、_|_つ_)
      | |  \/_/-、    /                  /  /`ー--―-´ /
      |-\ _|_ )_|   /                  |  // ̄( t ) ̄/
      ヽ-| ̄|  |_|_ /                 ,− |   | ヽ二二/⌒l
    /  l―┴、|__)                 |  (__> -―(_ノ
 /    `-―┘ /                   `- ´
           /
「>1しか残らなかった…」               「テンプレへのリンクもなかったのか!」


253 名前:デフォルトの名無しさん mailto:sage [2007/03/01(木) 22:48:55 ]
>>251
     [゚д゚]  ・・・?
     /[_]ヽ
      | |

254 名前:デフォルトの名無しさん mailto:sage [2007/03/01(木) 23:53:37 ]
>>253
おまえは呼んでない

255 名前:デフォルトの名無しさん mailto:sage [2007/03/04(日) 02:15:45 ]
pthreadのPTHREAD_MUTEX_INITIALIZERのように、
win32のCRITICAL_SECTIONを静的に初期化する方法はありますか。

現在は仕方が無いので
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
で済むところを
static pthread_mutex_t mutex;
static int initialized;
static int lock;
if (!initialized && InterlockedIncrement(&lock) == 1) {
  pthread_mutex_init(&mutex, 0);
  initialized = 1;
}
などと書きました。

なお、↑のコードでは、とりあえず
#define pthread_mutex_t CRITICAL_SECTION
#define pthread_mutex_init(A,B) InitializeCriticalSection(A)
#define pthread_mutex_lock(A) (EnterCriticalSection(A), 0)
#define pthread_mutex_unlock(A) (LeaveCriticalSection(A), 0)
#define pthread_mutex_destroy(A) DeleteCriticalSection(A)
などと定義しています(極めてうさんくさいですが)。

256 名前:デフォルトの名無しさん mailto:sage [2007/03/04(日) 04:38:29 ]
>>255
class CriticalSection
{
    CRITICAL_SECTION csect;
public:
    CriticalSection() { InitializeCriticalSection(&csect); }
    ~CriticalSection() { DeleteCriticalSection(&csect); }
    void Lock() { EnterCriticalSection(&csect); }
    void Unlock() { LeaveCriticalSection(&csect); }
    operator LPCRITICAL_SECTION() { return &csect; } 
};

class Lock
{
    CriticalSection& save_cs;
public:
    Lock(CriticalSection& cs) : save_cs(cs) { save_cs.Lock(); };
    ~Lock() { save_cs.Unlock(); }
};


257 名前:デフォルトの名無しさん mailto:sage [2007/03/04(日) 04:40:47 ]
static CriticalSection cs1; // で初期化しておいて下のように使える。

void func(){
    Lock lock(cs1);
    // 
}

void func(){
    cs1.Lock();
    // 
    cs1.Unlock();
}


258 名前:デフォルトの名無しさん mailto:sage [2007/03/04(日) 05:07:50 ]
というやり方だと、
コンパイラの吐く「ローカルな静的変数の初期化コード」に排他処理が行われないため
グローバル変数(staticメンバでも良いが)にしか使えない。

で、過去スレに書いたが
CriticalSectionへのポインタとInterLockedExchangePointerを使えば
ローカルな変数でも、排他しながらの初期化及び実行が行える。

259 名前:デフォルトの名無しさん mailto:sage [2007/03/04(日) 05:21:53 ]
なるほど。C++のstatic objectの初期化機能を利用する訳ですね。
Cでは使えないテクニックですね……。

>>255のコードには不備がありました。
2コ目以降のスレッドがInitializedCriticalSection()実行前に
下に流れてしまう可能性があるので、
上のコードの後で
while (!initialized) Sleep(1);
としなければなりませんね。




260 名前:デフォルトの名無しさん mailto:sage [2007/03/04(日) 05:48:19 ]
>>258
>で、過去スレに書いたが 
目を通しておきたいのですが過去スレというのはこのスレですか?その4以前?

最初のロックまでCRITICAL_SECTIONの初期化を遅延したいとか
考えない限り大丈夫のように思えるけど。

261 名前:デフォルトの名無しさん mailto:sage [2007/03/04(日) 05:48:40 ]
んー、だから

static CRITICAL_SECTION *p = NULL;
if (!p) {
 CRITICAL_SECTION *q = new ...;
 Interlocked...(&p, NULL, q); //引数の順番忘れた
 if (p != q) {
  delete q;
 }
}
EnterCriticalSection(p);
...
Leave...();

なら、Cでも使えるよ。

262 名前:デフォルトの名無しさん mailto:sage [2007/03/04(日) 05:53:34 ]
で、C++なら、これをclassにまとめて
#ifdef _WIN32 で切り分けてPTHREAD_MUTEX_INITIALIZERと使い分けると楽だよ。
ただ、必ずstaticなオブジェクトとして使わないといけない、ということを
分かった上で使わないといけないけど。

263 名前:デフォルトの名無しさん mailto:sage [2007/03/04(日) 05:57:13 ]
あ、Initializeとか忘れてたけど
まあ分かるでしょ

264 名前:デフォルトの名無しさん mailto:sage [2007/03/04(日) 06:12:45 ]
>>261
new, deleteがCでも使えるというのは冗談でしょう。

if (!p) {
 CRITICAL_SECTION *q = new ...;

これは、この部分に2コ以上のスレッドが同時に突入した場合、
2度以上InitializeCriticalSection()を実行させたいという意味ですか?


265 名前:259 mailto:sage [2007/03/04(日) 06:15:36 ]
> while (!initialized) Sleep(1);

このように書きましたが、これはWin32環境で合法なのでしょうか。
マルチコアのシステムではまずかったりしますか。

MSVC++で-Ox最適化をかけたアセンブリコードを眺める限り、
一見動きそうに思えますが、いまいち自信がありません。

266 名前:260 mailto:sage [2007/03/04(日) 06:16:08 ]
>>261
初期化を遅延する場合ですね。それなら了解。

267 名前:デフォルトの名無しさん mailto:sage [2007/03/04(日) 07:08:09 ]
>>264
newが使えない事くらい、わかった上で書いたんだけど(面倒だから)
そんな本質的じゃない部分を指摘してうれしい?

件の部分は、(ほぼ)同時に突入したら、当然複数初期化される。
けど、続く部分で、実際に代入されるのは一つであることが保証される。
(最初に実行されたスレッド以外からのCASは失敗する)
だから、それを実行した後、自スレッドで初期化した値とpが違っていたら
それを破棄して、全スレッド共有の値でロックを実行すればよいだけ。


まあ、俺が偉そうな事言いたくて書き込んだだけだから、あまり気にするな。
普通に非ローカルな静的変数とC++のインスタンス初期化を使うのが
いちばん簡単だし、わかりやすいし、無駄も無い。
初期化順が問題になることも無いでしょ。

268 名前:259 mailto:sage [2007/03/04(日) 07:17:53 ]
>>267
> そんな本質的じゃない部分を指摘してうれしい?

気を悪くされたならすみません。
Cで書いた場合のコードに、>>255と本質的な違いがあるのか?と
問いたかっただけです。
newが使えないだけではなく、クラスも使えませんよね。
>>261は全くCのコードではありません。

> 件の部分は、(ほぼ)同時に突入したら、当然複数初期化される。
単に複数回初期化されるだけでなく、メモリリークが発生しますね。

269 名前:デフォルトの名無しさん mailto:sage [2007/03/04(日) 08:14:12 ]
> メモリリークが発生しますね。
だからわざわざ(本来なら省略しても良い)deleteまで書いたんだけど?



270 名前:デフォルトの名無しさん mailto:sage [2007/03/04(日) 08:17:06 ]
まさかとは思うけど
「実行中に確保(初期化)されて、終了時でも解放されないままのもの」
という意味で「メモリリーク」という言葉を使っている、
More Effective C++すら読んでないような初心者だったら、ごめんよ。

271 名前:デフォルトの名無しさん mailto:sage [2007/03/04(日) 08:20:53 ]
>>268
>>261はいろいろ省略してるのだけど、InterlockedCompareExchangePointerを使えといってるのだと思うよ。

>Cで書いた場合のコードに、>>255と本質的な違いがあるのか?と 
>問いたかっただけです。 

どちらも遅延初期化で本質的な違いはなさそうだけど、
>>261はダブルチェックロッキングが正しく出来ているが>>255には穴がある。



272 名前:259 mailto:sage [2007/03/04(日) 08:27:12 ]
>>269
理解しましたm(_ _)m
他スレッドのInterlockedExchangePointer()によって値が変えられていたら
deleteするという意味なのですね。

Cで書くと
static CRITICAL_SECTION *p = 0;
if (!p) {
 CRITICAL_SECTION *q = malloc(CRITICAL_SECTION);
 InitializeCriticalSection(q);
 InterlockedExchangePointer(&p, q);
 if (p != q)
  free(q);
}
でしょうか。

273 名前:259 mailto:sage [2007/03/04(日) 08:30:03 ]
んが。
malloc(sizeof(CRITICAL_SECTION));
ですね。

それと。InterlockedExchangePointer()ではなく、
InterlockedCompareExchangePointer()を使わなければならないのですか。

むずかしい...。

274 名前:259 mailto:sage [2007/03/04(日) 08:32:30 ]
>>271
>>255のコードの穴というのは、>>259に書いたのとは別のものでしょうか。

275 名前:デフォルトの名無しさん mailto:sage [2007/03/04(日) 09:21:12 ]
あーそうか、ほんとごめん。
確かに>>271の通り、CompareExchangeの方のこと(つまり>>258が俺の凡ミス)。
俺が重要な部分を間違えていたのに、意図を理解してくれる人がいてくれて助かった。
他の人も含め、ごめんね。

>>259では、本質的な解決にならないと思うよ。
つまり、比較(テスト)と初期化(&代入)の間に他のスレッドに割り込まれる可能性を消すには
atomicなCASを実行するしかないって事。

276 名前:デフォルトの名無しさん mailto:sage [2007/03/04(日) 09:31:57 ]
あ、そうか、>>255を見るとInterlockedを使っているのか。
でも、InterlockedIncrementは正負と0しか判定できないんじゃなかったかな。

で、仮に
初期値を-1として
2^32個以上のスレッドが同時に初期化部に入ることは有りえないとして
>>259の修正(Inc失敗なら他のスレッドを待つ)を加えて
当然volatileにして
とすれば、正常に動くのかな。

でもそこまでするなら、やっぱりCASを使う方がまともかと。

277 名前:259 mailto:sage [2007/03/04(日) 09:40:12 ]
>>276
はい。CAS方式がエレガントでまともなコードであると納得できました。
Sleep()ループで待つなんてカッコ悪いことは出来ればしたくありません...。
有難うございます。

278 名前:デフォルトの名無しさん mailto:sage [2007/03/04(日) 09:45:22 ]
ここまでやれば大丈夫だと思うけど。
if (!initialized)
 if(InterlockedIncrement(&lock) == 1) { 
  pthread_mutex_init(&mutex, 0); 
  initialized = 1;
    メモリバリア〜〜
 } else {
    while (!initialized) {
        Sleep(1);
        メモリバリア〜〜  またはinitializedが揮発性であることが必要
    }
 }
}
老婆心から言えばスレッド生成前までに作っておいたほうがよいと思う。
スレッド生成後の初期化なんてバグの元。
PTHREAD_MUTEX_INITIALIZERマクロが何をやってるか調べてみたら何かヒントがあるかもしれないね。
javaで有名になったダブルチェックロッキングの話はまだ半分くらいしか理解できてないしなorz


279 名前:デフォルトの名無しさん mailto:sage [2007/03/04(日) 09:47:50 ]
InterlockedIncrementはWin95以前だと正負と0の判定しかできないので>>255のようには使えないよね。

あと厳密に言えばの話だけど
このスレの上のvolatile関連の議論からするとinitialized=1;の変更がキャッシュのせいで
他のスレッドに伝わらないかもしれない(規格的には)ので>>255のinitializedにはlock命令が必要だけど
lock命令を追加しようとすると結局>>261みたいになってしまうんじゃないかな。

別に言わなくてもわかるだろうけど
>>255は volatile static int lock = 0;
>>272
volatile static CRITICAL_SECTION *p = NULL;
if (p != q) { DeleteCriticalSection(q); free(q); }



280 名前:デフォルトの名無しさん mailto:sage [2007/03/04(日) 09:49:12 ]
> PTHREAD_MUTEX_INITIALIZERマクロが何をやってるか
これはさすがに定数値を{}なりで囲んでるだけだと思うけど。
Cでも使えるんだし。

281 名前:259 mailto:sage [2007/03/04(日) 09:52:14 ]
PTHREAD_MUTEX_INITIALIZERは単に{ 0 }
とかだと思います。

>>279
うわ。赤面しまくりです...。

ぶっちゃけUnixベースのライブラリをちょろっといじくってWin32に
移植しようと思っただけなのですが、こんなワナが待っていたとは
思ってもいませんでした。

282 名前:デフォルトの名無しさん [2007/03/04(日) 10:24:41 ]
下の例の場合変数iにvolatileは必要かどうか質問です。
lock, unlockがメモリバリアだから必要ないという認識なのですがつけている例も見ます。
>>261だとlockせずに読んでる箇所もあるので必要なのかもしれませんが、
この辺の基準ってどうされていますか?

int i;

thread_function() {
   mutex.lock()
   i = i + 1;
   mutex.unlock()
}


283 名前:デフォルトの名無しさん mailto:sage [2007/03/04(日) 10:32:03 ]
だれか
.NET Frameworkのメモリモデルとかに詳しい人おらんかね?


284 名前:デフォルトの名無しさん mailto:sage [2007/03/04(日) 10:42:25 ]
>>282
付けといた方がいいんじゃない?mutexのメモリバリアでcpuキャッシュの同期は取れても
スタックやレジスタに積まれたままだったら意味ないしね。

285 名前:デフォルトの名無しさん mailto:sage [2007/03/04(日) 11:17:03 ]
>>283
設計上はウィークメモリオーダリングということなので、OoOあり〜の、コヒーレンシキャッシュは信用できね〜のです。
今のところ実装上はx86系のWindows上ではストロングメモリオーダリングのみ。
Itaniumは構成によってウィークメモリオーダリングもある得るそうです。

286 名前:デフォルトの名無しさん mailto:sage [2007/03/04(日) 11:51:52 ]
ところが、CLR2.0では書き込みオーダは保証されてて、
今後もそうだと約束されてるらしい。

それはおいといて、よく理解できてないのが、
書き込みスレッドでメモリバリアを実行した場合、
読み込み前のメモリバリアは必要なのかどうか。

あるメモリ領域に書き込みしてメモリバリア実行、その後完了フラグセット。
別スレッドで完了フラグを確認してからメモリ領域を読み込みってときに、
完了フラグ確認後にメモリバリアは必要なのかどうか。
なんとなく読み込み順が保証されないから必要な気もするんだが、
.NETのメモリバリア命令はフルメモリバリアだから不要?ってのも見た。
.NETのメモリバリアは別プロセッサの読み込みキャッシュもクリアして
かつJITの最適化とかで先読みとかがおこらないなら大丈夫なんだと思うんだけど
この方面素人なのでいまいちよく分からない。


287 名前:デフォルトの名無しさん mailto:sage [2007/03/04(日) 11:53:25 ]
メモリバリアの説明には、このプロセッサ上でキャッシュをフラッシュするとかって説明になってんだよね…


288 名前:デフォルトの名無しさん mailto:sage [2007/03/04(日) 13:04:32 ]
Itaniumだと、そもそもout of orderしないですな。
命令の並べ替えや並列化はすべてコンパイラの仕事だ。

289 名前:デフォルトの名無しさん mailto:sage [2007/03/04(日) 13:11:11 ]
だからこそ その辺の事情は本来プログラムで意識したくないよな・・・

DCLの欠点なんて最たるものだし



290 名前:デフォルトの名無しさん mailto:sage [2007/03/04(日) 17:17:43 ]
>>282
メモリバリアだから必要ないという認識では、ちょっと違うね。
関数呼び出しをまたいでグローバル変数をキャッシュできないから
volatileが必要ないというのが本質。
変数をレジスタ等にキャッシュしていないからこそ、メモリバリアが有効になる。

仮にlockやunlockをインライン展開できるようなコードで実装できたとすると
while() { lock(); i = i + 1; unlock(); } はvolatileが無いと危険かもしれない。

291 名前:デフォルトの名無しさん mailto:sage [2007/03/04(日) 19:41:48 ]
>>290
それは本質じゃなく単なる実装の話だと思います。
たとえばmsvc++などは次の理由からそういう実装になっています。
現在のx86系WindowsはOoOはやっててもアプリからは見えないハード的な仕掛けになっていますし、
コヒーレントキャッシュもある前提なのでキャッシュによる不整合もありません。
x86はレジスタの数が少ないので関数呼び出しのタイミングで変数をメモリ上に書き出します。

たとえばpthreadのmutexではvolatileは不要とドキュメントにあります。
すべてのコンパイラがそうなってるかどうかは分かりませんが、少なくともスレッド系のライブラリと一体で
提供されている環境ではサポートされているはずです。

292 名前:デフォルトの名無しさん mailto:sage [2007/03/04(日) 20:23:08 ]
>>291
インライン展開できない関数を呼ぶ前は、x86であろうと無かろうと
非ローカル変数をキャッシュできないよ。
レジスタの数が問題なのではなく、非ローカルな変数は呼び出した先で
更新される可能性があるから。

293 名前:デフォルトの名無しさん mailto:sage [2007/03/04(日) 21:03:48 ]
あと、ローカル変数でも、アドレスを取って他の関数に渡している場合に
その前と後で変数の中身が変更される可能性は、コンパイラも考慮しているはず。
だから例えば>>255のlockや>>272のpにはvolatile不要なはず。
もちろん、>>255のinitializedには必要だけどね。

で、pthread_mutex_tも、アドレスを取って渡すのだからvolatile不要、
という考え方でも充分かもしれない。

ただし、アドレスを取って呼び出した関数から戻った後に
変数の中身が他のスレッドによって変更される可能性は考慮されないので
レジスタにキャッシュされるかもしれない。
それが問題になる可能性がある(コードで中身を参照している)ならば
volatileが必要になるね。

294 名前:デフォルトの名無しさん mailto:sage [2007/03/04(日) 21:29:48 ]
>>292
確かにそこは例えが悪かったので取り消します。
(PGOのような広域のインライン展開のことを考えていたのですが論旨に合わないようです)
言いたかったのは同期関数の呼び出しのタイミングで
偶然レジスタとメモリの同期が取られているという話ではなく、
メモリバリア実現の属性のひとつとして関数の呼び出し時にレジスタとメモリの同期が
とられるという仕組みが利用されてるということです。
だから、レジスタとメモリの同期以外にCPUキャッシュ間の同期やOoOの調整が必要ならば
その処理が同期関数に含まれていなければならないと考えているわけです。


295 名前:デフォルトの名無しさん [2007/03/05(月) 18:53:41 ]
         ____
       /      \
      /  ─    ─\
    /    (●)  (●) \馬鹿ばっか
    |       (__人__)    |
     \      ` ⌒´   /
    ノ           \
  /´               ヽ
 |    l              \
 ヽ    -一''''''"~~``'ー--、   -一'''''''ー-、.
  ヽ ____(⌒)(⌒)⌒) )  (⌒_(⌒)⌒)⌒))

296 名前:デフォルトの名無しさん [2007/03/05(月) 22:57:17 ]
volatile旋風スゴス

297 名前:デフォルトの名無しさん mailto:sage [2007/03/10(土) 22:35:07 ]
質問です。

while ( count > 1 ){
 pthread_cond_wait( &cond_t, &mutex );
}
この場合、条件変数と呼ばれるものはcountですか?
それともcond_tになるのでしょうか?
また、countのチェックにifは使ってはならない。と言われたのですが、
なぜだか解りません。
上記の部分と、
while (1){
 if( count > 1 ) pthread_cond_wait(ry);
}
は同じだと思うのですが・・・
よろしくお願いします

298 名前:デフォルトの名無しさん mailto:sage [2007/03/10(土) 22:51:41 ]
>>297

while (1)

  if( ! (count > 1) ) break;
  pthread_cond_wait(ry); 

と同じだと思う。

299 名前:デフォルトの名無しさん mailto:sage [2007/03/10(土) 23:04:21 ]
>>298
そうでした。すんません



300 名前:デフォルトの名無しさん mailto:sage [2007/03/10(土) 23:33:31 ]
> 条件変数と呼ばれるものはcountですか?それともcond_tになるのでしょうか?
条件変数はcond_t。!(count>1)は述語。

> countのチェックにifは使ってはならない。と言われたのですが、
言った本人に聞けばいいと思う。いけないってことは無いと思う。
pthread_mutex_lock(&mutex);
while (!pred(ry))
 pthread_cond_wait(&cond, &mutex);
pthread_mutex_unlock(&mutex);
というのが定型パターンの予感はするんで、
その人にとって奇怪なコーディングするなという意味かもしれん。

301 名前:デフォルトの名無しさん mailto:sage [2007/03/11(日) 08:33:14 ]
ありがとうございます。
countは述語っていうのですか。知りませんでした。
>ifでんでん
後でもう一度聞いてみます。

302 名前:デフォルトの名無しさん mailto:sage [2007/03/11(日) 11:25:05 ]
でんでんってなんだ。云々(うんぬん)と言いたいのか、わざとボケてるのかどっちだ。

303 名前:デフォルトの名無しさん mailto:sage [2007/03/11(日) 12:35:43 ]
>>302
単なる2chのジャーゴンだから気にするな

304 名前:デフォルトの名無しさん mailto:sage [2007/03/11(日) 14:17:43 ]
countが述語なんじゃなくて
"count>1"が述語
countは単なる変数

305 名前:301 mailto:sage [2007/03/11(日) 15:38:51 ]
>>304
"count>1"で、述語。ですか。解りました。
ありがとうございます。

>>でんでん
"うんぬん"で"云々"ですか。初めて知りました
ゆとり年代より一つ上なはずなんだけどゆとりでごめんなさい

306 名前:300 mailto:sage [2007/03/11(日) 15:43:08 ]
ごめん。!(count>1)でなく、count>1だった。
301に幸あらんことを。

307 名前:デフォルトの名無しさん mailto:sage [2007/03/11(日) 15:43:39 ]
俺がかつて1日だけ流行らそうとしてばら撒いてたでんでんが意外な影響を。

308 名前:デフォルトの名無しさん mailto:sage [2007/03/11(日) 16:04:43 ]
「云々」を「でんでん」ってことは
「云」を「でん」と読んでるって事だよな。

俺、そもそも「云」という漢字、単独でどう読むか知らないのだが。

309 名前:デフォルトの名無しさん mailto:sage [2007/03/11(日) 16:29:44 ]
>>308
「ウン」でしょ。



310 名前:デフォルトの名無しさん mailto:sage [2007/03/11(日) 16:37:38 ]
伝が“でん”だからなあ

311 名前:デフォルトの名無しさん mailto:sage [2007/03/11(日) 20:45:06 ]
雲が「うん」と読まれることには頓着しないらしい。

312 名前:デフォルトの名無しさん mailto:sage [2007/03/11(日) 22:22:20 ]
ワンタン
雲呑

313 名前:デフォルトの名無しさん mailto:sage [2007/03/12(月) 00:36:16 ]
うーんぬんむーしむし、かーたつむりー

314 名前:デフォルトの名無しさん [2007/03/16(金) 09:25:59 ]
         ____
       /      \
      /  ─    ─\
    /    (●)  (●) \  「テラワロスwwwwwwwうぇうぇwwww」・・・・と
    |       (__人__)    | ________
     \      ` ⌒´   ,/ .| |          |
    ノ           \ | |          |
  /´           カタ.    | |          |
 |    l             カタ  | |          |
 ヽ    -一ー_~、⌒)^),-、   | |_________|
  ヽ ____,ノγ⌒ヽ)ニニ- ̄   | |  |       ____


315 名前:デフォルトの名無しさん [2007/03/20(火) 00:12:35 ]
ごめん書籍いいでしょっていわれてるけれど
マルチスレッドの勉強する本をおしえてほしいの

316 名前:デフォルトの名無しさん mailto:sage [2007/03/20(火) 00:32:02 ]
マルチスレッドについて本で得られるものは1%もない。
といっては見もふたもないので、もう少し具体的にマルチスレッドで何をしたいの?

OSは?マルチスレッドアプリ?APIがしりたい?それともカーネルの実装(はないよな)?

317 名前:デフォルトの名無しさん [2007/03/20(火) 15:54:59 ]
Unix 方面の人は「実践マルチスレッドプログラミング」
Win32の人は「Win32マルチスレッドプログラミング」

当り前のことが当たり前に書かれてるだけで、
別にいいも悪いもないけど。

このあたりに出てくるような概念、問題、手法については常識として理解した上で、
新しい手法やOS/CPU/言語毎のメモリモデルなどについての知識を深めると、
volatile 論議とかで無駄に遊べる。

318 名前:デフォルトの名無しさん mailto:sage [2007/03/20(火) 23:15:04 ]
>>315
Java使いなら↓は超オススメ。
www.amazon.co.jp/Java-Concurrency-Practice-Brian-Goetz/dp/0321349601
邦訳版もあるよ。

319 名前:デフォルトの名無しさん [2007/03/21(水) 00:27:18 ]
>>317
素朴な疑問

> Unix 方面の人は「実践マルチスレッドプログラミング」
> Win32の人は「Win32マルチスレッドプログラミング」

この辺を読めば volatile 最強って言い切れるようになるんですか?




320 名前:デフォルトの名無しさん mailto:sage [2007/03/21(水) 03:30:37 ]
317をもう一度よく読んだほうがいいんじゃない?

321 名前:デフォルトの名無しさん mailto:sage [2007/03/21(水) 04:34:08 ]
自作自演の可能性

322 名前:デフォルトの名無しさん mailto:sage [2007/03/21(水) 13:51:09 ]
volatile厨を論破するのはそんなに簡単じゃないよ。

323 名前:デフォルトの名無しさん mailto:sage [2007/03/21(水) 15:55:04 ]
NG登録するだけだし

324 名前:デフォルトの名無しさん [2007/03/24(土) 10:03:31 ]
Win32の本ってオライリーのやつのことでいいの?

325 名前:デフォルトの名無しさん mailto:sage [2007/03/24(土) 15:56:09 ]
>>315
並行プログラミングの原理―プロセス間通信と同期への概念的アプローチ (単行本)

326 名前:デフォルトの名無しさん [2007/03/27(火) 14:50:58 ]
          ____
       / \  /\  キリッ
.     / (ー)  (ー)\
    /   ⌒(__人__)⌒ \ volatile厨を論破するのはそんなに簡単じゃないよ。
    |      |r┬-|    |  
     \     `ー'´   /
            ___
       /      \
クスクスッ /ノ  \   u. \ !?
    / (●)  (●)    \
    |   (__人__)    u.   |
     \ u.` ⌒´      /
         ____
       /      \!??
      /  u   ノ  \    クスクスッ
    /      u (●)  \
    |         (__人__)|
     \    u   .` ⌒/



327 名前:デフォルトの名無しさん [2007/03/27(火) 22:33:12 ]
Javaのsynchronizedとwaitとnotifyに関する質問なんだが

www.javaworld.jp/technology_and_programming/-/10941-5.html
ここの

class Buffer {
private int value;
private boolean isEmpty = true;
public synchronized void putValue(int v) {
while (!isEmpty) {
try {
wait();
} catch (InterruptedException e) { }
}
notifyAll();
isEmpty = false;
value = v;
}
public synchronized int getValue() {
while (isEmpty) {
try {
wait();
} catch (InterruptedException e) { }
}
notifyAll();
isEmpty = true;
return value;
}
}
これがどうして動くのか分からん。
あるスレッドがgetValueに入ってる間は、ほかのスレッドは
getValueにもputValueにも入れないんじゃないのか

328 名前:デフォルトの名無しさん mailto:sage [2007/03/27(火) 22:34:13 ]
すまんソースコードが見づらくなってしまった。
リンク先を見てくれ。

329 名前:デフォルトの名無しさん mailto:sage [2007/03/27(火) 22:52:21 ]
>>327
前のページで説明されてる。




330 名前:デフォルトの名無しさん mailto:sage [2007/03/27(火) 22:53:08 ]
ttp://sdc.sun.co.jp/java/docs/j2se/1.4/ja/docs/ja/api/java/lang/Object.html#wait()

の二段落目を理解できない無能?

331 名前:デフォルトの名無しさん mailto:sage [2007/03/27(火) 23:05:42 ]
すまんかった。
とんくす






[ 続きを読む ] / [ 携帯版 ]

前100 次100 最新50 [ このスレをブックマーク! 携帯に送る ] 2chのread.cgiへ
[+板 最近立ったスレ&熱いスレ一覧 : +板 最近立ったスレ/記者別一覧](*・∀・)<97KB

read.cgi ver5.27 [feat.BBS2 +1.6] / e.0.2 (02/09/03) / eucaly.net products.
担当:undef