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

このエントリーをはてなブックマークに追加
713デフォルトの名無しさん
orz って今の今まで、

○| ̄|_  の小さい版とは知っていたが、

四つんばいとは知らなんだ。
拳を握り、目を細めて ウググググ・・・って悔しがってるのかと思ってた。
714デフォルトの名無しさん:2005/06/27(月) 03:11:43
> 拳を握り、目を細めて ウググググ・・・
が分からん。orz
715デフォルトの名無しさん:2005/06/27(月) 03:52:26
漏れもわからん・・・
716デフォルトの名無しさん:2005/06/27(月) 04:32:17
とりあえず漏れの解釈。

顔の線
 ↓
○| ̄|_
↑ ↑ ↑
拳 目 鼻
717せめてOSくらい明記しようや:2005/06/27(月) 04:58:15
>>716

○| ̄|_  ̄|○
718デフォルトの名無しさん:2005/06/27(月) 05:01:52
伝説の予感・・・
719デフォルトの名無しさん:2005/06/27(月) 08:07:34
o/z-/b
720デフォルトの名無しさん:2005/06/27(月) 08:15:57
  @@@
 @@@@
○| ̄|_  ̄|○
  \◎/
   | | ̄|_  ○| ̄|_  orz
721デフォルトの名無しさん:2005/06/27(月) 08:59:46
>>716
見えるぞ、私にも見える!
722デフォルトの名無しさん:2005/06/27(月) 12:15:22
短足だから見間違えたんだな。
○| ̄|_
なら顔には見えまい。
723デフォルトの名無しさん:2005/06/27(月) 13:02:14
  @@@
 @@@@
○| ̄|_  ̄|○
  \ー/ ニヤリッ
724デフォルトの名無しさん:2005/06/27(月) 14:20:34
にしこり
725713:2005/06/27(月) 19:49:48
そうです。
726デフォルトの名無しさん:2005/06/27(月) 23:42:56
新キャラ誕生の瞬間を目撃!?
727713:2005/06/27(月) 23:54:47
顔の線
 ↓
○| ̄|_
↑ ↑↑
拳 目 口

これ、口だから。崩さんといて。<@
728デフォルトの名無しさん:2005/06/28(火) 00:04:57
く、口なのか?
729713:2005/06/28(火) 00:08:58
>>728
そうです。
730デフォルトの名無しさん:2005/06/28(火) 00:20:45
>>702
クリーンアップしてる間はキャンセル禁止(か遅延)にしとけば?
731デフォルトの名無しさん:2005/07/03(日) 22:45:44
クリーンナップ中にpthread_setspecific()したら
再度クリーンナップされるのはPOSIXの正しい仕様ですか?
732デフォルトの名無しさん:2005/07/05(火) 01:44:58
哲学者にレイプされました。アノ人たちにとってアタシは共有リソースだったんです。
三つの穴にとっかえひっかえ入れられて。入れてない哲学者は瞑想にふけて、
順番が来るのを待ってました。
アタシはセマフォなんて信じない。
デッドロックは無かったです。(T T)
733デフォルトの名無しさん:2005/07/05(火) 07:38:24
入れる物が一つならデッドロックはないわな
734デフォルトの名無しさん:2005/07/05(火) 09:33:43
○| ̄|_ ̄|○
735デフォルトの名無しさん:2005/07/05(火) 09:40:38
○| ̄|_ ̄|○ <デッドロックに耐えてよくがんばった!
736デフォルトの名無しさん:2005/07/05(火) 10:04:15
クラス内の関数をスレッド化することを考えています。

    for (int i=0;i<threadnum;i++)
    {
        if(pthread_create(&tid[i],NULL,(THREADFUNC)threadRoutine,(void*)i) != 0)
        {
            perror("pthread_create");
        }
    }

と書くと、3行目のところで
error: invalid use of member (did you forget the '&' ?)
というエラーが出てしまいます。

プライベートメンバ関数の
threadRoutine

void threadRoutine(void* pParam);
と宣言するところを
static void threadRoutine(void* pParam);
にすると、コンパイル可能なようなのですが、今度は、そのメンバ関数内で、staticではないメンバ変数が使えなくなってしまいます。
どのようにすればよいのでしょうか?
737736:2005/07/05(火) 10:06:02
(THREADFUNC)、tidはそれぞれ

typedef void *(*THREADFUNC)(void *);
pthread_t   tid[threadnum];

です。
738デフォルトの名無しさん:2005/07/05(火) 10:06:39
○| ̄|_ ̄|○ <スレッドよりもC/C++の勉強をしたまえ!
739デフォルトの名無しさん:2005/07/05(火) 16:20:26
○| ̄|_ ̄|○

これって、ルイ14世のAA?
740デフォルトの名無しさん:2005/07/05(火) 16:36:55
○| ̄|_ ̄|○ <私は哲学者だ。デッドロックは許さん。
741デフォルトの名無しさん:2005/07/05(火) 18:35:09
○| ̄|_| ̄|○
742デフォルトの名無しさん:2005/07/05(火) 18:41:47
○| ̄|_ ̄|○ <か、かあさん!
743デフォルトの名無しさん:2005/07/05(火) 23:37:12
○| ̄|_ ̄|○ < >>736>>629と同一人物なのか?
なんでこう同じ質問がなんども... _ ̄|○
744デフォルトの名無しさん:2005/07/06(水) 01:40:50
>>740 こんな感じでつか
                      Ψ
            ○| ̄|_| ̄|○
          Ψ                   Ψ
○| ̄|_| ̄|○           ○| ̄|_| ̄|○

            Ψ                Ψ
  ○| ̄|_| ̄|○       ○| ̄|_| ̄|○
745デフォルトの名無しさん:2005/07/06(水) 06:21:06
>>736
関数はstaticにして、クラス内の変数を使いたければ、クラス自体をその関数に
ポインタとして渡すしかない。
746デフォルトの名無しさん:2005/07/06(水) 08:56:21
>>745
○| ̄|_ ̄|○ <君もC/C++の勉強をしたまえ!
747デフォルトの名無しさん:2005/07/06(水) 09:09:19
>>736
Javaつかえ。C++はあまりマルチスレッド向きではない。
748736:2005/07/06(水) 14:25:39
ここは荒れたスレのようですね。他に行きます。
749デフォルトの名無しさん:2005/07/06(水) 14:31:45
○| ̄|_ ̄|○ <君の悩みはスレッドとは関係ないからC/C++のスレにでも逝きたまえ。
750デフォルトの名無しさん:2005/07/06(水) 14:34:21
>>748
745に答えが書いてあるではないか。
751デフォルトの名無しさん:2005/07/06(水) 14:47:59
○| ̄|_ ̄|○ <スレッドとスレッドをかけているのは絶対に秘密!
752デフォルトの名無しさん:2005/07/06(水) 16:40:00
>>750
○| ̄|_ ̄|○ >>745はクラスをファーストクラスのオブジェクトのように語っておるが…
753デフォルトの名無しさん:2005/07/06(水) 16:42:48
A| ̄|_ ̄|A <彼はクラスとオブジェクトの区別がついていないのですね。
754デフォルトの名無しさん:2005/07/06(水) 16:56:32
B| ̄|_ ̄|Bすまん、ただこれが書きたかっただけなんだ
755デフォルトの名無しさん:2005/07/09(土) 02:56:04
C言語+Windows APIを使っているのですが、  
最大化やウィンドウのリサイズを禁止するにはどうすればいいんでしょうか?  
最小化はそのまま使えるようにしたいのですが…  

756デフォルトの名無しさん:2005/07/09(土) 06:21:53
自分でメッセージ処理すればおk
757デフォルトの名無しさん:2005/07/09(土) 09:11:27
B| ̄|_ ̄|B <つーか、何スレ違いに回答してんだよ。
758デフォルトの名無しさん:2005/07/10(日) 11:52:37
Linuxオンチなんで、ちと教えてくださいまし。

- Linuxでマルチスレッド・アプリケーションとなったとき、
  pthreadは'事実上の標準'もしくは'アッタリマエ'か?

- pthradはLinuxの一部ではないが、たいていのディストリビューション
  には添付されている。という認識で正しいか?

- スレッド起こすのにはcloneとかいうsystem-callがあるが、
  こいつはコンテキストの切り替えにプロセスと同じことやる
  ので決して速くはない。は真か?
759デフォルトの名無しさん:2005/07/10(日) 12:06:00
上2つは「どのlinuxでも動くようにしたい」ということか?
最後のはよくわからんが普通にスレッド起こすのは十分速いよ。
760デフォルトの名無しさん:2005/07/10(日) 12:06:16
- 当たり前かつ標準

- pthradは一部でも添付されてもいないが、pthreadは標準

- clone(2)はpthread_create(3)を実現するためのシステムコール。
  あんたが使う類いのものじゃない。
761デフォルトの名無しさん:2005/07/10(日) 13:53:41
>>758
pthreadってのは単なるAPIのこと。
ttp://www.opengroup.org/onlinepubs/009695399/basedefs/pthread.h.html
で、UNIX系のOS上でC言語によるマルチスレッド・アプリケーションを記述するのなら、
pthread APIを使うのが「事実上の標準」。
ただし、pthread APIにはオプション的な扱いの関数などがあり、
これらは実装によっては使えないことがある。

Linux上で動作するpthread APIの実装としては、
- LinuxThreads … glibcに取り込まれたため、事実上の標準。
- Native POSIX Threading Library (NPTL) … LinuxThreadsの後継。これもglibcに取り込まれた。
- Next Generation POSIX Threading (NGPT) … NPTLの対抗馬だったが、あぼ〜ん
などがある。
ほとんどLinuxディストリビューションでは、LinuxThreadsかNPTLが使えるはず。

clone(2)ってのは、LinuxThreads、NPTLなどが内部で使ってるシステムコールであり、
アプリケーションプログラマが直接触るものではない。
762デフォルトの名無しさん:2005/07/10(日) 18:24:17
NPTLもclone(2)使ってるんだ。。。
763デフォルトの名無しさん:2005/07/12(火) 23:40:36
Win32でとある入出力デバイスをバッファ管理しながら
操作するライブラリ書いてるんだけど、
こういった場合スレッドセーフにするにはどこまでやるべき?
バッファやデバイス設定値を読み書きする所全て排他?
それともTLSでスレッド個別にメモリ確保のみ?

TLSだと複数スレッドから同一デバイスに対して
操作するときどうなるかわからんけどこれで許してもらえるかな?
仕様には特に明記されていないので、
俺様ルールでいいのかなとも思うんですが、
やっぱり普通はスレッドセーフにしないと駄目ですよね。
764デフォルトの名無しさん:2005/07/13(水) 01:38:08
デバイスへのリクエストが同期式の場合、
(つまりリクエスト呼び出し復帰時に結果が返る)
排他が必要な場合が結構ある。


765デフォルトの名無しさん:2005/07/13(水) 02:08:13
>>763
どこまでやるべきかは、前提とすべきスレッディングモデルの定義による。
話はそれからだ。
766デフォルトの名無しさん:2005/07/14(木) 01:15:07
どうしてこれは途中でデッドロックしてしまうんでしょう?
printfなどをmutexでロックしても同じでした。
初歩的なことかもしれませんが、よろしくお願いします。
#include <stdio.h>
#include <pthread.h>
void *ThreadFunc(void *pdata)
{
int i;

for (i = 0; i < 10; i++) {
printf("%c", *(char *)pdata);
}
return NULL;
}
int main(void)
{
int i;
pthread_t pthId;
char a[10];

for (i=0;i<10;i++) {
a[i] = i + '0';
pthread_create(&pthId, NULL, ThreadFunc, (void *)&a[i]);
}
for (;;) {
;
}
return 0;
}
767デフォルトの名無しさん:2005/07/14(木) 01:25:25
fflush(stdout);

とかいうオチじゃないだろうな
768766:2005/07/14(木) 02:21:27
>>767
ありがとうございます。
やってみたのですが、バッファリングの問題ではないようです。

書き忘れましたが、どうやらスレッドが終了(return)するとロックするようなのです。
ネットにあるような単一スレッドのサンプルは問題なく動いています。
_beginthreadを使った場合はこのようなことは起こりません。
なんでだろう・・・。
769デフォルトの名無しさん:2005/07/14(木) 07:16:20
>>768
何でpthIdは1個?
770デフォルトの名無しさん:2005/07/14(木) 07:22:43
joimしてない?
771デフォルトの名無しさん:2005/07/14(木) 07:29:36
>_beginthreadを使った場合はこのようなことは起こりません。
つまりCreateThread使ってるってこと?
Cランタイムライブラリを使う場合は_beginthreadを使う必要があると思うんだけど
772デフォルトの名無しさん:2005/07/14(木) 08:11:24
てゆうか
for (;;) {
;
}
ってなんだよ。
MSDOSならともかく、今時のOSで許されるコーディングじゃないぜ。
773766:2005/07/14(木) 08:37:48
>>759
返り値のIDを使わないからです。
配列にして個々にIDを入れても固まってしまいます。

>>770
メインスレッド側はjoinが必須なんでしょうか?
一応joinしてみたのですが、やはり固まります。

>>771
process.hの_beginthreadを使っています。

先ほど>>770さんに指摘されたjoinなどについて調べて、
結果的にはdetachを使用することでテストケースの場合はロックすることはなくなりました。
が、本件の方はdetachしてもロックしてしまいます。
もう少し調べてみます。
774デフォルトの名無しさん:2005/07/14(木) 10:30:59
joinしてもダメだったコードをさらせ。
775デフォルトの名無しさん:2005/07/14(木) 11:31:53
for (i = 0; i < 10; i++) {
printf("%c", *(char *)pdata);
}
fflush(stdout); <-- これ付け足したら動く予感
776デフォルトの名無しさん:2005/07/14(木) 11:51:49
>>768
> > 書き忘れましたが、どうやらスレッドが終了(return)するとロックするようなのです。

お前の言いたいのは、
・出力されません
に過ぎないのと違うのかと…

「ロック」言いたいだけと違うんかと…
777デフォルトの名無しさん:2005/07/15(金) 00:34:30
forでビジーループしちゃいかんだろ、スレッドで。

for( ; ; ) {{
  sched_yield();
}

ってして他のスレッドを動かすのが基本。

○| ̄|_ ̄|○
778デフォルトの名無しさん:2005/07/15(金) 00:48:27
>>777
> ○| ̄|_ ̄|○

○| ̄|_ ̄|○ <お前が喋れよ。登場するだけかよ!
779デフォルトの名無しさん:2005/07/15(金) 00:53:50
>>777
おいおい、それもビジーループなんだよ。
待ってるだけなら pthread_join() を使うのが基本中の基本。
大丈夫かホントに。
780766:2005/07/15(金) 01:36:12
>>776
ロックと書いたのは固まったプロセスを強制終了するのに数秒かかるからです。

先に書いた通り、ロックは防げましたし、その原因も分かりました(join、detachしてなかった)。
しかしまだ怪しい部分があります。
joinしても期待した動作という意味では「ダメ」なのでソース曝します。
ttp://kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/img/723.c
実行毎に表示される数字の個数が違いますし、最後のEndも表示されません。
joinの使い方は間違ってないと思うのですが・・・。
環境がNT4sp6、デュアルプロセッサです。
781デフォルトの名無しさん:2005/07/15(金) 02:05:19
NTでpthread、がとりあえず不思議。
782デフォルトの名無しさん:2005/07/15(金) 02:37:34
NetBSD でやったら "End" まで出たよ。
>>781 と同感なんだがどうやってるの?
cygwin?
783デフォルトの名無しさん:2005/07/15(金) 04:47:19
Linux 2.6も問題なし。
784デフォルトの名無しさん:2005/07/15(金) 09:16:06
>>766
○| ̄|_ ̄|○ <Win2kのcygwinで実行したところ一瞬で終了して以下が表示された。

01021304215360742819536074281953607428195360742819536074281953607428195360742819
53674289536748956789End
785766:2005/07/15(金) 09:35:41
仰る通り、Cygwinです。
マズイな、こりゃOSを疑うべきなのか。
それが分かっただけでも収穫です、どうもありがとうございました。
786デフォルトの名無しさん:2005/07/15(金) 10:04:31
OSつーかCygwinの問題だろう。
Cygwinは「UNIXと同じソースで動いたらラッキー」ぐらいのものだと思っ
といたほうがいい。
787デフォルトの名無しさん:2005/07/15(金) 11:08:06
いやそうなんだが、まさかこういう基本的なところでダメだとは驚いた。
コンパイルできないのはOKだが、誤動作は勘弁してほしいな。

Windows 使う場合は Windows の native thread を使えってことか。
まあ、API は pthread とそんなに違わないから (というか、たぶん
両方とも Mach の cthread の真似だよね、きっと)、wrapper ライブ
ラリ書いて pthread と Windows のどちらでも動くプログラムにする
のは難しくないよ。
788デフォルトの名無しさん:2005/07/15(金) 11:20:12
つうかNTはもうよせ、と
789デフォルトの名無しさん:2005/07/15(金) 11:24:35
cygwin、>>784で動いているやん。
つうかstdoutの排他は?
790デフォルトの名無しさん:2005/07/15(金) 11:33:14
791デフォルトの名無しさん:2005/07/16(土) 02:25:17
>>784で正しく動作しているように見えるけど何が問題なの?
792デフォルトの名無しさん:2005/07/16(土) 02:39:39
Win2kでは動くけど「NT4sp6、デュアルプロセッサ」では動かないということでわ?
793デフォルトの名無しさん:2005/07/17(日) 09:25:35
というかstdout排他してないし…
こんなのはたまたま動いているだけのプログラム。
794デフォルトの名無しさん:2005/07/17(日) 09:26:17
OSを疑うとか片腹痛い。
795デフォルトの名無しさん:2005/07/17(日) 10:26:30
>>780のコードは回りくどい方法だけど一応stdoutを排他制御してますやん。
796デフォルトの名無しさん:2005/07/18(月) 14:29:49
OSを疑うのはどうかと思うが。
cygwinを疑うのは正しい姿勢の予感。
797デフォルトの名無しさん:2005/07/18(月) 14:33:37
cygwinはイロイロやってそうだしなぁ
798デフォルトの名無しさん:2005/07/18(月) 16:54:17
>環境がNT4sp6、デュアルプロセッサです。
ってのに妙に引っかかるな。

デュアルプロセッサで、デュアルプロセッサカーネル使っていないとか
実は、cygwinはデュアルプロセッサに対応していない。とか
799デフォルトの名無しさん:2005/07/18(月) 20:53:37
> cygwinはデュアルプロセッサに対応していない

さすがにそりゃねーべ
今NTで十分テストされているとはあんまり思えないんだが、そのへんかな
800デフォルトの名無しさん:2005/07/18(月) 21:27:03
>>784だが、
うちのWinマシンはデュアルではないけどHTです。
OSからはCPU2個に見えてる状態。
801デフォルトの名無しさん:2005/07/18(月) 21:43:08
cygwinて、glibc?
なんかstdioの排他とかゆってる人いるけど、
glibcのstdioって、スレッドセーフじゃないの?
802デフォルトの名無しさん:2005/07/18(月) 21:57:01
>801
glibc じゃなくて newlib のはず。
803デフォルトの名無しさん:2005/07/18(月) 23:35:30
newlibはデュアルに対応していないというのが俺の評価。
スピンロックによる排他制御のために
x86のxchg命令によるatomicなtest&setを使っているが
これがlockプリフィックスつきでないからね。

newlib/libc/sys/linux/linuxthreads/machine/i386/pt-machine.h
のlong int testandset(int *spinlock)を見よ。

cygwinがnewlibのlinuxthreadをつかって
pthreadを実現していたらだめだろう。
これがx86 linuxというconfigureでのみ使われているんなら
関係ないんだろうけど。
それとは別にcygwinにはpthreadの実装があるから関係無いとは思うが。
正直その辺りの関係は俺もわからん。
804デフォルトの名無しさん:2005/07/19(火) 00:30:16
/* Spinlock implementation; required. */
PT_EI long int
testandset (int *spinlock)
{
 long int ret;

 __asm__ __volatile__(
   "xchgl %0, %1"
   : "=r"(ret), "=m"(*spinlock)
   : "0"(1), "m"(*spinlock)
   : "memory");

 return ret;
}


○| ̄|_ ̄|○ <ダメじゃん。 >>newlib
805デフォルトの名無しさん:2005/07/19(火) 00:48:32
あれ?xchgはLOCKプレフィクスなしでもメモリ相手ならロックかますと記憶してたが。。。
806803:2005/07/19(火) 01:04:02
ftp://download.intel.com/design/Pentium4/manuals/25366616.pdf

The XCHG instruction always asserts the LOCK# signal regardless of
the presence or absence of the LOCK prefix.

逝って来ます。
807デフォルトの名無しさん:2005/07/24(日) 21:50:22
【初心者歓迎】C/C++室 Ver.20【環境依存OK】
http://pc8.2ch.net/test/read.cgi/tech/1121644782/62
にて質問しましたがこちらのスレッドのほうが適切だと思いますのでこちらで質問させてください。

今gcc3.3.3にてスレッドを利用したプログラムを作成しようとしています。
5回程度のスレッド生成はうまくいきますが
Segmentation fault (core dumped)
が表示されてエラー終了してしまいます。
原因が分かりません。
どこがエラーの原因か指摘していただけませんか?
ソースは以下の通りです。

void *thread_test(void *tmp)
{
struct testarg baa;
//終了時にリソース割り当てを解放
pthread_detach(pthread_self());
baa.id = ((struct testarg *)tmp)->id;
baa.cmd = ((struct testarg *)tmp)->cmd;
free((struct testarg *)tmp);
printf("++++++++++++++++++++++++++++++++++++++++\n");
switch (baa.cmd){
case 1:printf("good morning\n");break;
case 2:printf("hello world\n");break;
case 3:printf("good bye\n");break;
default:printf("oh no!\n");break;
}
printf("++++++++++++++++++++++++++++++++++++++++\n");
return (NULL);
}
808807続き:2005/07/24(日) 21:51:42
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>

struct testarg{
int cmd;
int id;
};

void *thread_test(void *);

int main(void)
{
struct testarg *foo;char ss[80], *p, *pp;pthread_t threadID;int i = 0, j = 0;
for(;;){
j++;
printf("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n");
printf("%d回目\n", j);
//メモリ確保
if((foo = (struct testarg *)malloc(sizeof(struct testarg))) == NULL){
puts("malloc() error");
exit(1);
}
809807続きの続き:2005/07/24(日) 21:52:33
//自動操作

i %= 3;sleep(3);
foo->id = i;foo->cmd = i;i++;
//デバッグ用
printf("foo\nid = %d\ncmd = %d\n", foo->id, foo->cmd);
if(foo->id == -1)
break;

//クライアントスレッドを生成
if(pthread_create(&threadID, NULL, thread_test, (void *)foo) != 0){
puts("pthread_create() error");
exit(1);
}

printf("with thread %ld\n", (long int) threadID);
if(i==100)
break;
}
puts("good end");
return 0;
}
810デフォルトの名無しさん:2005/07/24(日) 22:32:54
>>807
うちでは落ちないでいつまでも動き続ける。
gcc は 3.3.5。
811デフォルトの名無しさん:2005/07/24(日) 22:43:48
pthread_detachをメイン側でやれば落ちないみたい
812807:2005/07/24(日) 23:12:26
mainでpthread_create()の後にpthread_detach()を挿入し、
thread_test()の中のpthead_detach()を削除することで解決しました。

>811さんありがとうございます。
すいませんが、一つ疑問があります。
pthread_create()の引数が取ってきたpthread_t型の変数で正しい値ならば
pthread_detach()はいつでもどこの関数でやってもいいんでしょうか?

>810さんありがとうございます。
いまバージョンアップ中です。
gcc 3.3.5にしたらどうなるかも報告したいと思います。

あと、一応私が書いたソースにはバグはなく、
Segmentation fault (core dumped) で落ちてしまうのは
gcc ver 3.3.3のせいだと考えてよいのでしょうか?
813デフォルトの名無しさん:2005/07/24(日) 23:40:18
落ちるのは gcc というより pthread の実装の違いかも。
814807:2005/07/25(月) 20:32:29
struct testarg{
int cmd;
int id;
pthread_t threadID;
};

として、
if(pthread_create(&foo->threadID, NULL, thread_test, (void *)foo) != 0){
・・・
}

void *thread_test(void *tmp)
{
struct testarg baa;
//終了時にリソース割り当てを解放
pthread_detach(((struct testarg *)tmp)->threadID);
・・・・・・
}
としたら問題が解決しました。

pthread_self()の問題だと思いますが、
原因はよくわかりませんでした。

失礼しました。
815デフォルトの名無しさん:2005/07/26(火) 00:33:54
pthreadを使ったマルチスレッドプログラムで、
あるスレッドがfcntlでファイルをロックしているとき、
同じプロセスの別のスレッドが同様にロックをしようとすると、
ロックが取得できてしまうんですか?
816デフォルトの名無しさん:2005/07/26(火) 01:31:45
>>815
fcntlはロックの所有権がプロセス単位だから。
817デフォルトの名無しさん:2005/07/29(金) 22:40:15
age
818デフォルトの名無しさん:2005/07/29(金) 23:05:36
マルチスレッドセーフとは
1.スレッドの中でスレッドを作成した場合にいうのでしょうか
2.一つのプロセスで複数のスレッドを作成した場合にいうのでしょうか。
それとも両方マルチスレッドセーフというのですか?
819デフォルトの名無しさん:2005/07/29(金) 23:07:35
1と2をどう区別していいのか教えてくれ。
820デフォルトの名無しさん:2005/07/29(金) 23:08:54
スレッドセーフの意味わかってるのか?
821デフォルトの名無しさん:2005/07/29(金) 23:34:22
1.
pthread_create(&threadID0, NULL, func0, (void *)foo);
pthread_create(&threadID1, NULL, func1, (void *)fooo);
func0()が実行されている間にメインスレッドにて新しく他のスレッドが作成される。

2.
void *func0(void *arg)
{
pthread_t theadID2;
pthead_create(&threadID2, NULL, function, (void *)arg);
}
メインスレッドから呼び出されたfunc0()の中で別のスレッドを作った。

こういうのを考えて818を書きました。
822デフォルトの名無しさん:2005/07/29(金) 23:41:49
>>821 お前にはマルチスレッドは無理。
823デフォルトの名無しさん:2005/07/29(金) 23:42:02
>>821 お前にはマルチスレッドは無理。
824デフォルトの名無しさん:2005/07/29(金) 23:42:02
>>821 お前にはマルチスレッドは無理。
825デフォルトの名無しさん:2005/07/29(金) 23:45:44
  ,j;;;;;j,. ---一、 `  ―--‐、_ l;;;;;;   
 {;;;;;;ゝ T辷iフ i    f'辷jァ  !i;;;;;  >>821 お前にはマルチスレッドは無理。
  ヾ;;;ハ    ノ       .::!lリ;;r゙      
   `Z;i   〈.,_..,.      ノ;;;;;;;;> 
   ,;ぇハ、 、_,.ー-、_',.    ,f゙: Y;;f   そんなふうにかんがえていた時期が
   ~''戈ヽ   `二´    r'´:::. `!     俺にもありました
826821:2005/07/29(金) 23:55:01
  ,j;;;;;j,. ---一、 `  ―--‐、_ l;;;;;;   
 {;;;;;;ゝ T辷iフ i    f'辷jァ  !i;;;;;  2chネラは真面目な人が多い
  ヾ;;;ハ    ノ       .::!lリ;;r゙      人を馬鹿にするようなことはないだろう
   `Z;i   〈.,_..,.      ノ;;;;;;;;> 
   ,;ぇハ、 、_,.ー-、_',.    ,f゙: Y;;f   そんなふうにかんがえていた時期が
   ~''戈ヽ   `二´    r'´:::. `!     俺にもありました
827デフォルトの名無しさん:2005/07/29(金) 23:59:51
>>821 お前には2ちゃんは無理。
828デフォルトの名無しさん:2005/07/30(土) 00:12:37
>181わぁ、書き方を間違えただけであって、正確にはだな、
マルチスレッドセーフを冒すのは、
1.〜
2.〜
それとも両方マルチスレッドセーフを冒すのでしょうか?
だと、思うのは俺だけか?
俺は、1.2.ともその可能性をはらんでいると思う
お互いを蝕むのを避けるために、踏切りの警報灯のように交互にチカチカ同期採る手法や
片方をlockさせる手法があるのでしょう
>181は気にすることはない
リアルで溜まったウサを晴らしたいヤシが吐き捨ててる場合もあるんだから
そういう肥溜めはシカトしときゃいい
829デフォルトの名無しさん:2005/07/30(土) 00:20:28
∋oノハヽo∈
  ( ´D`) 誤爆れすか?
830デフォルトの名無しさん:2005/07/30(土) 00:25:35
>>828は天然でつか?
831デフォルトの名無しさん:2005/07/30(土) 00:36:13
@| ̄|_ ̄|@ <ある関数が、複数のスレッドから同時に実行されてもハラハラしない時、

A| ̄|_ ̄|A <その関数はスレッドセーフである、とかなんとか言われるのである。

B| ̄|_ ̄|B <きっとね!
832デフォルトの名無しさん:2005/07/30(土) 01:04:39
>踏切りの警報灯のように交互にチカチカ同期採る手法

は、誤解招くから、補足しとくと、
お互いがどこまで進んだか分からないと、迂闊にお互いのデータを使えないから、同期を採って、進行度を相互確認する

それと、親プロセス、子プロセスの関係の、マルチプロセス、要はforkというのもあるけど(知っているかもしれないけど)、
これの弱点は、同じOSのshell上で動くから、処理が重くなる。だから、マルチスレッドが推奨されてるわけだけど、
利点もあって、親が終了しても、子は動き続けられる
833デフォルトの名無しさん:2005/07/30(土) 01:08:52
○| ̄|_ ̄|○ <いいからもう寝ろ
834デフォルトの名無しさん:2005/07/30(土) 11:27:37
835デフォルトの名無しさん:2005/07/30(土) 17:56:41
なんで、そんなにうなぎ連結してんの? キモイよ?
836デフォルトの名無しさん:2005/07/30(土) 20:52:17
一つだと、四つん這いと間違えるから。
837デフォルトの名無しさん:2005/07/31(日) 00:13:53
pThreadでロックをある所有が行い別のやつがアンロックを行うって方法を
使っているのですが、とても微妙な使用方法だと思うのですが改善する方法ないですか?
あとpthreadのデバッグってどうしてますか?
838デフォルトの名無しさん:2005/07/31(日) 06:37:15
>>837
君の頭を改善。
デバッガ。
839デフォルトの名無しさん:2005/08/01(月) 00:16:55
> 一つだと、四つん這いと間違えるから。

わらた
840デフォルトの名無しさん:2005/08/02(火) 20:41:39
誘導されてきました。
C言語でマルチスレッドプログラミングについて教えてもらいたいです。
問題は、
(1)簡単なスレッドプログラミング及びスレッドの動作について解説せよ。
(2)相互封鎖や相互実行が起こるプログラムを作成し、その動作を解説せよ。
(3)マルチスレッドで、turnやflagを使った排他制御のプログラムを作成し、その動作を解説せよ。
(4)消費者・生産者問題のプログラムを解説せよ。

です。宜しくお願いします。
841デフォルトの名無しさん:2005/08/02(火) 20:44:01
>>840
スレ違いです。
↓あたりへどうぞ。

内藤ホライゾンがC/C++の宿題を片付けます 49
http://pc8.2ch.net/test/read.cgi/tech/1122705615/

ぼるじょあがC/C++の宿題を片づけますYO! 48代目
http://pc8.2ch.net/test/read.cgi/tech/1121471445/
842デフォルトの名無しさん:2005/08/03(水) 02:12:13
見事な教えてクンぶりに感動すら覚えた。
誘導先でも煙たがられてるし...
843デフォルトの名無しさん:2005/08/04(木) 21:05:37
グローバル変数や静的変数をスレッドごとに持たせることって可能ですか?
変数をロックして共有するのではなく、メンバ変数みたいな感じで状態管理に使いたいんです。
errornoとかはそうなっているみたいなんですけど。
844デフォルトの名無しさん:2005/08/04(木) 21:35:41
>>543
TLS

ちと調べればすぐわかりそうな気がするが。
845デフォルトの名無しさん:2005/08/04(木) 21:38:29
単純にぐぐるとネットワーク関連の方がひっかかるので補足しておくと、Thread Local Storage な。
846デフォルトの名無しさん:2005/08/04(木) 21:50:33
>>843
"Thread Specific Data" とか "Thread Local Storage" と呼ばれるものだな。

普通はスレッドライブラリのAPIとして用意されているものだし、
最近のC/C++標準では __thread というキーワードで言語仕様にも採り入れられている。

ttp://gcc.gnu.org/onlinedocs/gcc/Thread_002dLocal.html
ttp://www.linux.or.jp/JM/html/glibc-linuxthreads/man3/pthread_key_create.3.html
ttp://www.microsoft.com/japan/msdn/library/ja/vccore/html/_core_Thread_Local_Storage_.28.TLS.29.asp
847デフォルトの名無しさん:2005/08/05(金) 00:11:19
C++で組んでたときはあんまり意識せずに書けたな。メンバ変数はデフォルトではインスタンスローカルだから
Cでも単純にスレッドごとに構造体のインスタンス別々にしてやればいいジャンとか思うの俺だけ?
848デフォルトの名無しさん:2005/08/05(金) 02:02:30
まあポインタで引っ張り回したら何だって出来るんだけど、
スレッド内関数呼び出しのそのレベルでも、
スレッドローカルな大域変数のように扱えるのが、
スレッドローカルストレージフレームワークだから…

Common Lispの*special*変数も似た風に使えるけど、
あれよりはコストが安い。
849デフォルトの名無しさん:2005/08/05(金) 03:02:18
( ´∀`) 気のせいダロ
850デフォルトの名無しさん:2005/08/05(金) 23:56:31
>846
>最近のC/C++標準では __thread というキーワードで言語仕様にも採り入れられている。
9899:1999 でも 14882:2003 でもそんなキーワードは引っかからないぞ。
つーか、__ で始まってる時点で処理系依存の拡張じゃないのか?
851デフォルトの名無しさん:2005/08/06(土) 08:55:10
>>846は、gccのドキュメントの以下の部分を誤読しているんだろう?
C99を__threadで拡張するとすると標準文書はこう変更されるってことなんだけど。

>5.51.1 ISO/IEC 9899:1999 Edits for Thread-Local Storage
>
> The following are a set of changes to ISO/IEC 9899:1999 (aka C99) that
> document the exact semantics of the language extension.

852846:2005/08/06(土) 19:43:25
>>850-851
うん、俺の勘違いだった
スマソ
853デフォルトの名無しさん:2005/08/06(土) 19:47:34
gccの__threadってなんなの?

int pthread_key_create(pthread_key_t *key, void (*destr_function) (void*));
int pthread_key_delete(pthread_key_t key);
int pthread_setspecific(pthread_key_t key, const void *pointer);
void * pthread_getspecific(pthread_key_t key);

のsyntax sugar?
854デフォルトの名無しさん:2005/08/06(土) 19:51:04
スレッドプロシージャをクラス内に実装する裏技(といっても常套手段)使えば
大域変数みたいに使うことはできる。
てかCreateThreadに渡すダミーのスレッドプロシージャにthisポインタ渡してメンバ関数を起動するだけだから。
(Win32での話)
855デフォルトの名無しさん:2005/08/06(土) 20:19:16
>>853
機能的には同じようなものだが、普通は__threadのほうが遥かに高速に動作する。

ttp://people.redhat.com/drepper/tls.pdf
上記PDFにあるように、ローダやダイナミックリンカなどと連係して
間接参照数回程度のコストで動作するようになっている。

まあ、逆に言うと、スレッドライブラリだけでなく、
ローダやリンカも対応してないと__threadは使えないってことになるが。
856デフォルトの名無しさん:2005/08/07(日) 01:27:51
さんざん既出かもしれないけど、質問します。
windowsでpthreadの状態変数みたいなのはどう実現すればよいのでしょうか?
排他変数にMutexをつかうならSignalObjectAndWaitをつかえばよいんだけれども
CriticalSectionを使いたいんです。
857デフォルトの名無しさん:2005/08/07(日) 01:30:48
状態変数に近いのはイベントオブジェクトじゃない?
858デフォルトの名無しさん:2005/08/07(日) 09:09:08
状態遷移マシンの実装を語るスレがほしいな。
859デフォルトの名無しさん:2005/08/07(日) 13:02:32
>>858
○| ̄|_ ̄|○ <オマエ「状態遷移マシン」て言ってみたかっただけだろ!
860デフォルトの名無しさん:2005/08/07(日) 13:03:24
正規表現ライブラリのソースをみるとか
マルチスレッド関係ないな
861856:2005/08/07(日) 13:18:58
> 状態変数に近いのはイベントオブジェクトじゃない?
そうなんですけど、pthreadの場合、 状態変数をwaitするとき
mutexを渡して内部でアトミックにmutexをアンロック→シグナル待ち→mutexのロックをしてて
これをwindowsで実現できないかなと・・・
WindowsのばあいMutexをWait〜系関数で待つことは出来るけど、CriticalSectionは使えない。

たとえばpthreadで状態変数をつかっているようなところを
windowsに移植するときはどうしたらよいのかなと思いまして・・・
862856:2005/08/07(日) 13:20:21
> 状態変数に近いのはイベントオブジェクトじゃない?
そうなんですけど、pthreadの場合、 状態変数をwaitするとき
mutexを渡して内部でアトミックにmutexをアンロック→シグナル待ち→mutexのロックをしてて
これをwindowsで実現できないかなと・・・
WindowsのばあいMutexをWait〜系関数で待つことは出来るけど、CriticalSectionは使えない。

たとえばpthreadで状態変数をつかっているようなところを
windowsに移植するときはどうしたらよいのかなと思いまして・・・
863デフォルトの名無しさん:2005/08/07(日) 13:51:27
aprだと、EventとMutexを使ってcond_wait/signalをエミュレートしてるね。
もちろん、cond_waitに渡すmutexはCRITICAL_SECTIONで良くて、
Mutexを使っているのはWaitForで待つためらしい。
http://apr.apache.org/
864デフォルトの名無しさん:2005/08/07(日) 14:18:12
クラス内のメソッドを並列で実行したいのですが、やり方がわかりません。どこかに参考になるページはありませんか?
865856:2005/08/07(日) 14:46:06
>>863
ありがとうございます。参考になりました。
どうやらcondに渡すのはCRITICAL_SECTIONみたいだけど、
cond内部でMutexを持っていてそれを用いて排他制御を行いつつ、
CRITICAL_SECTIONアンロック→シグナル待ち→CRITICAL_SECTIONロックしているみたい。
(apr-1.1.1\locks\win32\thread_cond.c)
866デフォルトの名無しさん:2005/08/07(日) 15:33:00
>>859
ばれたか。
でもWindowsでWindowMessageを使って実装する例とか、
専用のクラスの実装例とか、どんな問題があってどんなメリットがあるとか
そういうことを勉強したかったのもあるよ。
867デフォルトの名無しさん:2005/08/08(月) 01:01:11
pthread_cond_signal/broadcastの実装には
シグナルとウエイトをアトミックにやる必要がある。
「アトミックに」ってところが重要で
シグナルしてウエイトするというようにバラバラやっていたのではダメ。

それをする手段は、Win32だと、SignalObjectAndWaitしか知らん。
868デフォルトの名無しさん:2005/08/08(月) 03:11:15
?
869デフォルトの名無しさん:2005/08/09(火) 16:17:47
mutex といえば、Boost.Thread の Win32 版 mutex の実装に、
CRITICAL_SECTION ではなくて、Mutex が利用されていたな。

Win32 の Mutex は遅いから、メータードセクションを利用して
実装して欲しかった。
870デフォルトの名無しさん:2005/08/09(火) 19:11:37
>>869
今1.32のソース見たけど、クリティカルセクション使ってたよ
871デフォルトの名無しさん:2005/08/09(火) 20:12:15
>>869
メータードセクションってこれ何時頃から実装されてるの?
MSDNみて、こんなの有ったのかと目から鱗状態なんだけど。
95でも使えるっぽいから、相当前からある様なんだけど。
872デフォルトの名無しさん:2005/08/09(火) 21:36:20
自己レス。
APIとしてSDKに実装されてるわけじゃないのね。
MSDN英に.hと.cのフルソース上がってたからもらってきた。
mutexと置き換えて遊んでみる。>>869ありがと。
873デフォルトの名無しさん:2005/08/10(水) 15:20:21
うろ覚えだが、メータードセクションは、ロックカウントを持っていないので、
クリティカルセクションのつもりでリソースを1にして、
同じスレッドで複数回 EnterMeteredSection すると、あとあと面倒だったかも。
874デフォルトの名無しさん:2005/08/16(火) 18:00:27
メータードセクションなんで初めて知ったよ
みなさんスゴイすね
875デフォルトの名無しさん:2005/08/21(日) 13:45:16
>>873
それなら自分でReentrantな実装にしちゃえば?
876デフォルトの名無しさん:2005/08/22(月) 16:00:40
メータードセクションのReentrantな実装に改良している最中に、
以前AdvancedWindowsのオプテックスを
セマフォ的にしたものを作ったのを思い出した。orz

とても不毛な月曜の午前。
877デフォルトの名無しさん:2005/08/26(金) 14:48:45
基本的な質問します。
stringとかのポインタをスレッドに渡し、スレッドより先にメインが終了してしまった場合、
そのstringはもう生きていないですよね。
こういうときはどうやって処理をすればいいのでしょうか?
878デフォルトの名無しさん:2005/08/26(金) 14:52:35
>>877
寿命管理ができないなら、実体で渡す。
実体渡しが嫌なら、サボらずにちゃんと寿命管理を行う。
879デフォルトの名無しさん:2005/08/26(金) 14:52:34
○| ̄|_ ̄|○ <メインが終了したらプロセス全体が終わるだろ
880デフォルトの名無しさん:2005/08/26(金) 15:11:45
がんがって実態渡ししてみます。
881デフォルトの名無しさん:2005/08/26(金) 15:44:49
メインが終了したらアプリ全体が終わっちゃうから、
スレッドでの処理が終わるまでメインを待たせろつーの。。
882デフォルトの名無しさん:2005/08/26(金) 22:18:12
○| ̄|_ ̄|○ < ああ、面倒くせーな!
883デフォルトの名無しさん:2005/08/28(日) 13:15:09
マルチスレッドアウトな関数multithreadout()があります。
この原因はグローバル変数glbを使っていることです。

通常、同一プロセス内でmultithreadout()を使うと駄目ですが、
multithreadout()をdllファイルにしてもマルチスレッドアウトのままでしょうか?
884デフォルトの名無しさん:2005/08/28(日) 14:06:11
>>883
Yes.
DLL(が読み込まれたメモリ空間) はプロセススコープの資源。
885デフォルトの名無しさん:2005/08/28(日) 14:07:04
はい
886デフォルトの名無しさん:2005/08/28(日) 14:30:37
解決する方法として
1).マルチプロセスにする。
2).multithreadout()だけをexeファイルにして引数を受け渡す(パイプを使う&dllを使用しない)
3).multithreadout()をdllファイルにし、multithreadout()呼び出し専用の
  exeファイルを作り、パイプを使う

2).3).の違いはmultithreadout()が静的か動的かなのですが、
他に解決する方法はありますか?間違った解決方法を考えていませんか?

また、処理のほとんど(90%以上)はmultithreadout()が行います。
呼び出し回数は数回程度です。
887デフォルトの名無しさん:2005/08/28(日) 14:40:34
グローバル変数を使わないように、multithreadout()を変更する
と言う選択肢もあるはず
888デフォルトの名無しさん:2005/08/28(日) 14:42:41
multithreadout() を multithreadout_real()
か何かにリネームして、
multithreadout()は、
multithreadout()
{
static CriticalSectionとかMutexとか lock;
Lock(lock);
multithreadout_real();
Unlock(lock);
}
あたりにすればいいんじゃないかと思う。
例外処理とか、lockの初期化は適当に。
889856:2005/08/28(日) 17:35:49
以前紹介してもらったaprのミューテックスなんだけど、よく見ると怪しい部分があるような気がしてきた。
broadcastのときwaitしているスレッドを数えるためにカウントしているんだけど、
イベント待ちの直後そのカウンタをインクリメントする必要があって、その部分がクリチカルになっていない。
どうなんだろう?自分は怖いんでカウンタをCRITICAL_SECTIONで囲んだけれども。
890856:2005/08/28(日) 17:46:49
あう、mutexじゃなくてconditionだった。スマソ
891デフォルトの名無しさん:2005/08/30(火) 06:42:29
signalとかbroadcast待ってる香具師ってスピンしてんの?
古いイベントで使うようなselectとかとどっちが速い?
892デフォルトの名無しさん:2005/08/30(火) 06:44:41
×古いイベント
○古いイベント志向

すまそ。
893デフォルトの名無しさん:2005/09/01(木) 23:51:20
selectって古いイベント志向といういいかたするのか?
ま、それはさておき、遅いか早いかは

実装による。

以上だ!
894デフォルトの名無しさん:2005/09/01(木) 23:51:28
selectって古いイベント志向といういいかたするのか?
ま、それはさておき、遅いか早いかは

実装による。

以上だ!
895デフォルトの名無しさん:2005/09/02(金) 00:20:22
>>893-894
ちゃんと排他制御しろよ
896デフォルトの名無しさん:2005/09/02(金) 00:41:56
この読みが外れればそれを口実に日本に戦争を仕掛けるつもりだったのか
897デフォルトの名無しさん:2005/09/02(金) 00:43:20

誤爆しました。メンゴ
898デフォルトの名無しさん:2005/09/02(金) 03:07:40
>>893-894
イベントとか割り込みって、中でselect使ってんじゃね?
899デフォルトの名無しさん:2005/09/04(日) 08:45:05
Solarisだと、select(3C)はpoll(2)を使ってる
900デフォルトの名無しさん:2005/09/04(日) 13:10:28
>>899
それは昔の話で、select(3)の実装がpoll(2)を使わないように2,3年前に変わらなかったっけ?
901デフォルトの名無しさん:2005/09/04(日) 18:49:22
そんな重要そうな事もはっきりしないのがUNIX文化ってやつですね
902デフォルトの名無しさん:2005/09/04(日) 19:39:03
selectもpollも対して変わらんよ。じゃあ
「イベントとか割り込みって、中でpoll使ってんじゃね?」
と言えばいい?
903デフォルトの名無しさん:2005/09/04(日) 21:32:12
ちゃんとCPU返してくれればどうでもいい。

たまにビジーループぶん回すのがいるからのう…

904891:2005/09/05(月) 00:08:39
>>903
えっと、まさにそこを聞きたかったんすけど。

ループしてるか見分ける方法ってある?
905デフォルトの名無しさん:2005/09/05(月) 10:46:59
>>898
んなわけねー(w

>>904
お前以外にループする奴はいない。in お前のプログラム&カーネル。
906891:2005/09/05(月) 23:58:31
何言ってるのかわかんないんだけど。
907デフォルトの名無しさん:2005/09/06(火) 14:49:26
>>899
windowsはどうなんですか?
908899:2005/09/06(火) 21:37:49
Windowsは詳しくないから分からない

というか、こんなの聞いてどうなるものでもないような
909デフォルトの名無しさん:2005/09/06(火) 22:23:37
>>891
> signalとかbroadcast待ってる香具師ってスピンしてんの?

ロックが競合したときにmutexの入口でスピンすることはあっても、
signalとかbroadcastを待ってる状態(つまり条件変数をwaitしている状態)で
スピンし続けてCPUを離さないってことはありえない。
そんな実装があったら、条件変数の意味が無くなるだろ。
910デフォルトの名無しさん:2005/09/06(火) 22:44:19
スピンとポーリングって何が違うの?
911デフォルトの名無しさん:2005/09/06(火) 22:54:37
スピン = 無期限連続ポーリング
912デフォルトの名無しさん:2005/09/06(火) 23:21:03
>>910
spinってのはSMPで一つのCPUだけがポーリング対象の資源を
得ることが出来るようなポーリングの仕方のことを言う。

皆がアクセスできる皿と、自分の手元の皿を夫々がくるくる入れ替えて
手元に来た皿に肉が乗ってたら食べていい、みたいな感じ。
913デフォルトの名無しさん:2005/09/07(水) 03:41:53
>>912
一面的な説明で「仕方のことを言う」はいかがなものか。
914デフォルトの名無しさん:2005/09/07(水) 03:55:32
>>913
文句だけじゃなくて、一面だけというのなら別の面からとか
包括的な説明とか、内容あるレスつけようぜ。
915デフォルトの名無しさん:2005/09/07(水) 07:23:03
スピンしないポーリングって可能なのか。
スレッドとかシグナルってハードレベルでどうなってるのか
わからなくて効率が全然読めないんだが、
その辺をユーザーレベルで理解できる本、サイトない?
916デフォルトの名無しさん:2005/09/07(水) 09:07:10
WindowsならAdvancedWindowsという本かな。
これ読むとWindowsでポーリング待ちなんて馬鹿げてると思うはず。
917デフォルトの名無しさん:2005/09/07(水) 09:13:54
>>916
Windowsよく知らないので、詳しく!
918デフォルトの名無しさん:2005/09/07(水) 09:14:46
最前線UNIXのカーネル
http://www.amazon.co.jp/exec/obidos/ASIN/4894711893/
Solarisインターナル−カーネル構造のすべて
http://www.amazon.co.jp/exec/obidos/ASIN/4894714582/

この辺りの本が詳しいけどね。どのOSでも基本は同じだし。
この辺りが難しいようなら、

OSの基礎と応用−設計から実装、DOSから分散OS Amoebaまで
http://www.amazon.co.jp/exec/obidos/tg/detail/-/books/4894712067/

なんかが定番になっているけれど、同期関係は記述が少ないし、
そもそもこの本は全般的におおざっぱな解説に終始するな。
919デフォルトの名無しさん:2005/09/07(水) 09:53:00
詳しく!
920デフォルトの名無しさん:2005/09/07(水) 09:54:38
分散OS ”あ萌え場”って何でしょうか?
921デフォルトの名無しさん:2005/09/07(水) 12:05:28
>>917
「Advanced Windows」嫁
あとは「Win32 マルチスレッドプログラミング」
つーかこの話で本が1冊出来るかもよ
922デフォルトの名無しさん:2005/09/07(水) 12:58:32
>>915
非SMPではspin lockなど使わずにタダのループによるポーリングで十分
(カーネルモードで、割り込みを考慮しないとして)。

また、競合するスレッド/プロセスがいない場合には、SMPだろうが割り込みが
あろうが単純ループのポーリングで十分。

効率的な点については、spin lock の一サイクルはメモリ<->レジスタ間の
値の入れ替えで完了するので、行儀良く短いクリティカルセクションから
なるコードの場合は(並列度にもよるけど)、わざわざスケジューラをいじって
スレッドをシグナル待ちにするような処理よりも単にspin lockの方が効率が良い。
923デフォルトの名無しさん:2005/09/07(水) 13:14:22
>>922
> (カーネルモードで、割り込みを考慮しないとして)。
> また、競合するスレッド/プロセスがいない場合には、

殆んどあり得ない仮定を置いて、何を言っているんだが…
924デフォルトの名無しさん:2005/09/07(水) 13:30:57
>>923
バカ?スピンロックについての話なら、普通割り込みも競合もあるけど、

915は「スピンしないポーリングって可能なのか。」って聞いてるわけで、
単に「ポーリング」って言った場合には>>922の条件は良く有ることだと
思うけど。
925デフォルトの名無しさん:2005/09/07(水) 14:06:08
ポーリング儲は糞プロセス量産してんだろうね
926デフォルトの名無しさん:2005/09/07(水) 14:22:09
ものすごい短時間しか待たないことがわかってるなら、ポーリングの方が効率いいこともあるべ。
927デフォルトの名無しさん:2005/09/07(水) 14:33:01
>>915
同期無しでただ読むだけで済むように設計すればいい
928デフォルトの名無しさん:2005/09/07(水) 16:24:15
>>921
Windowz使ってないので、「Advanced Windows」読んでも意味ないし
929デフォルトの名無しさん:2005/09/07(水) 18:41:22
MINIX使ってないので、「オペレーティングシステム―設計と理論およびMINIXによる実装」読んでも意味ないし
930デフォルトの名無しさん:2005/09/07(水) 19:13:46
はあ。
Windowsは業界スタンダードだから意味あるはずだけどねえ
931デフォルトの名無しさん:2005/09/07(水) 20:05:26
何業界だ?
932デフォルトの名無しさん:2005/09/07(水) 20:08:36
Window業界でのはなしでしょう
933デフォルトの名無しさん:2005/09/07(水) 22:20:40
windowsのイベントや、UNIXのsignalは、プログラマからみれば
APIとしてはコードのその場所でじっとwaitしてる形になると思うけど
イベントやsignal自体の内部実装(カーネル側?)
では結局はポーリングで実現されてたりするわけ?
934デフォルトの名無しさん:2005/09/07(水) 22:24:37
エロゲー的にはポーリングが正義、というFAが出ておりますが何か?
935デフォルトの名無しさん:2005/09/07(水) 22:28:17
割り込みにきまってんだろハゲ
936デフォルトの名無しさん:2005/09/07(水) 22:34:22
>>933
signal trampoline
937デフォルトの名無しさん:2005/09/13(火) 18:52:56
>>933
イベントやシグナルみたいな大掛かりなものはスレッド自体が
待ち状態になってスケジュールしなおされる。

スピンロックで待つのはWin32でSMPのEnterCriticalSection(記憶違
いかも)とか、Windows の WDM のコードとか、linux のカーネル内の
コードとかでスケジューラを動かすまでもないホンのちょっとの排他
処理を行うとき。
938デフォルトの名無しさん:2005/09/13(火) 22:59:20
なるほろ
939デフォルトの名無しさん:2005/09/16(金) 02:59:23
今2wayの鯖あるのですが、2つのCPUを効率よく使って計算させようと思うと
スレッド間でメモリ共有するだけでいいでしょうか?何か気をつけることないですか?
940デフォルトの名無しさん:2005/09/16(金) 03:10:07
意味若乱
941デフォルトの名無しさん:2005/09/16(金) 03:35:40
逆になるべく共有リソースを無くして独立させる方が良いと思う。
共有してると、アクセス排他制御とか同期制御とかが絶対必要。
942デフォルトの名無しさん:2005/09/16(金) 03:52:23
ていうかスレッドはメモリを共有してるもんでしょう
943デフォルトの名無しさん:2005/09/16(金) 07:09:44
>>942
メモリ空間は共有してても、同じメモリアドレスを共有してなきゃ問題ないじゃん。
944デフォルトの名無しさん:2005/09/16(金) 08:49:07
>>943
財布は共有してても生活空間は共有しない
という独立思考の高い夫婦モデルだな
945デフォルトの名無しさん:2005/09/16(金) 09:48:15
まあ普通プロセス/タスク内のスレッド間ではメモリを共有してるけどな。
946デフォルトの名無しさん:2005/09/21(水) 19:20:26
>>937
なんか変じゃない?
スレッドがスケジューリングされなきゃ、何時まで経っても他スレッドが実行されず、
状態が変化しないのと違う?
947デフォルトの名無しさん:2005/09/21(水) 20:05:03
>>946
完全に協調型ならそうなりますな。
普通は外的要因で叩き起こされると思いまふが。

948デフォルトの名無しさん:2005/09/21(水) 20:15:08
>>946の行っている意味が分からないので解説して。
>>937のどの部分に対していっているの?
949デフォルトの名無しさん:2005/09/21(水) 20:16:49
元の質問も、その答えも、高度すぎて意味がわからん
950デフォルトの名無しさん:2005/09/21(水) 23:40:48
>>948
いつまでもspinlockの所有権をacquire しようとし続けると
デッドロックしてしまうということ。
なわけでデッドロックしないように考慮する必要がある。

具体的には、
Win32 API のCritical Section の場合にはInitializeCriticalSectionAndSpinCountで
「スケジューリングしないでぐるぐる回る回数(の上限)」を設定して使う必要があるし、
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/initializecriticalsectionandspincount.asp

Windows のカーネル内でKeAcquireSpinLock なんかを使う場合にはdispatch level とか
も考慮して、acquire したら自コンテキストの実行が中断されないうちにすぐreleaseすることが
要求されている。
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/kmarch/hh/kmarch/Synchro_f74a900d-aad5-4473-8f46-00531c9ade89.xml.asp
951デフォルトの名無しさん:2005/09/21(水) 23:50:19
要するに、

>>937
> スケジューラを動かすまでもない

を「自分からyeild()しないで」等に書き直した方がいいって事ね。

952デフォルトの名無しさん:2005/09/22(木) 03:02:54
そもそもSMPでスケジューラ等を実装するには、
スピンロック等の低レベルな排他機構が必要なわけで…
953デフォルトの名無しさん:2005/09/22(木) 11:44:45
マルチスレッドと、ウィンドウプロシージャについて質問なんですが、
現在、通信系のプログラムを書いています。

あるデータを受信したら処理をして、その結果を送信元に返信する。

という関数があるのですが、
1).スレッドを作り、そのスレッドで処理をさせる。
2).ウィンドウプロシージャを作り、メッセージにデータのポインタを渡す。
 ウィンドウプロシージャで処理を行わせる。

この2通りを考えてみたんですが、楽なのは2)です。
どっちの方法が有効でしょうか?
954デフォルトの名無しさん:2005/09/22(木) 11:48:00
スレッドを使ってブロッキングでやるのが1番楽だと思う
955デフォルトの名無しさん:2005/09/22(木) 14:02:05
>>953
結局1)が楽です。
956デフォルトの名無しさん:2005/09/22(木) 16:32:07
こんにちは。
gcc(RHEL), MinGW(Win), Visual Studio .NET(Win)の各環境でC++を使って私用ミニツールなど
を作ったりして仕事してる、一介の営業マンです。最近はサービスでお客さん用のツールなんか
も作ったりし始めました。SE受注減らしてどうするんだって感じですが。

C/C++でのpthreadに関する質問です。
pthread_createでガーっと並列にスレッドを作って仕事をさせ、pthread_joinを回して終了を待つわけな
のですが、
pthread_joinはブロックするので、先頭のスレッドが長引いちゃうと後に続くスレッドが先に終わってても
ボケーっと待ってしまいますよね。
これを、スレッドが終了した順に処理する方法ってありますでしょうか?
よろしくお願いします。
957デフォルトの名無しさん:2005/09/22(木) 16:46:40
例えばこんな風にすればいいんじゃない?

* 生きてるスレッド数を数えるカウンタを用意しておく。(スレッド数で初期化)
* 各スレッドは終わるときにカウンタを減らして、ゼロになったら pthread_cond_signal() みたいなことをする。
* メインは pthread_cond_wait() かなんかで待ち。
* 起こされた時にはスレッドは全部終わってるはず。
* もちろんカウンタをいじるときは排他制御。
958デフォルトの名無しさん:2005/09/22(木) 16:48:56
あと、スレッドが終わる度になんかするなら、

* 各スレッドは終わるときにカウンタを減らして、 pthread_cond_signal() みたいなことをする。
* メインは pthread_cond_wait() かなんかで待ち。
 起きたときにカウンタがゼロになってたら全部終わってるはず。
959デフォルトの名無しさん:2005/09/22(木) 16:53:21
どうせ全部まとめて終了を待つなら、順番にjoinするだけで何の問題もないと思うけど。

メインスレッドはワーカースレッドを終了を順次待ちつつ何かしてる必要があるなら、
キューを用意してスレッドが終了前に自分のpthread_tを追加するとか、
メインスレッドがイベントループなら終了を通知するイベントを投げるとか。
960デフォルトの名無しさん:2005/09/22(木) 19:33:15
> 全部まとめて終了を待つ
逆です
早く終わったスレッドの順に次のジョブキューに入れるやり方ですね
961デフォルトの名無しさん:2005/09/22(木) 19:36:14
それならスレッドプールでしょ
962デフォルトの名無しさん:2005/09/22(木) 19:42:45
元の質問文と真実の内容がかけ離れてんな
963デフォルトの名無しさん:2005/09/22(木) 20:10:03
>>960
>早く終わったスレッドの順に次のジョブキューに入れるやり方ですね

その場合はスレッド終わっちゃいけないから、joinなんか使えないと思われ
964デフォルトの名無しさん:2005/09/22(木) 20:30:46
リスト構造にしたらいいんじゃね?
965デフォルトの名無しさん:2005/09/23(金) 01:37:09
>>963
pthread_cleanup_push()で登録するとか。
966956:2005/09/29(木) 20:31:03
つまりこんなかんじ?

1. 子スレッドはその仕事の最後にグローバル関数で
「俺は終わりましたフラグ」を立ててから死ぬ

2. メインのスレッドは全部の子スレッドの「俺は終わり
ましたフラグ」を監視しながらぐるぐる回ってる

3. あるスレッドの「俺は終わりましたフラグ」が立ったら、
そのスレッドの計算結果を取得して次の仕事に放り込む


んー、スレッドの数が不定なので、俺は終わりましたフラグの
作り方と監視の仕方の実装に工夫が要りそうですね。
967デフォルトの名無しさん:2005/09/29(木) 21:40:28
>>956
なぜスレッドを使って並列でしようとしてるのかが見えないんだけど・
本当にマルチスレッドにする必要あるのかな
968デフォルトの名無しさん:2005/09/29(木) 21:43:23
つか>>965は無視なんか?
969デフォルトの名無しさん:2005/09/29(木) 21:56:27
リスト構造でやってみたらと・・・

//スレッドに持っていく構造体
typedef struct tag tag;
struct tag{
tag *next;//初期化してNULLにしておく
・・・
};

//メインが持つグローバルデータ
tag *root;
tag *last;
int flg;

計算が終わった子は
flgが特定の値であれば待機。
flgが特定の値でなければ特定の値にして
  rootがNULLでなければlast->nextに自分の構造体のアドレスを登録。
  rootがNULLであればrootとlastに自分の構造体のアドレスを登録。

メインスレッドは
flgが特定の値であれば待機。
flgが特定の値でなければ特定の値にして、
構造体のデータを取り出す。
root=root->next;とする。
flgの値を戻す。

ま、こんな感じでどうざんしょ。
970デフォルトの名無しさん:2005/09/29(木) 22:00:26
>>966
漏れならこうするよ。

メインスレッド
1. ジョブをキュー(FIFO)に登録。
2. ワーカスレッドを妥当な数だけ生成
3. pthread_cond_wait() か何かで待ち、ジョブのキューが空になっていたら完了。

ワーカスレッド
1. ジョブをキューから取り出して実行
2. 完了したら、その結果を利用した「次の仕事」を(もしあれば)ジョブキューに入れる。
  無ければスレッド終了。
3. 1に戻る
971デフォルトの名無しさん:2005/10/01(土) 13:03:58
pthread_cond_waitとかpthread_cleanup_pushとか、クレバーなコーディングはご法度
972デフォルトの名無しさん:2005/10/03(月) 13:56:54
クリティカルセクションとミューテクスはどちらがお勧めなのでしょうか?
ダンディーな方、教えてくださいませ。
973デフォルトの名無しさん:2005/10/03(月) 14:47:01
>>972
オススメと言うか、その2つは使い分けるもの。
Win32の場合の話だけど、

プロセス内でのスレッドの同期程度ならクリティカルセクションを用いる。
複数のプロセスで排他を行いたいなら、ミューテックスの類を使う。

SMPで無ければ効率は同じ。SMPの場合にはInitializeCriticalSectionAndSpinCount の説明を参照。
974デフォルトの名無しさん:2005/10/03(月) 18:16:26
>>973さん
なるほど、納得しました!
どうもありがとうございました。
975デフォルトの名無しさん:2005/10/03(月) 19:09:16
>>974
まだあった・・
複数の同期オブジェクトを待ったり、待っている最中にWindowメッセージや
COMのLRPC(外部スレッド/プロセスからのCOM呼び出し)を処理する必要
があるなら Mutex。
976デフォルトの名無しさん:2005/10/03(月) 19:28:00
>>975
色々違いがあるんですね。
ご丁寧に有難うございましたm(_ _)m
977デフォルトの名無しさん:2005/10/11(火) 23:14:03
age
978デフォルトの名無しさん
お舞らたとえばですがファイルの内容をメモリ上に展開しそこにほかのスレッドがアクセスする必要があるとしたらどんな風に書きますか?
・データは木構造
・IOからメモリに展開するスレッドは複数
・そこにUI スレッドや、計算スレッドが頻繁にアクセスする。リーダーとライターが複数ずついる。
・ためしにクラスレベルロックみたいのでやったらUIスレッドでCPUが100%言ってないのにたまに固まる(1秒以下)ことがある。

こういう場合ってどんな風にするもんなんでしょう。粒度さげると書くのが('A`)マンドクさくなるしデッドロックの危険も出てくる。
一般解や俺ならこうしてるってのがあればよろ。