713 :
デフォルトの名無しさん :
2005/06/27(月) 02:16:21 orz って今の今まで、 ○| ̄|_ の小さい版とは知っていたが、 四つんばいとは知らなんだ。 拳を握り、目を細めて ウググググ・・・って悔しがってるのかと思ってた。
714 :
デフォルトの名無しさん :2005/06/27(月) 03:11:43
> 拳を握り、目を細めて ウググググ・・・ が分からん。orz
漏れもわからん・・・
とりあえず漏れの解釈。 顔の線 ↓ ○| ̄|_ ↑ ↑ ↑ 拳 目 鼻
伝説の予感・・・
o/z-/b
@@@ @@@@ ○| ̄|_  ̄|○ \◎/ | | ̄|_ ○| ̄|_ orz
短足だから見間違えたんだな。 ○| ̄|_ なら顔には見えまい。
@@@ @@@@ ○| ̄|_  ̄|○ \ー/ ニヤリッ
にしこり
725 :
713 :2005/06/27(月) 19:49:48
そうです。
新キャラ誕生の瞬間を目撃!?
727 :
713 :2005/06/27(月) 23:54:47
顔の線 ↓ ○| ̄|_ ↑ ↑↑ 拳 目 口 これ、口だから。崩さんといて。<@
く、口なのか?
729 :
713 :2005/06/28(火) 00:08:58
>>702 クリーンアップしてる間はキャンセル禁止(か遅延)にしとけば?
クリーンナップ中にpthread_setspecific()したら 再度クリーンナップされるのはPOSIXの正しい仕様ですか?
哲学者にレイプされました。アノ人たちにとってアタシは共有リソースだったんです。 三つの穴にとっかえひっかえ入れられて。入れてない哲学者は瞑想にふけて、 順番が来るのを待ってました。 アタシはセマフォなんて信じない。 デッドロックは無かったです。(T T)
入れる物が一つならデッドロックはないわな
○| ̄|_ ̄|○
○| ̄|_ ̄|○ <デッドロックに耐えてよくがんばった!
クラス内の関数をスレッド化することを考えています。 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ではないメンバ変数が使えなくなってしまいます。 どのようにすればよいのでしょうか?
737 :
736 :2005/07/05(火) 10:06:02
(THREADFUNC)、tidはそれぞれ typedef void *(*THREADFUNC)(void *); pthread_t tid[threadnum]; です。
○| ̄|_ ̄|○ <スレッドよりもC/C++の勉強をしたまえ!
○| ̄|_ ̄|○ これって、ルイ14世のAA?
○| ̄|_ ̄|○ <私は哲学者だ。デッドロックは許さん。
○| ̄|_| ̄|○
○| ̄|_ ̄|○ <か、かあさん!
○| ̄|_ ̄|○ <
>>736 は
>>629 と同一人物なのか?
なんでこう同じ質問がなんども... _ ̄|○
>>740 こんな感じでつか
Ψ
○| ̄|_| ̄|○
Ψ Ψ
○| ̄|_| ̄|○ ○| ̄|_| ̄|○
Ψ Ψ
○| ̄|_| ̄|○ ○| ̄|_| ̄|○
>>736 関数はstaticにして、クラス内の変数を使いたければ、クラス自体をその関数に
ポインタとして渡すしかない。
>>745 ○| ̄|_ ̄|○ <君もC/C++の勉強をしたまえ!
>>736 Javaつかえ。C++はあまりマルチスレッド向きではない。
748 :
736 :2005/07/06(水) 14:25:39
ここは荒れたスレのようですね。他に行きます。
○| ̄|_ ̄|○ <君の悩みはスレッドとは関係ないからC/C++のスレにでも逝きたまえ。
○| ̄|_ ̄|○ <スレッドとスレッドをかけているのは絶対に秘密!
>>750 ○| ̄|_ ̄|○
>>745 はクラスをファーストクラスのオブジェクトのように語っておるが…
A| ̄|_ ̄|A <彼はクラスとオブジェクトの区別がついていないのですね。
B| ̄|_ ̄|Bすまん、ただこれが書きたかっただけなんだ
755 :
デフォルトの名無しさん :2005/07/09(土) 02:56:04
C言語+Windows APIを使っているのですが、 最大化やウィンドウのリサイズを禁止するにはどうすればいいんでしょうか? 最小化はそのまま使えるようにしたいのですが…
自分でメッセージ処理すればおk
B| ̄|_ ̄|B <つーか、何スレ違いに回答してんだよ。
758 :
デフォルトの名無しさん :2005/07/10(日) 11:52:37
Linuxオンチなんで、ちと教えてくださいまし。 - Linuxでマルチスレッド・アプリケーションとなったとき、 pthreadは'事実上の標準'もしくは'アッタリマエ'か? - pthradはLinuxの一部ではないが、たいていのディストリビューション には添付されている。という認識で正しいか? - スレッド起こすのにはcloneとかいうsystem-callがあるが、 こいつはコンテキストの切り替えにプロセスと同じことやる ので決して速くはない。は真か?
上2つは「どのlinuxでも動くようにしたい」ということか? 最後のはよくわからんが普通にスレッド起こすのは十分速いよ。
- 当たり前かつ標準 - pthradは一部でも添付されてもいないが、pthreadは標準 - clone(2)はpthread_create(3)を実現するためのシステムコール。 あんたが使う類いのものじゃない。
>>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などが内部で使ってるシステムコールであり、
アプリケーションプログラマが直接触るものではない。
NPTLもclone(2)使ってるんだ。。。
Win32でとある入出力デバイスをバッファ管理しながら 操作するライブラリ書いてるんだけど、 こういった場合スレッドセーフにするにはどこまでやるべき? バッファやデバイス設定値を読み書きする所全て排他? それともTLSでスレッド個別にメモリ確保のみ? TLSだと複数スレッドから同一デバイスに対して 操作するときどうなるかわからんけどこれで許してもらえるかな? 仕様には特に明記されていないので、 俺様ルールでいいのかなとも思うんですが、 やっぱり普通はスレッドセーフにしないと駄目ですよね。
デバイスへのリクエストが同期式の場合、 (つまりリクエスト呼び出し復帰時に結果が返る) 排他が必要な場合が結構ある。
>>763 どこまでやるべきかは、前提とすべきスレッディングモデルの定義による。
話はそれからだ。
どうしてこれは途中でデッドロックしてしまうんでしょう? 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; }
fflush(stdout); とかいうオチじゃないだろうな
768 :
766 :2005/07/14(木) 02:21:27
>>767 ありがとうございます。
やってみたのですが、バッファリングの問題ではないようです。
書き忘れましたが、どうやらスレッドが終了(return)するとロックするようなのです。
ネットにあるような単一スレッドのサンプルは問題なく動いています。
_beginthreadを使った場合はこのようなことは起こりません。
なんでだろう・・・。
joimしてない?
>_beginthreadを使った場合はこのようなことは起こりません。 つまりCreateThread使ってるってこと? Cランタイムライブラリを使う場合は_beginthreadを使う必要があると思うんだけど
てゆうか for (;;) { ; } ってなんだよ。 MSDOSならともかく、今時のOSで許されるコーディングじゃないぜ。
773 :
766 :2005/07/14(木) 08:37:48
>>759 返り値のIDを使わないからです。
配列にして個々にIDを入れても固まってしまいます。
>>770 メインスレッド側はjoinが必須なんでしょうか?
一応joinしてみたのですが、やはり固まります。
>>771 process.hの_beginthreadを使っています。
先ほど
>>770 さんに指摘されたjoinなどについて調べて、
結果的にはdetachを使用することでテストケースの場合はロックすることはなくなりました。
が、本件の方はdetachしてもロックしてしまいます。
もう少し調べてみます。
joinしてもダメだったコードをさらせ。
for (i = 0; i < 10; i++) { printf("%c", *(char *)pdata); } fflush(stdout); <-- これ付け足したら動く予感
>>768 > > 書き忘れましたが、どうやらスレッドが終了(return)するとロックするようなのです。
お前の言いたいのは、
・出力されません
に過ぎないのと違うのかと…
「ロック」言いたいだけと違うんかと…
forでビジーループしちゃいかんだろ、スレッドで。 for( ; ; ) {{ sched_yield(); } ってして他のスレッドを動かすのが基本。 ○| ̄|_ ̄|○
>>777 > ○| ̄|_ ̄|○
○| ̄|_ ̄|○ <お前が喋れよ。登場するだけかよ!
>>777 おいおい、それもビジーループなんだよ。
待ってるだけなら pthread_join() を使うのが基本中の基本。
大丈夫かホントに。
780 :
766 :2005/07/15(金) 01:36:12
NTでpthread、がとりあえず不思議。
NetBSD でやったら "End" まで出たよ。
>>781 と同感なんだがどうやってるの?
cygwin?
Linux 2.6も問題なし。
>>766 ○| ̄|_ ̄|○ <Win2kのcygwinで実行したところ一瞬で終了して以下が表示された。
01021304215360742819536074281953607428195360742819536074281953607428195360742819
53674289536748956789End
785 :
766 :2005/07/15(金) 09:35:41
仰る通り、Cygwinです。 マズイな、こりゃOSを疑うべきなのか。 それが分かっただけでも収穫です、どうもありがとうございました。
OSつーかCygwinの問題だろう。 Cygwinは「UNIXと同じソースで動いたらラッキー」ぐらいのものだと思っ といたほうがいい。
いやそうなんだが、まさかこういう基本的なところでダメだとは驚いた。 コンパイルできないのはOKだが、誤動作は勘弁してほしいな。 Windows 使う場合は Windows の native thread を使えってことか。 まあ、API は pthread とそんなに違わないから (というか、たぶん 両方とも Mach の cthread の真似だよね、きっと)、wrapper ライブ ラリ書いて pthread と Windows のどちらでも動くプログラムにする のは難しくないよ。
つうかNTはもうよせ、と
cygwin、
>>784 で動いているやん。
つうかstdoutの排他は?
>>784 で正しく動作しているように見えるけど何が問題なの?
Win2kでは動くけど「NT4sp6、デュアルプロセッサ」では動かないということでわ?
というかstdout排他してないし… こんなのはたまたま動いているだけのプログラム。
OSを疑うとか片腹痛い。
>>780 のコードは回りくどい方法だけど一応stdoutを排他制御してますやん。
OSを疑うのはどうかと思うが。 cygwinを疑うのは正しい姿勢の予感。
cygwinはイロイロやってそうだしなぁ
>環境がNT4sp6、デュアルプロセッサです。 ってのに妙に引っかかるな。 デュアルプロセッサで、デュアルプロセッサカーネル使っていないとか 実は、cygwinはデュアルプロセッサに対応していない。とか
> cygwinはデュアルプロセッサに対応していない さすがにそりゃねーべ 今NTで十分テストされているとはあんまり思えないんだが、そのへんかな
>>784 だが、
うちのWinマシンはデュアルではないけどHTです。
OSからはCPU2個に見えてる状態。
cygwinて、glibc? なんかstdioの排他とかゆってる人いるけど、 glibcのstdioって、スレッドセーフじゃないの?
>801 glibc じゃなくて newlib のはず。
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の実装があるから関係無いとは思うが。 正直その辺りの関係は俺もわからん。
/* 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
あれ?xchgはLOCKプレフィクスなしでもメモリ相手ならロックかますと記憶してたが。。。
806 :
803 :2005/07/19(火) 01:04:02
【初心者歓迎】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);
}
#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); }
//自動操作 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; }
>>807 うちでは落ちないでいつまでも動き続ける。
gcc は 3.3.5。
pthread_detachをメイン側でやれば落ちないみたい
812 :
807 :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のせいだと考えてよいのでしょうか?
落ちるのは gcc というより pthread の実装の違いかも。
814 :
807 :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でファイルをロックしているとき、 同じプロセスの別のスレッドが同様にロックをしようとすると、 ロックが取得できてしまうんですか?
>>815 fcntlはロックの所有権がプロセス単位だから。
817 :
デフォルトの名無しさん :2005/07/29(金) 22:40:15
age
818 :
デフォルトの名無しさん :2005/07/29(金) 23:05:36
マルチスレッドセーフとは 1.スレッドの中でスレッドを作成した場合にいうのでしょうか 2.一つのプロセスで複数のスレッドを作成した場合にいうのでしょうか。 それとも両方マルチスレッドセーフというのですか?
1と2をどう区別していいのか教えてくれ。
スレッドセーフの意味わかってるのか?
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を書きました。
,j;;;;;j,. ---一、 ` ―--‐、_ l;;;;;;
{;;;;;;ゝ T辷iフ i f'辷jァ !i;;;;;
>>821 お前にはマルチスレッドは無理。
ヾ;;;ハ ノ .::!lリ;;r゙
`Z;i 〈.,_..,. ノ;;;;;;;;>
,;ぇハ、 、_,.ー-、_',. ,f゙: Y;;f そんなふうにかんがえていた時期が
~''戈ヽ `二´ r'´:::. `! 俺にもありました
826 :
821 :2005/07/29(金) 23:55:01
,j;;;;;j,. ---一、 ` ―--‐、_ l;;;;;; {;;;;;;ゝ T辷iフ i f'辷jァ !i;;;;; 2chネラは真面目な人が多い ヾ;;;ハ ノ .::!lリ;;r゙ 人を馬鹿にするようなことはないだろう `Z;i 〈.,_..,. ノ;;;;;;;;> ,;ぇハ、 、_,.ー-、_',. ,f゙: Y;;f そんなふうにかんがえていた時期が ~''戈ヽ `二´ r'´:::. `! 俺にもありました
828 :
デフォルトの名無しさん :2005/07/30(土) 00:12:37
>181わぁ、書き方を間違えただけであって、正確にはだな、 マルチスレッドセーフを冒すのは、 1.〜 2.〜 それとも両方マルチスレッドセーフを冒すのでしょうか? だと、思うのは俺だけか? 俺は、1.2.ともその可能性をはらんでいると思う お互いを蝕むのを避けるために、踏切りの警報灯のように交互にチカチカ同期採る手法や 片方をlockさせる手法があるのでしょう >181は気にすることはない リアルで溜まったウサを晴らしたいヤシが吐き捨ててる場合もあるんだから そういう肥溜めはシカトしときゃいい
∋oノハヽo∈ ( ´D`) 誤爆れすか?
@| ̄|_ ̄|@ <ある関数が、複数のスレッドから同時に実行されてもハラハラしない時、 A| ̄|_ ̄|A <その関数はスレッドセーフである、とかなんとか言われるのである。 B| ̄|_ ̄|B <きっとね!
>踏切りの警報灯のように交互にチカチカ同期採る手法 は、誤解招くから、補足しとくと、 お互いがどこまで進んだか分からないと、迂闊にお互いのデータを使えないから、同期を採って、進行度を相互確認する それと、親プロセス、子プロセスの関係の、マルチプロセス、要はforkというのもあるけど(知っているかもしれないけど)、 これの弱点は、同じOSのshell上で動くから、処理が重くなる。だから、マルチスレッドが推奨されてるわけだけど、 利点もあって、親が終了しても、子は動き続けられる
○| ̄|_ ̄|○ <いいからもう寝ろ
なんで、そんなにうなぎ連結してんの? キモイよ?
一つだと、四つん這いと間違えるから。
pThreadでロックをある所有が行い別のやつがアンロックを行うって方法を 使っているのですが、とても微妙な使用方法だと思うのですが改善する方法ないですか? あとpthreadのデバッグってどうしてますか?
> 一つだと、四つん這いと間違えるから。 わらた
840 :
デフォルトの名無しさん :2005/08/02(火) 20:41:39
誘導されてきました。 C言語でマルチスレッドプログラミングについて教えてもらいたいです。 問題は、 (1)簡単なスレッドプログラミング及びスレッドの動作について解説せよ。 (2)相互封鎖や相互実行が起こるプログラムを作成し、その動作を解説せよ。 (3)マルチスレッドで、turnやflagを使った排他制御のプログラムを作成し、その動作を解説せよ。 (4)消費者・生産者問題のプログラムを解説せよ。 です。宜しくお願いします。
841 :
デフォルトの名無しさん :2005/08/02(火) 20:44:01
見事な教えてクンぶりに感動すら覚えた。 誘導先でも煙たがられてるし...
グローバル変数や静的変数をスレッドごとに持たせることって可能ですか? 変数をロックして共有するのではなく、メンバ変数みたいな感じで状態管理に使いたいんです。 errornoとかはそうなっているみたいなんですけど。
>>543 TLS
ちと調べればすぐわかりそうな気がするが。
単純にぐぐるとネットワーク関連の方がひっかかるので補足しておくと、Thread Local Storage な。
C++で組んでたときはあんまり意識せずに書けたな。メンバ変数はデフォルトではインスタンスローカルだから Cでも単純にスレッドごとに構造体のインスタンス別々にしてやればいいジャンとか思うの俺だけ?
まあポインタで引っ張り回したら何だって出来るんだけど、 スレッド内関数呼び出しのそのレベルでも、 スレッドローカルな大域変数のように扱えるのが、 スレッドローカルストレージフレームワークだから… Common Lispの*special*変数も似た風に使えるけど、 あれよりはコストが安い。
( ´∀`) 気のせいダロ
>846 >最近のC/C++標準では __thread というキーワードで言語仕様にも採り入れられている。 9899:1999 でも 14882:2003 でもそんなキーワードは引っかからないぞ。 つーか、__ で始まってる時点で処理系依存の拡張じゃないのか?
>>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.
852 :
846 :2005/08/06(土) 19:43:25
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?
スレッドプロシージャをクラス内に実装する裏技(といっても常套手段)使えば 大域変数みたいに使うことはできる。 てかCreateThreadに渡すダミーのスレッドプロシージャにthisポインタ渡してメンバ関数を起動するだけだから。 (Win32での話)
さんざん既出かもしれないけど、質問します。 windowsでpthreadの状態変数みたいなのはどう実現すればよいのでしょうか? 排他変数にMutexをつかうならSignalObjectAndWaitをつかえばよいんだけれども CriticalSectionを使いたいんです。
状態変数に近いのはイベントオブジェクトじゃない?
状態遷移マシンの実装を語るスレがほしいな。
>>858 ○| ̄|_ ̄|○ <オマエ「状態遷移マシン」て言ってみたかっただけだろ!
正規表現ライブラリのソースをみるとか マルチスレッド関係ないな
861 :
856 :2005/08/07(日) 13:18:58
> 状態変数に近いのはイベントオブジェクトじゃない? そうなんですけど、pthreadの場合、 状態変数をwaitするとき mutexを渡して内部でアトミックにmutexをアンロック→シグナル待ち→mutexのロックをしてて これをwindowsで実現できないかなと・・・ WindowsのばあいMutexをWait〜系関数で待つことは出来るけど、CriticalSectionは使えない。 たとえばpthreadで状態変数をつかっているようなところを windowsに移植するときはどうしたらよいのかなと思いまして・・・
862 :
856 :2005/08/07(日) 13:20:21
> 状態変数に近いのはイベントオブジェクトじゃない? そうなんですけど、pthreadの場合、 状態変数をwaitするとき mutexを渡して内部でアトミックにmutexをアンロック→シグナル待ち→mutexのロックをしてて これをwindowsで実現できないかなと・・・ WindowsのばあいMutexをWait〜系関数で待つことは出来るけど、CriticalSectionは使えない。 たとえばpthreadで状態変数をつかっているようなところを windowsに移植するときはどうしたらよいのかなと思いまして・・・
aprだと、EventとMutexを使ってcond_wait/signalをエミュレートしてるね。
もちろん、cond_waitに渡すmutexはCRITICAL_SECTIONで良くて、
Mutexを使っているのはWaitForで待つためらしい。
http://apr.apache.org/
864 :
デフォルトの名無しさん :2005/08/07(日) 14:18:12
クラス内のメソッドを並列で実行したいのですが、やり方がわかりません。どこかに参考になるページはありませんか?
865 :
856 :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)
>>859 ばれたか。
でもWindowsでWindowMessageを使って実装する例とか、
専用のクラスの実装例とか、どんな問題があってどんなメリットがあるとか
そういうことを勉強したかったのもあるよ。
pthread_cond_signal/broadcastの実装には シグナルとウエイトをアトミックにやる必要がある。 「アトミックに」ってところが重要で シグナルしてウエイトするというようにバラバラやっていたのではダメ。 それをする手段は、Win32だと、SignalObjectAndWaitしか知らん。
?
mutex といえば、Boost.Thread の Win32 版 mutex の実装に、 CRITICAL_SECTION ではなくて、Mutex が利用されていたな。 Win32 の Mutex は遅いから、メータードセクションを利用して 実装して欲しかった。
>>869 今1.32のソース見たけど、クリティカルセクション使ってたよ
>>869 メータードセクションってこれ何時頃から実装されてるの?
MSDNみて、こんなの有ったのかと目から鱗状態なんだけど。
95でも使えるっぽいから、相当前からある様なんだけど。
自己レス。
APIとしてSDKに実装されてるわけじゃないのね。
MSDN英に.hと.cのフルソース上がってたからもらってきた。
mutexと置き換えて遊んでみる。
>>869 ありがと。
うろ覚えだが、メータードセクションは、ロックカウントを持っていないので、 クリティカルセクションのつもりでリソースを1にして、 同じスレッドで複数回 EnterMeteredSection すると、あとあと面倒だったかも。
メータードセクションなんで初めて知ったよ みなさんスゴイすね
>>873 それなら自分でReentrantな実装にしちゃえば?
メータードセクションのReentrantな実装に改良している最中に、 以前AdvancedWindowsのオプテックスを セマフォ的にしたものを作ったのを思い出した。orz とても不毛な月曜の午前。
877 :
デフォルトの名無しさん :2005/08/26(金) 14:48:45
基本的な質問します。 stringとかのポインタをスレッドに渡し、スレッドより先にメインが終了してしまった場合、 そのstringはもう生きていないですよね。 こういうときはどうやって処理をすればいいのでしょうか?
>>877 寿命管理ができないなら、実体で渡す。
実体渡しが嫌なら、サボらずにちゃんと寿命管理を行う。
○| ̄|_ ̄|○ <メインが終了したらプロセス全体が終わるだろ
880 :
デフォルトの名無しさん :2005/08/26(金) 15:11:45
がんがって実態渡ししてみます。
メインが終了したらアプリ全体が終わっちゃうから、 スレッドでの処理が終わるまでメインを待たせろつーの。。
○| ̄|_ ̄|○ < ああ、面倒くせーな!
883 :
デフォルトの名無しさん :2005/08/28(日) 13:15:09
マルチスレッドアウトな関数multithreadout()があります。 この原因はグローバル変数glbを使っていることです。 通常、同一プロセス内でmultithreadout()を使うと駄目ですが、 multithreadout()をdllファイルにしてもマルチスレッドアウトのままでしょうか?
>>883 Yes.
DLL(が読み込まれたメモリ空間) はプロセススコープの資源。
はい
解決する方法として 1).マルチプロセスにする。 2).multithreadout()だけをexeファイルにして引数を受け渡す(パイプを使う&dllを使用しない) 3).multithreadout()をdllファイルにし、multithreadout()呼び出し専用の exeファイルを作り、パイプを使う 2).3).の違いはmultithreadout()が静的か動的かなのですが、 他に解決する方法はありますか?間違った解決方法を考えていませんか? また、処理のほとんど(90%以上)はmultithreadout()が行います。 呼び出し回数は数回程度です。
グローバル変数を使わないように、multithreadout()を変更する と言う選択肢もあるはず
multithreadout() を multithreadout_real() か何かにリネームして、 multithreadout()は、 multithreadout() { static CriticalSectionとかMutexとか lock; Lock(lock); multithreadout_real(); Unlock(lock); } あたりにすればいいんじゃないかと思う。 例外処理とか、lockの初期化は適当に。
889 :
856 :2005/08/28(日) 17:35:49
以前紹介してもらったaprのミューテックスなんだけど、よく見ると怪しい部分があるような気がしてきた。 broadcastのときwaitしているスレッドを数えるためにカウントしているんだけど、 イベント待ちの直後そのカウンタをインクリメントする必要があって、その部分がクリチカルになっていない。 どうなんだろう?自分は怖いんでカウンタをCRITICAL_SECTIONで囲んだけれども。
890 :
856 :2005/08/28(日) 17:46:49
あう、mutexじゃなくてconditionだった。スマソ
signalとかbroadcast待ってる香具師ってスピンしてんの? 古いイベントで使うようなselectとかとどっちが速い?
×古いイベント ○古いイベント志向 すまそ。
selectって古いイベント志向といういいかたするのか? ま、それはさておき、遅いか早いかは 実装による。 以上だ!
selectって古いイベント志向といういいかたするのか? ま、それはさておき、遅いか早いかは 実装による。 以上だ!
896 :
デフォルトの名無しさん :2005/09/02(金) 00:41:56
この読みが外れればそれを口実に日本に戦争を仕掛けるつもりだったのか
↑ 誤爆しました。メンゴ
Solarisだと、select(3C)はpoll(2)を使ってる
>>899 それは昔の話で、select(3)の実装がpoll(2)を使わないように2,3年前に変わらなかったっけ?
901 :
デフォルトの名無しさん :2005/09/04(日) 18:49:22
そんな重要そうな事もはっきりしないのがUNIX文化ってやつですね
selectもpollも対して変わらんよ。じゃあ 「イベントとか割り込みって、中でpoll使ってんじゃね?」 と言えばいい?
ちゃんとCPU返してくれればどうでもいい。 たまにビジーループぶん回すのがいるからのう…
904 :
891 :2005/09/05(月) 00:08:39
>>903 えっと、まさにそこを聞きたかったんすけど。
ループしてるか見分ける方法ってある?
>>898 んなわけねー(w
>>904 お前以外にループする奴はいない。in お前のプログラム&カーネル。
906 :
891 :2005/09/05(月) 23:58:31
何言ってるのかわかんないんだけど。
908 :
899 :2005/09/06(火) 21:37:49
Windowsは詳しくないから分からない というか、こんなの聞いてどうなるものでもないような
>>891 > signalとかbroadcast待ってる香具師ってスピンしてんの?
ロックが競合したときにmutexの入口でスピンすることはあっても、
signalとかbroadcastを待ってる状態(つまり条件変数をwaitしている状態)で
スピンし続けてCPUを離さないってことはありえない。
そんな実装があったら、条件変数の意味が無くなるだろ。
スピンとポーリングって何が違うの?
スピン = 無期限連続ポーリング
>>910 spinってのはSMPで一つのCPUだけがポーリング対象の資源を
得ることが出来るようなポーリングの仕方のことを言う。
皆がアクセスできる皿と、自分の手元の皿を夫々がくるくる入れ替えて
手元に来た皿に肉が乗ってたら食べていい、みたいな感じ。
>>912 一面的な説明で「仕方のことを言う」はいかがなものか。
>>913 文句だけじゃなくて、一面だけというのなら別の面からとか
包括的な説明とか、内容あるレスつけようぜ。
スピンしないポーリングって可能なのか。 スレッドとかシグナルってハードレベルでどうなってるのか わからなくて効率が全然読めないんだが、 その辺をユーザーレベルで理解できる本、サイトない?
WindowsならAdvancedWindowsという本かな。 これ読むとWindowsでポーリング待ちなんて馬鹿げてると思うはず。
>>916 Windowsよく知らないので、詳しく!
詳しく!
分散OS ”あ萌え場”って何でしょうか?
>>917 「Advanced Windows」嫁
あとは「Win32 マルチスレッドプログラミング」
つーかこの話で本が1冊出来るかもよ
>>915 非SMPではspin lockなど使わずにタダのループによるポーリングで十分
(カーネルモードで、割り込みを考慮しないとして)。
また、競合するスレッド/プロセスがいない場合には、SMPだろうが割り込みが
あろうが単純ループのポーリングで十分。
効率的な点については、spin lock の一サイクルはメモリ<->レジスタ間の
値の入れ替えで完了するので、行儀良く短いクリティカルセクションから
なるコードの場合は(並列度にもよるけど)、わざわざスケジューラをいじって
スレッドをシグナル待ちにするような処理よりも単にspin lockの方が効率が良い。
>>922 > (カーネルモードで、割り込みを考慮しないとして)。
> また、競合するスレッド/プロセスがいない場合には、
殆んどあり得ない仮定を置いて、何を言っているんだが…
>>923 バカ?スピンロックについての話なら、普通割り込みも競合もあるけど、
915は「スピンしないポーリングって可能なのか。」って聞いてるわけで、
単に「ポーリング」って言った場合には
>>922 の条件は良く有ることだと
思うけど。
ポーリング儲は糞プロセス量産してんだろうね
ものすごい短時間しか待たないことがわかってるなら、ポーリングの方が効率いいこともあるべ。
>>915 同期無しでただ読むだけで済むように設計すればいい
>>921 Windowz使ってないので、「Advanced Windows」読んでも意味ないし
MINIX使ってないので、「オペレーティングシステム―設計と理論およびMINIXによる実装」読んでも意味ないし
はあ。 Windowsは業界スタンダードだから意味あるはずだけどねえ
何業界だ?
Window業界でのはなしでしょう
windowsのイベントや、UNIXのsignalは、プログラマからみれば APIとしてはコードのその場所でじっとwaitしてる形になると思うけど イベントやsignal自体の内部実装(カーネル側?) では結局はポーリングで実現されてたりするわけ?
エロゲー的にはポーリングが正義、というFAが出ておりますが何か?
割り込みにきまってんだろハゲ
>>933 イベントやシグナルみたいな大掛かりなものはスレッド自体が
待ち状態になってスケジュールしなおされる。
スピンロックで待つのはWin32でSMPのEnterCriticalSection(記憶違
いかも)とか、Windows の WDM のコードとか、linux のカーネル内の
コードとかでスケジューラを動かすまでもないホンのちょっとの排他
処理を行うとき。
なるほろ
今2wayの鯖あるのですが、2つのCPUを効率よく使って計算させようと思うと スレッド間でメモリ共有するだけでいいでしょうか?何か気をつけることないですか?
意味若乱
逆になるべく共有リソースを無くして独立させる方が良いと思う。 共有してると、アクセス排他制御とか同期制御とかが絶対必要。
ていうかスレッドはメモリを共有してるもんでしょう
>>942 メモリ空間は共有してても、同じメモリアドレスを共有してなきゃ問題ないじゃん。
>>943 財布は共有してても生活空間は共有しない
という独立思考の高い夫婦モデルだな
まあ普通プロセス/タスク内のスレッド間ではメモリを共有してるけどな。
>>937 なんか変じゃない?
スレッドがスケジューリングされなきゃ、何時まで経っても他スレッドが実行されず、
状態が変化しないのと違う?
>>946 完全に協調型ならそうなりますな。
普通は外的要因で叩き起こされると思いまふが。
元の質問も、その答えも、高度すぎて意味がわからん
要するに、
>>937 > スケジューラを動かすまでもない
を「自分からyeild()しないで」等に書き直した方がいいって事ね。
そもそもSMPでスケジューラ等を実装するには、 スピンロック等の低レベルな排他機構が必要なわけで…
マルチスレッドと、ウィンドウプロシージャについて質問なんですが、 現在、通信系のプログラムを書いています。 あるデータを受信したら処理をして、その結果を送信元に返信する。 という関数があるのですが、 1).スレッドを作り、そのスレッドで処理をさせる。 2).ウィンドウプロシージャを作り、メッセージにデータのポインタを渡す。 ウィンドウプロシージャで処理を行わせる。 この2通りを考えてみたんですが、楽なのは2)です。 どっちの方法が有効でしょうか?
スレッドを使ってブロッキングでやるのが1番楽だと思う
こんにちは。 gcc(RHEL), MinGW(Win), Visual Studio .NET(Win)の各環境でC++を使って私用ミニツールなど を作ったりして仕事してる、一介の営業マンです。最近はサービスでお客さん用のツールなんか も作ったりし始めました。SE受注減らしてどうするんだって感じですが。 C/C++でのpthreadに関する質問です。 pthread_createでガーっと並列にスレッドを作って仕事をさせ、pthread_joinを回して終了を待つわけな のですが、 pthread_joinはブロックするので、先頭のスレッドが長引いちゃうと後に続くスレッドが先に終わってても ボケーっと待ってしまいますよね。 これを、スレッドが終了した順に処理する方法ってありますでしょうか? よろしくお願いします。
例えばこんな風にすればいいんじゃない? * 生きてるスレッド数を数えるカウンタを用意しておく。(スレッド数で初期化) * 各スレッドは終わるときにカウンタを減らして、ゼロになったら pthread_cond_signal() みたいなことをする。 * メインは pthread_cond_wait() かなんかで待ち。 * 起こされた時にはスレッドは全部終わってるはず。 * もちろんカウンタをいじるときは排他制御。
あと、スレッドが終わる度になんかするなら、 * 各スレッドは終わるときにカウンタを減らして、 pthread_cond_signal() みたいなことをする。 * メインは pthread_cond_wait() かなんかで待ち。 起きたときにカウンタがゼロになってたら全部終わってるはず。
どうせ全部まとめて終了を待つなら、順番にjoinするだけで何の問題もないと思うけど。 メインスレッドはワーカースレッドを終了を順次待ちつつ何かしてる必要があるなら、 キューを用意してスレッドが終了前に自分のpthread_tを追加するとか、 メインスレッドがイベントループなら終了を通知するイベントを投げるとか。
960 :
デフォルトの名無しさん :2005/09/22(木) 19:33:15
> 全部まとめて終了を待つ 逆です 早く終わったスレッドの順に次のジョブキューに入れるやり方ですね
それならスレッドプールでしょ
元の質問文と真実の内容がかけ離れてんな
>>960 >早く終わったスレッドの順に次のジョブキューに入れるやり方ですね
その場合はスレッド終わっちゃいけないから、joinなんか使えないと思われ
リスト構造にしたらいいんじゃね?
>>963 pthread_cleanup_push()で登録するとか。
966 :
956 :2005/09/29(木) 20:31:03
つまりこんなかんじ? 1. 子スレッドはその仕事の最後にグローバル関数で 「俺は終わりましたフラグ」を立ててから死ぬ 2. メインのスレッドは全部の子スレッドの「俺は終わり ましたフラグ」を監視しながらぐるぐる回ってる 3. あるスレッドの「俺は終わりましたフラグ」が立ったら、 そのスレッドの計算結果を取得して次の仕事に放り込む んー、スレッドの数が不定なので、俺は終わりましたフラグの 作り方と監視の仕方の実装に工夫が要りそうですね。
>>956 なぜスレッドを使って並列でしようとしてるのかが見えないんだけど・
本当にマルチスレッドにする必要あるのかな
リスト構造でやってみたらと・・・ //スレッドに持っていく構造体 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の値を戻す。 ま、こんな感じでどうざんしょ。
>>966 漏れならこうするよ。
メインスレッド
1. ジョブをキュー(FIFO)に登録。
2. ワーカスレッドを妥当な数だけ生成
3. pthread_cond_wait() か何かで待ち、ジョブのキューが空になっていたら完了。
ワーカスレッド
1. ジョブをキューから取り出して実行
2. 完了したら、その結果を利用した「次の仕事」を(もしあれば)ジョブキューに入れる。
無ければスレッド終了。
3. 1に戻る
pthread_cond_waitとかpthread_cleanup_pushとか、クレバーなコーディングはご法度
クリティカルセクションとミューテクスはどちらがお勧めなのでしょうか? ダンディーな方、教えてくださいませ。
>>972 オススメと言うか、その2つは使い分けるもの。
Win32の場合の話だけど、
プロセス内でのスレッドの同期程度ならクリティカルセクションを用いる。
複数のプロセスで排他を行いたいなら、ミューテックスの類を使う。
SMPで無ければ効率は同じ。SMPの場合にはInitializeCriticalSectionAndSpinCount の説明を参照。
>>973 さん
なるほど、納得しました!
どうもありがとうございました。
>>974 まだあった・・
複数の同期オブジェクトを待ったり、待っている最中にWindowメッセージや
COMのLRPC(外部スレッド/プロセスからのCOM呼び出し)を処理する必要
があるなら Mutex。
>>975 色々違いがあるんですね。
ご丁寧に有難うございましたm(_ _)m
977 :
デフォルトの名無しさん :2005/10/11(火) 23:14:03
age
お舞らたとえばですがファイルの内容をメモリ上に展開しそこにほかのスレッドがアクセスする必要があるとしたらどんな風に書きますか? ・データは木構造 ・IOからメモリに展開するスレッドは複数 ・そこにUI スレッドや、計算スレッドが頻繁にアクセスする。リーダーとライターが複数ずついる。 ・ためしにクラスレベルロックみたいのでやったらUIスレッドでCPUが100%言ってないのにたまに固まる(1秒以下)ことがある。 こういう場合ってどんな風にするもんなんでしょう。粒度さげると書くのが('A`)マンドクさくなるしデッドロックの危険も出てくる。 一般解や俺ならこうしてるってのがあればよろ。