1 :
デフォルトの名無しさん :
02/11/19 01:15 マルチスレッドプログラミングについて語るスレ。
OS・言語・環境は問わないが、それゆえ明記すべし。
これといったリンク先がないので
>>2 はブラクラ。
つーか前スレのリンクぐらい貼れバーカ。
3 :
デフォルトの名無しさん :02/11/19 01:21
重複してる(;_;)
重複したのでこちらは「マルチタレントプログラミング相談室」となります。
重複したのでこちらは「マルチのプログラミング相談室」となります。 後の始末はオタな方々が行ってくれるでしょう。
ええと、ここが最初に立ったっぽいので、ここを残して他は削除依頼を だします。すみませんです。
スレ立て荒らしの1をアクセス規制するよう要望板に報告してきます。
削除依頼出しました。
>>7 ありがとうございます。
マルチたんハァハァ
マルチのプログラムを作ってくれるのはこのスレですかっ!?
763復活希望
重複したのでこちらは「マルチすれっど対策プログラミング相談室」となります。 後の始末は削除な方々が行ってくれるでしょう。
↓この「移転したよ。。。」ってスレ何なの?
C/C++で、pthread_mutex_lock(...) した関数から抜けるとき、 unlock(...)することを保証するにはどうしたらよいでしょう? returnで返る前には自分でunlockしていますが、longjmpやthrow のときにはunlockされないので困っています。
C++なんかで保証させようと思う方が間違っている。
longjmpされると不可能だが、throwだと「全部catchする」っていう書き方がなかったっけ?
↑ブラクラ
>>18 throwならデストラクタは実行される。
つーかそんなの全然マルチスレッドに限った話題じゃない。
デストラクタじゃだめだと思うけど… 出るときにロック壊しちゃって委員会?
ちがう。コンストラクタでlock、デストラクタでunlockするオブジェクトを作 るってこと。 C++のidiomを知らないんならARMから読み直せ。
Cでは無理なんですね。 素直にJavaを使って書くことにします。
AutoLock { public: AutoLock() { lock(); } ~AutoLock() { unlock(); } }; F() { try { AutoLock autoLock; } catch (...) { throw; } }
>>28 そうだぞ。正しいunlock()の仕方なんてスレ違いだぞ。
>>30 マルチスレッドに限った話題じゃないが、マルチスレッド
プログラミングで必要な話題ではあるだろう。
なにが「カラアゲうまうま」だあほじゃねーの? えっらそーに。
また香ばしいのが虚勢をはってるなぁ 736 といい、こいつといい、このスレの伝統ですか?
38 :
デフォルトの名無しさん :02/11/20 18:10
俺の脳、処理能力低いので普段はシングル処理ですが、 仕事中だけマルチになります。 2ちゃんねるやったりwinMXでエロやアニメ落としまくったり私用のメールやりとりしたり 女子社員のいろんな妄想したり見つからないようにお菓子食ったり、 その合間に仕事したり
それはマルチタスクでしょ
class UnlockHook { pthread_mutex_t& lock; UnlockHook(pthread_mutex_t& l) : lock(l) {} ~UnlockHook() { pthread_mutex_destroy(&lock); } }; ... pthread_mutex_lock(l1); { UnlockHook hook(l1); .... // throw されるかも ... } これでhookのデストラクタがちゃんと呼ばれるんだろうけど、 いったいどうやってるんだろう? ひょっとして、throwってすごく遅い?
41 :
デフォルトの名無しさん :02/11/20 20:35
Ruby >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> C++
41から電波がゆんゆんです。
ママ:まぁ、パパったら。うふふふふ。 子供:あはははは。 パパ:わっはっは。これは傑作だ。
>>40 > ひょっとして、throwってすごく遅い?
つーか、重いデストラクタがいっぱい走る状況なら、return だけでもすごく遅いと思うが...。
>>40 重いかどうかは処理系によるけど、まあ想像つくわな。
でも想像でしかないわけで、最近での処理系でのオーバーヘッドって
どれくらいのもんなのだろう。
#include <stdio.h> #include <unistd.h> #include <sys/time.h> static void no_exception() { } static void use_exception() { try { throw 0; } catch (...) { } } static void eval(void (*p)()) { timeval before, after, r; gettimeofday(&before, NULL); for (int i = 0; i < 100000; i++) { p(); p(); p(); p(); p(); p(); p(); p(); p(); p(); } gettimeofday(&after, NULL); timersub(&after, &before, &r); printf("%ld.%03ld\n", r.tv_sec, r.tv_usec / 1000L); } int main() { eval(no_exception); eval(use_exception); return 0; } Athlon 1.4GHz g++ 2.96 -O2 0.004 5.579
optimized?
Win32 APIなんだけど、ここの人たちのほうが詳しそうなので教えて君させてください。 InterlockedExchangeとInterlockedExchangePointerってなにが違うんでしょう? InterlockedExchange If you are exchanging pointer values, this function has been superseded by the InterlockedExchangePointer function. InterlockedExchangePointer If you are exchanging pointer values, this function supersedes the InterlockedExchange function. 意味不明なんですが
よう! カスども元気か?
>>48 PVOIDとLONGのサイズが一緒じゃない場合があるからだろ。
M$の64ビット環境では、longは32ビットのままじゃなかったっけ?
>>50 そういう事ですか。さんくす。
64bitだと、intは32bitもしくは64bitでlongも64bitだと思ってました。
そういえば、LONG LONGなんてのがありましたね。
52 :
デフォルトの名無しさん :02/11/22 20:49
Ruby以外のsureddoは糞
sureddo・・・( ´,_ゝ`)プッ
お前らのマルチスレッドプログラムで、XeonのHyperThreadingで 劇的に速くなった香具師はいますか?
>>51 LONG LONGではなく、LONGLONGだね。
M$の場合は、longが32bitで、__int64が64ビット。
__int128なんかも予約されていたような気がする。
普通の64bitな処理系ではlongが64bit。
普通って何?
>>56 50=55の脳内処理系のことでしょう。
少なくとも普通じゃない。
LP64って慣習だったのか・・・
>>58 んじゃ、そうじゃない処理系挙げてみ。
64bit環境なら、SolarisもLinuxもTru64もHP-UXもlongは64bitだよ。
LP64は規格だよね。SUSの。
SUSって何? ローカル規格団体?
Single Unix Specification
>>54 CPU-boundな処理を2つのスレッドに分けるのはなかなか大変よ。
通常は分けるとしてもCPU-bound(ひとつ)、I/O-bound(ふくすう)
だからねえ・・・
並列アルゴリズムを応用するといっても、CPU数が高々4つだろうから
通信オーバーヘッドが目立つだけかも。
>>64 いや、SUSとPOSIXは統合された。だから標準に準拠したOSならすべて。
ちなみにWinNT, Win2kもPOSIX互換、と少なくともMSは主張してる。
なるほど、POSIX規格にLP64というのがあるんですね。 見たことないけど。
>>67 IEEE std.1003.1-2001 (POSIX V6)では、getconf nameとして
_POSIX_V6_ILP32_OFF32, _POSIX_V6_ILP32_OFFBIG,
_POSIX_V6_LP64_OFF64, _POSIX_V6_LPBIG_OFFBIG
が定義された。すべての処理系は、上の少なくとも1つをサポートしなければ
ならない。
69 :
デフォルトの名無しさん :02/11/24 02:08
>>46 Intel(R) Celeron(R) CPU 1.70GHz (RedHat Linux 7.3)
0.007
5.567
AMD-K6(tm)-III Processor (Sun Cobalt Linux)
0.028
12.291
C99 の long long int 型は・・・? long 型と一緒?
73 :
デフォルトの名無しさん :02/11/24 12:27
>>68 プログラミング環境 int long ポインタ off_t
_POSIX_V6_ILP32_OFF32 32 32 32 32
_POSIX_V6_ILP32_OFFBIG 32 32 32 >=64
_POSIX_V6_LP64_OFF64 32 64 64 64
_POSIX_V6_LPBIG_OFFBIG >=32 >=64 >=64 >=64
74 :
デフォルトの名無しさん :02/11/24 12:27
>>72 longはint以上の長さを持つ。
最低32ビット。
long longはlong以上の長さを持つ。
最低64ビット。
75 :
デフォルトの名無しさん :02/11/29 14:10
結局MSの64ビット環境は規格違反という事ね。
未対応と違反とでは全然違うだろう。
> ちなみにWinNT, Win2kもPOSIX互換、と少なくともMSは主張してる。
78 :
デフォルトの名無しさん :02/11/29 14:54
(´-`).。oO(完全互換と言い切っていない所がミソ。。。)
NTがPOSIXサポートしてるのは政府の入札を受けるためなんだから そんな半端なことしては意味がないと思うんだが
間違えた 1003.1:1990→1003.1-2001だ
間違えはいいとして、コロンはどこから出てきたんだ?
POSIXってどこまでサポートしてるのか明示しないと意味ないような・・・ linuxも完備してるわけじゃないし・・・
>>83 LinuxのどこがPOSIXじゃないの?
LinuxがPOSIX準拠だなんて誰か言ったっけ? これだから犬厨は・・・
86 :
デフォルトの名無しさん :02/12/01 02:02
Unifix Linux (旧称FT Linux)はPosix V4 compliantの認定を受けている。
他のディストリビューションは、
「やればできることは(FTのおかげで)わかったから、わざわざ金かけるまでも
ないや」ということで、認定は受けていないが、ほぼPosix-compliantと言ってよい。
>>85 犬厨って何?
>>85 >犬厨って何?
IME-onでlinuxと打つ。
→ぃぬx
>>87 はー、なるほど。Winな人が使う蔑称ってことね。
ま た 犬 厨 か 。
そもそも
>>83 が、何の関係もないLinuxを攻撃したのが
原因だな。
そもそも>何の関係もない>83が原因だな。
∧_∧ / ̄ ̄ ̄ ̄ ̄ ( ´∀`) < オナラモナー ( ) \_____ | | | (__)_)
93 :
デフォルトの名無しさん :02/12/01 11:19
結論: L i n u x 最 強
94 :
デフォルトの名無しさん :02/12/01 11:22
結論: i n a x 最 強
>>94 ハァ?
ウォシュレット最強は TOTO ですがなにか?
>>95 > ウォシュレット最強は TOTO ですがなにか?
そりゃ当たり前だろ。
「ウォークマン最強は SONY です。」と言ってんのと同じだよ。
ちなみに、シャワートイレ最強は INAX ですが、それが何か ?
とりあえずおまえらスレ違いです(w
>>97 ここはウンチスレッドプログラミングについて語るスレですが、何か?
糞をしながら小便が出るのはマルチスレッド処理だよな?
>>99 単にバッファが個別にあるだけと思われる。
排出自体は、DMA じゃねーのか ?
CPU からの命令ですぐ止まらないし...。
DMA = Direct Members of the body Access ですか?(ちと苦しいか)
ウォシュレット最強にしてみろ。 浣腸より痛いぞ。
ぶぁっはははははーーーっ!! TOTO が最強だって信じてる奴がこの世にいたのか!? ぶぁっはははははーーーっ!! ぶぁっはははははーーーっ!!
>>103 おまいは最強の
\ 馬 / \ 鹿 /
∩ ∩
| つ 「,"|
ヾ∧ !,'っ_ ⊂_,!
/ ・ |ミ / ・ ヽつ
(_'... |ミ ▼,__ |
(゚Д゚; )..|ミ (゚Д゚ ,)・|
(| .、)| (| 、)|
| | | ・・|
ヽ.._人 ヽ._・ν
U"U U"U
だな・・・。
微妙に荒れてきたげいいんは 93 か?
何の関係無いのは 83 のレスじゃなくて 83 本人なのか(w
正直どうでもいい
前スレはまともだったのにこんな糞スレに成り果てて。 お父さんは悲しいよ。
お母さんは実家に帰ります。
俺は家出します。
そしてお爺ちゃんは餓死。
俺の布教のおかげでマルチスレッドプログラムが激減したようだな。 よいことだ。
115 :
デフォルトの名無しさん :02/12/09 16:35
↓「おざなり」と「なおざり」の違いを述べよ。
ウリナラ
>>115 おまいは 「がいしゅつ」 とかもいちいち訂正するのかと
>>119 2 ちゃんねるでは
× きしゅつ
○ がいしゅつ
× げんいん
○ げいいん
だからよろしくな。
ぶぁっはははははーーーっ!! がいしゅつか間違いだと思っている奴がこの世にいたのか!? ぶぁっはははははーーーっ!! ぶぁっはははははーーーっ!!
>>121 × がいしゅつか間違いだと思っている奴がこの世にいたのか!?
○ がいしゅつが間違いだと思っている奴がこの世にいたのか!?
123 :
デフォルトの名無しさん :02/12/10 00:17
Windowsは最新のXPでも、dual processor対応は個々のアプリが 最適化されなければいけないそうですね。 OSXならば、OSX対応アプリならdual processorに標準対応ですな。
だまれ
うまれ
こまれ
>>123 はいはい、よかったですね。
満足したら、MAC 板に帰ってくださいね。
OSXって言ってもただのUnixだろ? シングルスレッドのアプリが自動的に速くなるわけがない。
ハァ? Appleの技術力をナメてませんかぁ? NEXT時代から培ってきた技術は、今、最高の時期を迎えています。 そんなマックをただのUNIX呼ばわりする馬鹿は、逝ってよしってことです。
でも、結局 Unix のパクリだろ。
だって、ただのFreeBSDだもん…
どうせただのぬるぽだろ。
シングルスレッドのバイナリをソフトで自動的に マルチスレッド実行するOSなんてあるわきゃない。
古い68Kアプリをマルチスレッド実行してくれたりして
>>133 自動的に排他制御と同期を挿入して…なんて確かに不可能だね。
>>134 マルチプロセスだろ。
そう設計されてない限り、マルチスレッドにする事はできない。
MAC OS X を馬鹿にするつもりは無いが、 132 と 129 は大いに馬鹿にしたい。
すまん。123。 でも、132 を馬鹿にしたいというのも正しいw
>>133 「ハードで」ならマルチスレッド化は可能?
>>140 2Pとか3Pとか乱交とかそういう意味だろ?
インテルのHTってチムポが2本になるんだよな?
>>141 その通り。
おまいの脳内においてのみナー。
>>139 MultiscalerとかSKYとかの事を言ってるなら、
あれも「自動マルチスレッド化」ではない。
どの処理を並列実行できるか解析して自動的にマルチスレッド化してくれる OS、 いやせめてソースのトランスレータでもあれば随分ありがたいな。 ・・・ほとんどあり得ないと思うけど。
プログラムがソースコードあるいは中間コード形式で配布されるようになれば、 並列最適化しながら実行することもできる・・・ かもしれない
>>145 まさか。だったらJavaでできてるはず。
C++でマルチスレッドを扱っているのですが、 クラス関数をスレッドとすることはできないのでしょうか _beginthread(&LoadCharacterData, 0, NULL); とやると error C2276: '&' : 仮想関数のアドレスを取ろうとしました。 と起こられてしまいます
>>147 static関数にインスタンスのポインタを渡して、そっからメンバ関数を呼ぶ。
(´-`).。oO(微妙にマルチスレッドとは違う話だな。。。)
> ・・・ほとんどあり得ないと思うけど。 つまり、人間に最適化できるならコンピュータにも最適化させる事ができるという事だ。 誰か挑戦する猛者は居ないか?
>>145 ネタとしては面白いので
最近の研究事例をひっぱってくれ
>つまり、人間に最適化できるならコンピュータにも最適化させる事ができるという事だ。 人間もチューリング等価だと?
つまりたとえば、 for( int i = 0; i<max; i++ ) sum += f(i); とあったら、(f(x)は数学的関数) t1:for( int i=0; i<max/2; i++ ) { tmp = f(i); lock(sum); sum += tmp; unlock(sum);} t2:for( int i=max/2; i<max; i++ ) { tmp = f(i); lock(sum); sum += tmp; unlock(sum);} に自動分解するソフト?
並行プログラミングの話題か
自動解析むの話だから、プログラミングは関係無い。
>>153 そんなのはFortranのコンパイラがとっくにやってる。
Fortran が最強という事でよろしいか?
158 :
デフォルトの名無しさん :02/12/17 04:33
Windowsで、 _beginthreadex とかで指定するスタック領域を増やすのと、 TLS(Thread-Specific Storage)使うのはどっちが効率がいいのでしょうか? buffer領域の場所を使うバッファにいちいち教えてあげる TLS は 面倒なので、効率が変わらなければ、スタック領域の方が便利なような気がします。 誰かおしえてちょ。
159 :
デフォルトの名無しさん :02/12/17 05:42
>>6 マルチスレッドなんだから
スレがいくつか平行に存在してていいじゃないか。
>>158 TLS はそういうものじゃないし、効率はスタックの方がいいよ。
そもそも 158 の考えている使い方なら TLS なんかいらないでしょ。
>Thread-Specific Storage Lどこー?
>>158 TLSって
Thread Local Storage
じゃなかったのか?
呼び名が混じってるな TSD Thread Specific Data - pthread TLS Thread Local Storage - Win32 どっちも同じもの。
>>158 160は不親切だったので追記する。
TLS は unix だと signal ハンドラやら、windows だと hookproc の中やら、
現在実行中のスレッドがよーわからん&引数として(スタックフレームで)適当な
データもよう使えんときに、スレッド毎に必要なデータを使うためにある。
マルチスレッドじゃなければ(他に手立てが無くて)グローバル変数を使うような場面ね。
使わないで済むならもちろん使わない方が良い。keep it simple って観点で。
WindowsではTLS使用数に限界がある場合があるので 可能な限り使わない方がよい
UNIX板GCCスレによれば、iaのみでだけどTLSサポートだそうな ただしVCのようなコンストラクタのあるオブジェクトを置けない 制限がどうなっているのかは不明。
167 :
デフォルトの名無しさん :02/12/17 14:37
「WANT YOU!!」
昨年、2ちゃんねるにおいてタシロ祭りを巻き起こした
「TIME誌 Person of the Year」投票。
ところが昨年の投票に懲りたのか、TIME誌は投票可能な人物を
あらかじめ設定するという方法に出てきました。これは黙っていられません。
2ちゃんねらーの力で、彼ら米国人が最も無視したい人物
「Yasser Arafat」アラファト議長を表紙に!!
ところがここに邪魔をする一つの謎の集団が突如現れました、
彼等はこともあろうに現イスラエル首相、シャロンに一斉砲撃を開始!
瞬く間にアラファトを蹴落として首位の座に君臨しました。
その強烈な攻撃は、ユダヤ勢力対2ちゃんねらという構図を予想させ、
戦いは一時、圧倒的な差を以てシャロンの完全勝利として終結しつつありました
しかし、我々は諦めずに抗戦。現在、じわりじわりと反撃の炎が立ち上り始めています。
今ならまだ間に合います。
勇気ある君の一票が伝説になる!
http://live.2ch.net/test/read.cgi/festival/1039909795/
>>165 ハァ?
普通に使ってる限り足りなくなることなんかないだろ。
まさか個々の変数に対して割り当ててるんじゃないよな?
>>168 Windows2000以降では制限が緩くなったが
それより古いOSでは1プロセスあたり64
TLSを用いるDLLを多用するとまずい
普通に使ってる限り足りなくなることはないということは同意
でも
>>158 みたいなことをしていれば足りなくなる可能性もある
フライング方式に見えて一瞬何の事かわかりませんですた
172 :
デフォルトの名無しさん :02/12/26 01:56
printfの遅さで、挙動が変わるような通信アプリ のデバッグってどうやればよいのでしょうか?
>>172 それって
前スレとか前々スレとかで見かけた気がするぞ。
ネタか?
マルチスレッドと何か関係あるのか?
たしかに以前のスレで見た気がするな。 ネタじゃねえの。
177 :
デフォルトの名無しさん :02/12/30 19:47
作られたスレッドから、さらにスレッド作り出しても問題無いですか? 入れ子みたいにするのマズイですか?
マズイない
179 :
デフォルトの名無しさん :02/12/31 11:54
>>133 OS板のBeO信者はパーヴァシブスレッドっていったかなんだか忘れたが、
できると豪語してたぞ。ただの電波かもしれない。
>>179 確かBeのウィンドウアプリはデフォルトでスレッド2・3本作ってるって
話を聞いたけどそのことじゃないの。
ランタイム部分をマルチスレッドにするのは別に難しい事じゃないと思われ。 っていうか、それで速度的に有利になる状況というのがあんまり考えられないけど。
>>180 MFCだってMTでコンパイルすればウインドウくらいは
そうなってんじゃないの?
183 :
デフォルトの名無しさん :02/12/31 16:35
/MT でって事? ・・・・・こりゃ晒し上げかな?
COMなら勝手にスレッドを生成するが
>>182 C Runtime が MT Safe になるだけ。
186 :
デフォルトの名無しさん :03/01/01 07:18
NTのアプリだと常に2本のスレッドが生成されるんじゃなかった? たしかWin32マルチスレッドって本に書いてあった。
>>186 それはOS側のメッセージディスパッチャ内部で起動されるスレッドの
話であって、アプリがマルチスレッド化される話とは別。
つか、タスクマネージャでスレッド数見りゃ分かるやん。
>>180 そうやって複数のスレッドをいきなり立てたって、それぞれを何に使うんだ?
真にアクティブなオブジェクトとして、それぞれのオブジェクトが 活動するのですよ。
プログラム中のどのバイナリコードとデータ構造がオブジェクトかが、判別がつく と言うのか? どうやって?
電波発言は板違いです★
Win32ですが、クラス内で public: static void Thread(void*); とスレッド関数を作って内部で呼び出しても大丈夫でしょうか?
パケットモニタソフトを作っているのですが、 ネットワークアダプタが複数ある場合、アダプタ毎にWSARecvするので マルチスレッドを考えてるのですが、この場合マルチスレッドは必要ないでしょうか? 複数アダプタが検出された場合、クラスラッピングしておけば用意に必要本数ができるので上記の質問をしたのですが 何分知識不足で的外れな質問かもしれません・・ 後、和書か訳本でマルチスレッドのお勧めの本とかありましたら宜しければ教えてください。<(_ _)>
IP記録実験
http://qb.2ch.net/test/read.cgi/accuse/1042013605/ 1 名前:ひろゆき ◆3SHRUNYAXA @どうやら管理人 ★ 投稿日:03/01/08 17:13 ID:???
そんなわけで、qbサーバでIPの記録実験をはじめましたー。
27 名前:心得をよく読みましょう 投稿日:03/01/08 17:20 ID:yL/kYdMc
SETTING.TXT管轄でないということは全鯖導入を視野に、か?
38 名前:ひろゆき ◆3SHRUNYAXA 投稿日:03/01/08 17:22 ID:rLfxQ17l
>>27 鋭いです。
73 名前:ひろゆき ◆3SHRUNYAXA 投稿日:03/01/08 17:27 ID:rLfxQ17l
>ところで、IPが抜かれて何か今までと変わることってあるのでしょうか?
・今までより、サーバが重くなる。
・裁判所や警察からの照会があった場合にはIPを提出することがある。
>>73 * ※ ☆ ※ ※ ※ ☆ ※ *
* ※ ☆ ※ ※ ☆ ※ ※ ☆ ※ *
* ※ ☆ ※ ※ ☆ .☆ ※ ※ ☆ ※ *
* ※ ☆ ※ ※☆ ☆※ ※ ☆ ※ *
* ※キタ━━━━━(゚∀゚)━━━━━ !!!※ *
* ※ ☆ ※ ※☆ ☆※ ※ ☆ ※ *
* ※ ☆ ※ ※☆ .☆※ ※ ☆ ※ *
* ※ ☆ ※ ※ ☆ ※ ※ ☆ ※ *
* ※ ☆ ※ ※ ※ ☆ ※ *
AA貼り付けそうな予感
/\ /\ /:::::::ヽ____/::::::::ヽ、 丿 ::.__ .::::::::::::: __ ::::ヽ_ / /。 ヽ_ヽv /: /。ヽ ::::::ヽ -┼- 丿~~~| / / ̄ ̄√___丶  ̄ ̄\ ::::| ■ ■ -┼- /~~~~/ ━━━ | .:::::::::: / / tーーー|ヽ ..::::: ::|━━━━━━ ▼ ▼ .| 丿 | .:::::. ..: | |ヽ ::| ● ● | ::: | |⊂ニヽ| | :::::| \ / /| : | | |:::T::::| ! .::| \ \\ / / \: ト--^^^^^┤ 丿 \\\ \\\ お、大阪・・・・
こないだの2ちゃん敗訴で日本で大規模な匿名掲示板を運営することは事実上不可能になってしまったからなぁ
x-beat.comですた。
エロ系の発言っていうより、炉利だろおめー
======2==C==H======================================================
2ちゃんねるのお勧めな話題と
ネットでの面白い出来事を配送したいと思ってます。。。
===============================読者数: 138720人 発行日:2003/1/9
年末年始ボケがそろそろ収まり始めた今日このごろのひろゆきです。
そんなわけで、年末に予告したIP記録ですが実験を開始しています。
「2ちゃんねる20030107」
こんな感じで各掲示板の最下部に日付が入ってるんですが、
20030107以降になってるところはログ記録実験中ですー。
んじゃ!
────────────────────────Age2ch─
■この書き込みは、Age2chを使って配信されています。
────────────────────────────
Keep your thread alive !
http://pc3.2ch.net/test/read.cgi/software/1041952901/l50 ────────────────────────────
>>28 違います。判決は訴状送達の翌日(初日不算入の原則)からとしてます。
ビビる大木ってホントつまんないよな 面白くないってだけじゃなくて嫌悪感を憶えるよ はたして大木目当てでチャンネル合わせる香具師なんかいるのか? 石橋もパクリばっかで中身ないけど 大木も負けず劣らずつまらん こんなのは全然別の仕事定年までして からくりビデオレターくらいなら出してやってもいいが わざわざ金払って画面に出す意味がワカラン 事務所はコイツのどこが面白くて契約したんだ? 下積みテキトーにやれば芸無しが画面に出れるという 前例を作ったらいかんよ あんなの一生前説レベルだろ それでも客が不機嫌になる弊害は避けられない
ともあれ、 2ch の インターネットイノベータ・インキュベータ としての役割は終焉した。 昔は井戸端会議の戯言として(いわゆる”便所の落書き”として)失笑されていたのに 今では規模的に(判例でも)”社会に影響を与えるメディア”として扱われる存在になった。 つまり、ホントは昔から違法性はあったんだけど目立たなかっただけ、ってこと。 ⇒あまりにも 公序良俗 からかけ離れたサイト、それが 今も昔も 2ch の実態。
1chみたいにログ流出だけは避けてくれればとりあえずはいいかなと。 しょうがないでしょう、このご時世。
キニシナイ
かちゅがいつの間にやらNGワード対応になっとる…知らんかった。
警察、裁判所の世話になる書き込みをしなきゃいいだけの話だろ IP記録する事で基地外の書き込みが減るだろうから、なにも困る事はないだろう?
全ての板ってことっすか?
今回の件で言論の自由さえも脅かされることになるかも 誰も何も言えない時代が来そうな伊予柑
匿名掲示板の意味を履き違えてる人が多くて萎える。
腐れはおもしろいときとつまらないときの差が激しいな。
======2==C==H======================================================
2ちゃんねるのお勧めな話題と
ネットでの面白い出来事を配送したいと思ってます。。。
===============================読者数: 139038人 発行日:2003/1/10
なにやら、連日メルマガだしてるひろゆきです。
そんなわけで、ログ記録実験ですが、いちいちサーバ指定するのが面倒なので、
全部のサーバに入れてみました。
重くなって落ちたりしてもご愛嬌ってことで。。。
んじゃ!
────────────────────────Age2ch─
■この書き込みは、Age2chを使って配信されています。
────────────────────────────
Keep your thread alive !
http://pc3.2ch.net/test/read.cgi/software/1041952901/l50 ────────────────────────────
名誉毀損は事実であるかどうかは関係ないよ 気をつけてね
今までもIPが割れることなんか気にせずカキコしてたからどでもいい。 そのうちチャンとチョンには宣戦布告しなきゃならんと思ってた。
わからないが、IDからIPを抜くらしいな。 まぁ、ひろゆきが実際そういうことしてたとは思えないが。
┨←なんでこれ付けないの?→┠
残念ながら、2chは匿名性以外にも存在価値ができてしまったインターネットです。
意見を聞いてもらうために「次スレたってないようなのでこちらに」は やめろ。
別に今まで通り書き込みは減らないよ せいぜい厨や変なこぴぺが減るぐらいで議論はなくならない。 別に変にビクツク事ないじゃん。
あと5分以内やね(^_^;)6億
て
( ゚Д゚)空気読めよ、山系!
最高裁への上告は認められなくなったから、これで事実上判決確定だよ。
逆転も何もないって。
勢いで上告なんかしても一発で上告却下(門前払い)だよ。
二審も一審を支持。これに対して上告しようにも、
刑事訴訟と同様、自由に上告できるってもんでもないのです。
民事訴訟法312条 (上告の理由) 1項
「上告は、判決に憲法の解釈の誤りがあること
その他憲法の違反があることを理由とするときに、することができる。」
http://www.m-net.ne.jp/~doba/goto/hon.htm ようするに上告しても今の制度では100%無駄。
これで完全終了ってことか。
> ちなみにWinNT, Win2kもPOSIX互換、と少なくともMSは主張してる。
コピペ?
620 と 623 は別人ですが何か?(w いや、ごめん。どうせループだから、公開トリップ使って遊んだだけ。本当にごめん。
ハソコン初心者だがアケ板見れるけど?
232 :
名無しさん@XEmacs :03/01/12 21:41
>>193 > マルチスレッドを考えてるのですが、
すればいいじゃん。その方が自然だし。
(^^)
既出です
(^^)
236 :
デフォルトの名無しさん :03/01/18 08:18
何課あちこちのスレでスレと関係無いカキコが多いなー
NullPointerException が発生したら 「ぬるぽ」 と出力するようにしますた。
(^^)
242 :
デフォルトの名無しさん :03/01/27 00:53
HTA(JScript)でActiveXコンポーネントを利用して ダウンローダを作ろうとしてます。 IEコンポーネントにURLを渡してhtmlファイルをDLすると 大量のURLがDL対象だと時間がかなりかかってしまいます・・。 そこで、複数のURLを配列に入れて、その配列を引数で渡したら マルチスレッドで、それらのページ(画像とかじゃなくhtmlファイル)を うりゃ〜っと高速DLしてくれるようなActiveXが作りたいのですが、 何をどうしていいのやら・・。 ・このActiveX作成に最適な言語 ・参考となりそうなサイトor書籍 ・ヒント全般 ・答え など、教えていただけないでしょうか?
> うりゃ〜っと高速DL ( ゚д゚) ポカーン
OpenIrvineのソースでもみれば?
マルチスレッド化するだけで劇的に速くなると思ってるのだろうか? レスポンス待ち時間の分くらいしか速くならないのに。 むしろ、コネクション数をうまく調整しないと却って遅くなるぞ。
CPU8個積んでますが何か?
254 :
名無し@沢村 :03/01/28 01:32
>>246 無効の竹垣に竹立てかけたのは竹立てかけたかったから?
258 :
名無し@沢村 :03/01/28 23:58
このスレは今から、
「
>>246 に取りあえずレスするスレ」
になりますた
>>246 259 が 246 に対してレスしてないよ?
261 :
デフォルトの名無しさん :03/02/11 15:22
gcc2.95.2(g++)使ってマルチスレッドプログラミング( in Linux or Solaris) basic_stringってthread-safe?
ソース見ればいいのに つかstd::でスレッド安全性を考慮したものってあるのか?
263 :
デフォルトの名無しさん :03/02/12 00:53
ソースなんか見る必要はない headerみれば乗ってる。 mapやvectorはスレッドセーフにできそうだが
ヘッダもソースの一部かと・・・ まだCの癖が抜けてないのかな
>>264 挿入や削除ですぐ反復子が無効になるSTLをどうやったらMT-safeにできるのか
考えてみてくれ。現在並みの性能要件と機能性を満たした形で、
本当にできると思ってるの?
例えばthread Aとthread Bで同じコンテナインスタンスの反復子を
それぞれいじくっても平気か、ということだ。
メインスレッドがBeginPaint()を実行して サブスレッドがGetDC()を実行して サブスレッドがGetDC()を実行しても いいのでしょうか? これらのAPIは、裏で排他処理をしていますか? それともプログラマが排他処理をするべきですか?
>>267 Win32と仮定するが、オブジェクトによっては、それを作成した
スレッド以外のスレッドからのアクセスを禁止しているものがある。
通常は明示されているが、それぞれについて調べるしかない。
記述がない、確証がない、バグの原因になりそうならば、
排他するしかないだろう。
>>268 Win32です。
質問が下手だったです…
えと、メインスレッドではWM_PAINTに応答を
しています。
ワーカースレッドで計算処理をしています。
この計算処理をすぐに表示したいときに
どうしようかなと…
ワーカースレッドでGetDC()をしようと思った時に
メインスレッドがWM_PAINTに応答しているかどうか
チェックするべきなのでしょうか?
私の勝手な予想だと、BeginPaint()がロックしているので
GetDC()が少しの間待機していて、EndPaint()が終了したら
GetDC()の待機が解けてGetDC()が成功するのでは…と
思っています。
ワーカースレッドが複数あったら、GetDC()の
取り合いが起きそうだけど…あっていますでしょうか?
GetDCとマルチスレッドの関係について調べたか? 調べてからにしてくれ。
ワーカースレッドで表示まで一緒にやらせようってのがそもそも
> メインスレッドがWM_PAINTに応答しているかどうか > チェックするべきなのでしょうか? 応答してないような時にはきっと、描画なんかしてちゃいかんのだろうな。
ヘルプのマルチスレッドのところ読んできたよ… >To enhance performance, access to >graphics device interface (GDI) objects >(such as palettes, device contexts, regions, and the like) >is not serialized. もしやるとしたら、自分で排他処理をする必要があるのね… おれ、BeginPaint()やGetDC()で得るデバイスコンテキスト(DC)って GDIオブジェクトとは別だと思ってた ペンとかブラシとかのグループとデバイスコンテキストのグループと >ワーカースレッドで表示まで一緒にやらせようってのがそもそも MsgWaitFor系の関数でメインスレッドで処理をするのでしょうか? だったら自分の質問Tってかなり変だったのかな…
描画は単一のスレッドでやったほうがいいと思うズラ
>>275 > >ワーカースレッドで表示まで一緒にやらせようってのがそもそも
の続きは
「マルチスレッドにする意味がない。」
> MsgWaitFor系の関数でメインスレッドで処理をするのでしょうか?
> だったら自分の質問Tってかなり変だったのかな…
メインスレッドとワーカースレッドでどういう情報をどの程度やりとりするか
によると思うが。ワーカーからなにか能動的にメインに投げる必要があるなら
イベントループに組み込むだろうし、そうでなくて単に途中経過を脇から取り
出すだけなら(CriticalSectionで保護して)変数を共有するだけで済むかも知
れないし。
こまれ
ゴマドレ
280 :
デフォルトの名無しさん :03/03/28 19:28
保守アゲ
> >error C2664: '_beginthread' : 1 番目の引数を 'void (void *)' から 'void (__cdecl *)(void *)' に変換できません。 (新しい機能 ; ヘルプを参照) > スコープ内でこの名前を持つ関数でターゲット型に一致するものはありません。 > vc6でこのようなエラーが出ました。 で、関数なのですが、テンプレートなのです。 template < typename TYPE > void __cdecl Thread( void* p ){} main() { ::_beginthread( Thread< bool, bool >, 0, &thread ); } テンプレートは使えないのでしょうか?
bool がひとつ余計でした
283 :
デフォルトの名無しさん :03/04/03 02:00
質問なのですが256MBの領域を確保して、それを0で初期化するルーチンを 高速化しようと思い、2つのスレッドで半分ずつ初期化しようとしています。 しかし、成功するときも多いのですが、5回に1度くらい、WaitForSingleObject()で スレッドの終了を確認できず固まってしまいます。 どこが悪いかご教授いただけないでしょうか? Windows2000 Pro, Athlon MP 1900+ * 2 の環境です。
char *bmp_table_smp[4]; // 分割して初期化するときの先頭ポインタ int bmp_table_smp_size; // 個々のサイズ void *BmpTableInitSMP(void *id) { memset(bmp_table_smp[(int)id],0,bmp_table_smp_size); return 0; } void BmpTableClear(void) { HANDLE pt[4]; // スレッドのハンドル int size,max_thread = 2; size = BMP_TABLE_SIZE*sizeof(BMP_TABLE); bmp_table = (BMP_TABLE*)malloc( size ); bmp_table_smp_size = size / max_thread; if ( bmp_table_smp_size * max_thread != size ) { printf("Size is odd!\n"); exit(0); } for (i=0;i<max_thread;i++) { bmp_table_smp[i] = (char*)bmp_table + bmp_table_smp_size*i; } for (i=0;i<max_thread;i++) { pt[i] = (HANDLE)_beginthread( (void(__cdecl *)(void *))BmpTableInitSMP,0,(void *)i); } for (i=0;i<max_thread;i++) { WaitForSingleObject(pt[i], INFINITE); printf("pt[%d] thread end.\n",i); } }
>283 分割したら遅くなると思うが、、、 いまどきはCPU2つ以上が基本なのか?
void *BmpTableInitSMP じゃなくて __cdecl void BmpTableInitSMP では。
>>285 1CPUだと256MBの初期化に0.50秒かかるのですが2CPUだと
0.43秒ぐらいになります。何度も呼ばれるので少しは効果が
あると思って。それにP4とかはHTがあるのでひょっとして
効果があるかも。
自業自得
beginthreadex()を使うように変更したら まったく固まらないようになりました。 お騒がせしました。 何が違うんだろ・・・?
クローズしたスレッドハンドルを操作したら どうなるか想像もできないのか コードも汚いしスレッド以前の問題だ
なんだライブラリのバグか。
>>294 この場合、_beginthreadと_beginthreadexの動作の違いは何故?
_beginthread っつうのは要するに、スレッドが終了されるとスレッドハンドルを 勝手に CloseHandle() するんだろ。
HT-P4では速くならんと思う MMXでも使ったほうがよくないか?
0fillごとき最適化してどうするよ。 どうあがいてもバス速度がネックになるわけだし、 気にするだけ無駄だって。
何度も呼ばれるって言ってんじゃん
バス速度がネックになるから何度やっても同じっしょ
>>281 cppllのログかどこかで読んだだけでしかとは覚えてないのだけど、
VC6はそういうテンプレートを正しく処理できないそうだ。
template < typename TYPE > void __cdecl Thread( void* p, TYPE dummy){}
とかいう風にダミーの引数を持たせて回避するんだったかな???
でもこの場合にそんなことしたらますます駄目だし…、
そうだ!こうやっておいてキャストすればうまくいったりしない?
template < typename TYPE > void __cdecl Thread(TYPE* p){}
>>302 そういうウザいネタはアセンブラスレでやってね。
ハァ?
>>304 そういうウザいネタはハァ?スレでやってね。
しかしアセンブラ以外ではベンチはいらんのですか そうですか
303は一生バブルソートでも使ってろ
まあ、最適化でバス速度を超える速さでメモリアクセス出来たら奇跡だよな。
マルチスレッドで並列に書き込んだら、キャッシュ乱れてバス帯域有効に使えんわな。 CPU特化memset, loop unrolling, word/cache alignmentが王道で、スレ違いだわな。 freeの速いmemsetたくさん転がってるよ。sizeも固定みたいだから選択肢たくさんあるよ。
つか、実際に多少なりとも速くなっているのに、バスが云々、と 言って取り合いもしないのは甘ちゃんだな、てめーら。
速くなってるって、、、本当に速くなってるの?計測の方法は正しい? 283でてこーい。 速くなったとして、どういう理由なのかはちょっとだけ知りたいかも。 ただ、キャッシュ込みのバス調停は、アーキテクチャに依存しまくりなので 一般的な結論を得ることは難しいかも。
個人的見解だと、メモリ共有アーキテクチャの場合は多プロセッサで寄ってたかって memset するのは効率的でないと思う。 別のアプローチとして、MMX を使ったら memset の 114.6% の速度になった。 (Athlon XP + DDR-SDRAM)
>>309 最近のCPUにはキャッシュ制御系の命令もあるから、キャッシュ汚染の問題は
回避できるかと。(そうしたところで速いかは知らんが)
今時のAT互換機だと、キャッシュはCPU側にしかないからこの場合のプロセッサ間のキャッシュ汚染の心配は無いんじゃないの? 2CPUで速くなる理由としては、マルチタスクOSでは他のタスクを実行する時間もあるわけだし、1CPUではメモリバスの書込みサイクルをフルに使っていないんだと思う。 P4-HTはパイプラインと実行ユニットにアイドルが発生するプログラムどうしを並列して食わせるから速くなるわけで、0fillだと速くならないと思われ。 キャッシュも汚染するし。
同じCPUで実行しちゃうと、 cacheのentryの奪い合いが始っちゃうと思われ
316 :
デフォルトの名無しさん :03/04/14 13:17
bool Thread::begin() { if (handle_ && WaitForSingleObject(handle_, 0) == WAIT_TIMEOUT) { // Error: 前のスレッドがまだアクティブ return false; } if (handle_) { // 前のスレッドは終了しているのでハンドルを閉じる CloseHandle(handle_); } // 新しいスレッドを生成する handle_ = (HANDLE) _beginthreadex(.....); return handle_ == NULL ? false : true; } このようにして、最初の begin() 呼出しで立ち上がったスレッドが アクティブである間は、2度目以降の begin() の呼出しをブロック したいと考えています。 そこでなんですが 2度目の begin() 呼出しの時点で最初のスレッドが まだ生成されておらず結果 WaitForSingleObject が WAIT_TIMEOUT 以外の値を返す可能性はあるでしょうか。
handle_ってメンバ変数? 排他をちゃんとやらんといかんような・・・ そこから考えてみるといいかもよ
handle_はインスタンス変数? race conditionではありうるかもね。
begin()全体をクリティカルセクションで囲め
320 :
デフォルトの名無しさん :03/04/14 15:46
>>316 ないよ。
ハンドルが得られた時点で、タイムスライスが割り当てられているか
否かはともかく、スレッドは生成されていて、waitable になってるから。
ただし排他は必要。
>>317-320 皆さんありがとうございます。handle_ は
class Thread {
HANDLE handle_;
となっていてコンストラクタで NULL に初期化されます。書き忘れ
失礼致しました。
_beginthreadex() が成功した時点でそれが保証されるんですね。
うまく行くということだと助かります。必要な排他処理というのは
begin() の入口と出口のことですよね。
この二つに分割して考えた方が分かりやすいんじゃ… (1)スレッドが終了したらスレッドのハンドルを閉じる (2)前のスレッドのハンドルが有効なら次のスレッドを開始しない
>>316 begin()を呼んでいるスレッドが複数あったりすると、それでは問題あるね。
まぁ、そんな実装しないと思うけど。
(^^)
∧_∧ ( ^^ )< ぬるぽ(^^)
保守
327 :
デフォルトの名無しさん :03/05/01 07:02
ho
328 :
デフォルトの名無しさん :03/05/01 16:16
ちょいと質問させてくだせえ。 pthread_createと、pthread_joinくらいしか使っていない プログラムを作っているのですが、 RedHat9.0でcompileすると実行時にcoreを吐いてしまう、ないし挙動不審です。 #RedHat8.0とかその以外のdistribution(Debianとか)では大体機能します。 うまくいく環境 (redhat 8.0) gcc 3.2, glibc-2.2.93-5 マズーな環境(redhat 9.0) gcc 3.2.2, glibc-2.3.2-11.9 プログラムには、 C++をベースにしていて、socketにはselectシステムコール使用してます。 #きちんとスレッドセーフを確認していないので、buggyだとは思います。 どこかクリティカルに問題が起こしているか、見当をつけたいわけです。 アドバイスをお願いします。ぜひに……
thread 使うなら select は使わない。
>>328 状況もわからんのにどんなアドバイスを期待してんだか...。
とりあえず、スレッド間で共有しているリソースを洗い出すことからはじめたらどうよ。
あと、core がでてんなら、直接的な原因はわかるだろうからそこから逆に追っていけばいいんでは ?
>329 select併用すると駄目っすか? #selectを使わずに #network受信待ちを解除する(timeoutさせる)代替手段ってどんなのあります? >330 >とりあえず、スレッド間で共有しているリソースを洗い出すことからはじめたらどうよ。 ループを続行するか否かのbool変数くらいしかないのですが、 そんなもんでもリソース食い合うとマズいのでしょうか? >あと、core がでてんなら、直接的な原因はわかるだろうからそこから逆に追っていけばいいんでは ? libc6絡みでcore dumpしたというメッセージが表示された記憶がありますが、 ちょっと詳しいこと分からないです。 RedHat9.0からNPTLが採用されているので、それ絡みかな、とか思ってました。 (それ以前のバージョンは問題なく動いていたので)
>>331 > #selectを使わずに
> #network受信待ちを解除する(timeoutさせる)代替手段ってどんなのあります?
read()をSIGNALで止めるってのはできなかったっけ。EINTRで戻って来ないか?
> >あと、core がでてんなら、直接的な原因はわかるだろうからそこから逆に追っていけばいいんでは ?
> libc6絡みでcore dumpしたというメッセージが表示された記憶がありますが、
> ちょっと詳しいこと分からないです。
詳しいことはcore(とgdb)に聞け。
>>331 > libc6絡みでcore dumpしたというメッセージが表示された記憶がありますが、
> ちょっと詳しいこと分からないです。
正直そんな事でマルチスレッドのデバッグができるとは思えない。
悪いけど、ネタと見なして以下スルーするよ。
334 :
デフォルトの名無しさん :03/05/03 19:12
>329-330 >332-333 レスありがとうございます。(ほんま素人ですんません) とりあえず、問題となっている部分が特定したのですが…… (signal 11 で segmentation fault起こしてました) プログラムループの周波数を調整するのに、 signal, setitimer, sigpause 等を使っていたのが原因でした。 10ミリ秒単位でスリープかけるために、signalを使用していたのですが、 何とかpthreadとうまく共存させる方法、 もしくは目的と達成する代替手段はないものでしょうか? この辺、きちんと理解・解決するための、 何か良い資料等ございましたらお教えいただけないでしょうか?
335 :
bloom :03/05/03 19:13
usleep?
usleepよりは nanosleepの方がいいような。
>>334 > signal, setitimer, sigpause 等を使っていたのが原因でした。
自分のプログラミングのせいじゃないと主張なさるわけか?
>>334 > 何とかpthreadとうまく共存させる方法、
仕様に従ってきちんと使う。
>336-337
usleepを使った場合の精度が気に入らなくて、
強引にsignalを使っていたのですが、
ttp://www.linux.or.jp/JM/html/LDP_man-pages/man2/nanosleep.2.html >nanosleep はより高い精度の停止も可能である。
>もしプロセスが SCHED_FIFO や SCHED_RR のようなリアル・タイム方針の元でス
>ケジュールされているならば、 2 ms 以下の停止ができ、
nanosleepは、2ms以下で制御できるのですね。知りませんでした。
試してみます。ありがとうございました。
>338-339
>signal, setitimer, sigpause 等を使っていた*自分の不勉強*が原因でした。
と字間を補足しますよ。POSIX準拠ちゃんと調べます。
正直、だいぶ昔に作ったパーツの使い回しだったので
この辺の問題、すっかり忘れてました。
メンドッチイネ
timeGetTimeを複数のスレッドで使いたいんですが その場合timeBeginPeriodを そのスレッド数分やるべきでしょうか? それともどれかのスレッドで一回だけやれば十分?
>344 一応、一回で十分。 timeBeginPeriod() はスレッドをまたいでも有効。 それどころか、プロセスをまたいでも有効。
>>344 何やるのかしんないけど、この辺は極めて怪しげ仕様なので、MSDNを熟読のこと。
というかMSDNさえ信用できない世界だ timeBeginPeriodでぐぐるとサイトによって相反することが書いてたりするし
この場合MSDNに書いてあることがすべてだろ。 マルチスレッドだろうがなんだろうがtimeBeginPeriodを使ったら それに対応するtimeEndPeriodを呼ばなければならない。 一回最初にやって複数スレッドで使いまわすなら、 すべてのスレッドが終わった後で最後にtimeEndPeriodを一回呼べばよい。 なんか実験してるサイトもあるが、みた感じ日本語のサイトはどれも 場当たり的で参考にならない。ゲーム系のプログラマってみんな あんな感じなのか?
349 :
デフォルトの名無しさん :03/05/10 16:30
>>349 > UNIXのマルチスレッドプログラミングの勉強をしようと思うのですが、
> 私のレベルは、ようやくスレ立てと削除依頼が出せるようになった程度で
> ageとsageをうまく使いこなせません。
ネタと言うことで良いか ?
> 負荷に応じてスレッドの優先順位をうまく調整する UNIXでそれやるのはキツいような気がするナー OS側の制約に翻弄されそうな予感。
OSやスレッドモデルによってスレッドの制御がどのように行われるか よく理解した上でないとだめな場合もあるから、よく注意してやるがよい
>350 ネタ調で書きすぎました。すんません。真面目な質問なのです。 >351-352 まったく仰るとおりで、えーと、とりあえず、基本を押さえながら 最近の動向も探っていこうという方針です。 >> 負荷に応じてスレッドの優先順位をうまく調整する この内容に限定しなくてもよいですから、 とりあえず、この本は使えた、使えないとか、いろいろお聞きかせください。 技術本は高いので、厳選しようかと…… 以下は、リストアップしている本です。 ・Pスレッドプログラミング ・実践マルチスレッドプログラミング ・Win32/C++ マルチスレッドプログラミング詳説 ・マルチスレッドプログラミング入門 ・POSIXスレッドプログラミング ・ATLプログラミング―C++テンプレートによるスレッドセーフなコンポーネント開発
Pスレッドプログラミング: 訳が劣悪だった。 POSIXスレッドプログラミング: 自分はこれをスレッド入門とした。 自分自身は計算の並列化に使ってるだけなんで、 負荷に応じて優先順位を…なんて面倒くさそうなことは考えたこともありません。
Solaris使うなら、scheduling classの解説が載っている奴を。 昔はwww.sun.comにいい解説があったんだが、 今は全部セミナーになってしまったな。消すことないと思うんだが…
実践マルチスレッドプログラミング はそこそこ無難との噂が…… >354 うわー、よくスレッド直書きで並列のコーディングできるね。 わたしゃ、並列するときは、MPIが使うのがせいぜいです。 厳密な負荷分散に考慮するような処理までは必要ないけど、例えば、 ・タスクA: 2000Hzで処理を実行 ・タスクB: 500Hzで処理を実行 を並行に流しても、処理の優先度がうまく調整できない…… 数十Hzだと大した問題ではないけど、 数千Hzの重い処理だとつらい。この辺、うまく解決したい。 実は、あんまし小難しいことを考えずに、 金で解決する(マルチプロセッサにする)のが正解だったりして。
そこらのOSのタスクスイッチって10ms単位ぐらいじゃないの?
「pthread」プログラミングじゃなくて「Pスレッド」って時点で怪しいよな。
Pentium4のタスクスイッチって、 Pentium3に比べて異様に重い気がするのだが、 これって私の勘違い? それとも周知の事実? プログラム実行時の体感でなんとなくそう感じる。 ベンチとったわけではないから、はっきりしたことは言えないのだが……。 ちなみにOSはRedHat。
>>360 ム板なんだし、ベンチとってみては?協力するよ。
そして衆知の事実にしようぜ。
コンテキストスイッチとタスクスイッチとXのフォワードウィンドウ切り替えの違いがわかってないっぽいな
>>359 リアルタイムOSじゃないんだから、スレッドの優先度は上げられても
2000Hzとか500Hzをキッチリ守るのは無理だと思う。
実行時間の比率を4:1にするのすら難しいんじゃないかなあ。
>2000Hzとか500Hzをキッチリ守るのは無理だと思う。 有り余るCPUパワーで 禁断のソフトウェアループをかませば可能なのだけど、 論外だなあ……とか思いつつ。 >実行時間の比率を4:1にするのすら難しいんじゃないかなあ。 (スレッド毎に)gettimeofdayで時間を計りながらnanosleepで時間を調整しつつ…… ってアホでつかヲレは……。 なんかこの辺の、冴えたやり方はないものかなあ。
タイマ割り込みは使えないのかい?
2000Hzの処理の後、4回に1回500Hzの処理を入れたらいけないのか?
RT Linuxでmy scheduling policy用のschedulerを書く。そすれば、 >実行時間の比率を4:1にするのすら難しいんじゃないかなあ。 は簡単。
リアルタイムOSじゃないんだから、と・・・
>366 >2000Hzの処理の後、4回に1回500Hzの処理を入れたらいけないのか? ロックかけるってこと? レスポンスが落ちるのがちょっと心配かなあ。 仮に優先課題を (1)レスポンスタイム (2)タスクのバランス 2000回処理した後にまとめて500回処理するのではなく、 4:1のバランスを維持する。 と想定すると、やっぱり残された選択肢はリアルタイムOS?
>>369 つか366が言いたいのは
2000Hz taskA
500Hz taskB
として、
A,A,A,A+B,A,A,A,A+B.....
でいいんじゃない?って事では。
371 :
デフォルトの名無しさん :03/05/15 01:42
そろそろスレッドを使う理由を改めて考える必要があるんじゃないですか
すんません、write-read,write-write lock のクラスを Win32 と C++ で欲しいのですが。 CriticalSection と Event と WaitForMultipleObjects or WaitForSingleObject だけで 書くとどうなりますか? Semaphore とか使うと遅くないですかね?
kernelオブジェクト使うと遅いよ。 どのみちEvent/WaitXXXObject使うなら変わらないと思うが。
>370
>A,A,A,A+B,A,A,A,A+B.....
ちょっと書き方がまずかったみたい。
>>2000 回処理した後にまとめて500回処理するのではなく、
>>4 :1のバランスを維持する。
AとBをあくまで並列に処理させた場合に、
(マルチプロセッサか、Hyper-Threadingでもない限り
所詮は1CPUのタスクスイッチなのだけど)
なるべく4:1のバランスを維持するということを意図した。
1秒後のバランスが、トータルで4:1だとしても、
0.1秒で見て 10:1 とか一時的にふらついていたら嫌だなと。
WEBのサーバとかだとあんまし問題にならないだろうけど、
制御系だと結構重要ではないかと。
2500hzで貰ってきて、aaaabと自分で呼び出せばいいような。
制御系ならRTOS使えってことで終了。
シングルタスクOSを使ってVM環境を作り 時分割で処理を進めればいい
いまだに直に制御してんのか?
マルチスレッドって解決策として安直すぎるよね。 コーディングもデバッグも大変になるし。
MMX命令を複数のスレッドで 同時に使用することになっても問題ないですかね? 問題になるならクリティカルしようと思ってますが
MMXってIA32のことだよな。 dispatcherがよろしくやってくれるはず。 でないとFPUも安全じゃない。
昔、FPUについて調べたことです。 FPUのレジスタはスレッドのスイッチの際、 切り替えが行われません。 スイッチ後初めて浮動小数点命令を使ったときに、 例外が発生し、レジスタの切り替えを行います。 MMXも同じようなことをしてるんじゃないかと思います。 詳しくはIA32のマニュアルを読むとよいです。 ただOSによっては方針が違うかもしれません。 少なくともWindowsはスイッチの際の切り替えは やっていなかったと思います。
マルチスレッドってかなり能力の高い人でないと勉強するのは難しいのかな? 結城さんの本もかなりうまく書けているらしいですけど、なかなか敷居が高そうで、、、 一部の人に任せてしまって、問題なしですか?
マルチスレッドを不用意に使うとバグの元になったり、かえって非効率に なることのほうが多いのでよく理解したうえで、適切な場所に使う必要があります。 スレッドの実装そのものは別に難しいものではないので、 勉強しておいてもいいんでないかな。 と思ったけど >一部の人に任せてしまって、問題なしですか? その根性に問題あり。 プログラマとしての適正なさそうだからやめていいよ。
> プログラマとしての適正なさそうだからやめていいよ。 最近これ多いな。同じ人?
>>384 さぞかし優秀な部下がたくさんいらっしゃるんでしょうね。
>>385 384ではないが、俺も似たようなことを思った。
普通、「当面は得意な奴に任せておけばいいや」と思っても、一応勉強しとくよな。
プログラムというのは、後天的に身に付く技術なので特別な才能はいらないし、 最低限人間として平均的な能力があればよく、適性もいらない。 ただし平均的なレベルから大きく劣る奴は何をやっても駄目なので、 当然プログラムも満足に作れない。 問題なのはプログラマとしての適性なのではなく、 あらゆる作業における基本能力が欠けていること。
誰かにスレッドコーディングを任せると、2倍の労力が掛かるのを知らんのか? 自分で書いた方が10000倍ましだ。 若手教育にはまず「マルチスレッドプログラミングではまらせる」ことが大事。 スレッドかじった奴にHTやMPマシンでコード書かせてみー。泣きついてくること 受け合い。
2倍で済めばいいほうでは?
392 :
デフォルトの名無しさん :03/05/21 10:55
漏れはスケジュールずらされたから5倍位手間掛かってるかも。 残業代が出たからいいものの。。。。。
偉い人はLinuxでpthreadを使ってプログラミングなんかしないんだろな。 SUNのワークベンチだかなんだかのIDEを素直に使ったほうがデバッグの効率はよさげだ。 Linux+pthreadでサーバ書いてしまいました。デバッグだるくて鬱。
Linux以外のUNIX系OSのスレッドの実装はどうなってるんでしょうか? やっぱPOSIXスレッドなのですか? そもそもpthreadなんて使わないのだろうか・・ LinuxはNPTLやらなんやら色々出てきてもうだめぽ・・
pthreadってそんなにだめなんですか? Windowsの ::beginthreadex() もかなりだめぽと思うのですが。
>>394 solarisのがpthreadの元になってる。ほぼ同じと思っていい。
pthreadに無いので有名なのはスレッドの強制停止かな。
まあこれはsolarisのが変なのかもしれない。
他のunixにもあるんだが、
いかんせんマイナーなので中身はよくわからん。
>>393 IDEとpthreadは両立します。
UNIXのスレッド開発環境の問題は、frameworkがないplatformが多いことと、
あってもvendor固有なことです。(e.g. DECthread)
>>394 pthreadは仕様であって、実装ではありません。NPTLはpthreadの一実装です。
ただし、いわゆるPC-UNIXには完全準拠の実装が少ないという問題はあります。
>>396 スレッドの強制停止がないのは、
最低限の設計が行なわれているAPIであることの証左です。
「Javaスレッドプログラミング」
http://www.amazon.com/exec/obidos/ASIN/0201310090/103-8053412-8027047 に解説があります。大規模かつミッションクリティカルなスレッドプログラミングにおいて、
スレッドの強制停止に頼るようなプログラマはチンカスです。
なお、realtime extensionがあれば、
signalを使った非同期処理をthreadごとに用いることができます。
乱筆ご容赦。
Linuxの実装で、スレッド毎にシグナルを処理できたっけ。 今の実装だと、どのスレッドがシグナル食らったか容易には判らんとかきいた。
399 :
デフォルトの名無しさん :03/05/27 23:44
400
∧_∧ ピュ.ー ( ^^ ) <これからも僕を応援して下さいね(^^)。 =〔~∪ ̄ ̄〕 = ◎――◎ 山崎渉
402 :
デフォルトの名無しさん :03/05/28 21:39
ageとく
携帯ゲーム機"プレイステーションポータブル(PSP) このPSPは、新規格UMD(ユニバーサルメディアディスク)というディスクを利用しており、そのサイズは直径6cmととても小さい(CDの半分程度)。 容量は1.8GBとなっている。 画面は4.5インチのTFT液晶で、480px x 272px(16:9)。MPEG4の再生やポリゴンも表示可能。外部端子として、USB2.0とメモリースティックコネクタが用意されているという。 この際、スク・エニもGBAからPSPに乗り換えたらどうでしょう。スク・エニの場合、PSPの方が実力を出しやすいような気がするんですが。 任天堂が携帯ゲーム機で圧倒的なシェアをもってるなら、スク・エニがそれを崩してみるのもおもしろいですし。かつて、PS人気の引き金となったFF7のように。
結論: L i n u x 最 強
保守
(^^)
(⌒V⌒) │ ^ ^ │<これからも僕を応援して下さいね(^^)。 ⊂| |つ (_)(_) 山崎パン
保守
マルチスレッドにおけるC++の例外処理の挙動ってどうなってるんでしょうか? まずは自分で実験しる( ゚Д゚) とか言われそうですが、 コンパイラやOS依存とかだったらアレなので・・。
例外処理はスレッド、というかスタックに対し行われるものだから、 スレッドごとにスタックが完全に独立していれば何も問題ない"はず" あるスレッドでthrowされた例外オブジェクトを別のスレッドで 参照するだとかそういうトンチンカンなことはしないよな?
>>409 tryを見つけるとリストの先頭にcatchを追加する。
例外が発生するとリストをたどりながら、どこでcatchするかを調べる。
例外はこのような実装になっている。
で、リストの先頭をどこかに保持しておかないとリストが作れない。
この先は調べてないんだけど、
スレッドのIDとかの情報を保持している領域に
そのリストの先頭を追加するとかしているんじゃないかと思う。
412 :
デフォルトの名無しさん :03/09/21 10:01
>>409 > コンパイラやOS依存
です。C++標準は何も言ってません。
コンパイラ、プラットフォームを限定すると情報得られやすいかも。
>>410-412 レスサンクスです。
>あるスレッドでthrowされた例外オブジェクトを別のスレッドで
>参照するだとかそういうトンチンカンなことはしないよな?
捕まえてあげないと、別スレッドまで飛んでくるんじゃないか?と
トンチンカンな事を考えてました・・。
コンパイラやOS依存となると
とりあえずは、あるスレッド内で発生した例外は
そのスレッド内で全て拾ってあげて
処理を完結するように心がけるのが得策かなぁ? (´・ω・`)
>コンパイラ、プラットフォームを限定すると情報得られやすいかも。
環境はVC++7.1がメインです。
414 :
デフォルトの名無しさん :03/09/24 17:53
下に記すようなプログラムを Windows(Visual C++)で書きたいのですが、 UNIXのselectに相当する処理を行うには、どのような手順を踏むのが適当でしょう? やりたいことは単純に、 一定時間(数秒ほど)データの受信がなければ、処理を中断するようにしたいわけです。 受信用スレッドを作成してループを回しているのですが、 (厳密な時刻テーブルでの中断処理は必要なく)とりあえず、プログラム終了の際、 このデータ受信待ちのスレッドをどうやって正常終了させるかの問題を解決したいです。 ご教授くださいませ。 ---受信用スレッド内の該当箇所--- struct timeval timeout; fd_set fd; FD_ZERO( &fd ); FD_SET( recvfs, &fd ); timeout.tv_sec = 1; timeout.tv_usec = 0; // 1秒待ってもデータが来なかったら処理をとばす。 switch( select( FD_SETSIZE, &fd, (fd_set *)0, (fd_set *)0, &timeout ) ){ case 0: break; case -1: break; default: if( FD_ISSET( recvfs, &fd) ) socket.RecvData(); // 何らかのデータを受信する break; }
コンソールとかをselectしてないなら、Winsockのselect使えばいいと思うが。
416 :
デフォルトの名無しさん :03/09/25 10:24
>>415-416 ありがとうございます。さっそく今からプログラムを組んでみます。
>>416 わかりやすく解説されていて、
少なくとも下調べの数時間分の労力が短縮されるかと。
サイトを作ってくれた方に感謝です。
418 :
デフォルトの名無しさん :03/10/31 16:07
マルチスレッドをサポートしてるデバッガってあるんでつか? linux上で動くカワイイやつをさがしてます。 どなたか、おしえてください。
419 :
デフォルトの名無しさん :03/10/31 21:44
>>418 GDBで普通にサポートしてませんか?
で、自分の質問で悪いんだけど、マルチスレッドでオブザーバーパターンとか
多用してるとオブジェクト同士のロックがどうしてもデッドロック状態になって
しまうんですが、普通どのように回避するのでしょうか?
他のオブジェクトへのポインタを配列で持ちあって網の目状になっていて自分
のロックを確保してから相手のメソッド呼んで、その相手のメソッドの中でもロッ
ク確保して他のオブジェクト呼んで・・・とか繰り返しているとデッドロックは
避けられないと思うのですが。
420 :
デフォルトの名無しさん :03/11/01 21:46
age
>>419 UNIXで開発してる奴は普通まともなスレッドが実装されたOS使ってないから答えられない
Solarisのスレッドはまともだと思うが。
>>419 どのスレッドがデッドロック状態にあるかどうかもわかんの?
>>419 多数のスレッドが、無作為に、直接Mutexかけて
相手の資源を参照しあうってのは、想像どおり
やっちゃいけないこと。
全くランダムにメッセージをやりとりしているのなら、
メッセージを送るという全ての状態で、1つの
共通な排他ロックを使わざるを得ない。
それだけでは効率悪いし、流れがわからんので、
普通は自前でメッセージマネージャを実装する。
スレッド作る前に並列性を抽出しておくって寸法な。
グループAとグループBは全く相関ないから、並列に
動かせるとか、最初に計画しておくわけよ。
データベースのロックマネージャみたいのを実装して・・・ って無理か
426 :
デフォルトの名無しさん :03/11/02 10:13
C言語でのデッドロックの回避方法がのってるサイトってないのん?(´・ω・`)
別に言語は関係ない
428 :
タイムアウトしたい人 :03/11/04 08:39
アホっぽい質問ですいません。 とあるDLLがありまして、それの中の関数の実行時間が、 1000msec 〜 5000msec という時間ムラのある処理です。 これを 2000msec をしきい値としてタイムアウトしたいのですが、 どのようにすればいいでしょうか? タイムアウト自体は、CreateThreadして、 WaitForSingleObjectの引数でどうにかなるとして、 いったん起動してしまったスレッドの実行を 明示停止するのは、どうすればいいのでしょうか。 (CloseHandleってシステムによるスレッド管理を止めるだけですよね??) TerminateThreadはダメよ、 とMSDNに書いてあるので使う気があまりしません。 関数自体に、タイムアウトの引数を持たせるとか、 同期イベントをうけとる引数を持たせるとかしないと、 タイムアウトを実現する根本的な解決にならないのでしょうか? (そのDLLはサードパーティのやつなんでバイナリしかない...)
>>427 サンプルプログラムとかほっしんですけど。
>>428 Plathomeは Windowsでいいのかな? (本文中から推察してる)
明示的に止めるなら、スレッドの引き数に
HANDLE abort = ::CreateEvent(0, FALSE, FALSE, 0);
とでもしたスレッド停止イベントでもつっこんでスレッドに渡してやって、
スレッド内部で、
HANDLE handles[] = { abort, (他なんかのハンドル)};
DWORD x = ::WaitForMultipleObjects(2, handles, FALSE, 2000);
switch (x) {
case WAIT_OBJECT_0: goto __abort;
case WAIT_OBJECT_0+1: ....
:
}
としといて、外から ::SetEvent(abort); じゃだめか?
ていうか、こういうこと知らないのか普通の香具師は?
こえーよ。おまいらスレッド使うの止めれ。
>>430 それじゃあ無理でしょ
WaitFor〜で2秒間Waitしてる間何も仕事できないじゃん。
WAIT_OBJECT_0 + 1で仕事開始したらabort用のイベント見てないから終了できないし。
abortイベントを使うのはいいとして、仕事の間中、要所要所でTIMEOUTを0にして
監視するしかないんじゃない。単にbool変数でもいいんだが。
>>428 2秒以上時間がかかったスレッドは、そのまま実行させといて終わったら回収
でいいじゃん
>>428 そういう場合通信は無駄
生成したスレッド毎に時間計測させる
434 :
タイムアウトしたい人 :03/11/06 07:18
どうも、みなさんレスありがとうです。 430さんのご返事で主旨がおかしくなっちゃったんですけど、 これって、バイナリライブラリ内の関数で ソースがないときの質問だったのですが... やっぱりスレッドで実行される関数の内部に 手を入れられない場合にこういうことをするのはキビしいのですね。 普通のヤツはスレッド使うのやめれ、っていわれちゃった。(笑)
435 :
タイムアウトしたい人 :03/11/06 07:21
しまった、スレッド切っちゃった、ごめん。
>これって、バイナリライブラリ内の関数で
>ソースがないときの質問だったのですが...
その関数に途中で正確に中断させる機能がないなら、タイムアウトは無理。
中断させなくても良くて、単に結果を無視して次の処理を実行すればいいなら、
>>432 のやり方でしょう。
437 :
デフォルトの名無しさん :03/11/06 15:20
スレッドを使うプログラムでは、 【プログラム中の全てのスレッドは、 常に同じ順序でロックを要求しなければならない】 という原則があるらしいのですが、具体的にどのような 手法をとればいいのかよくわかりません。 自前で、スレッド・ロック・マネージャみたいなのを 作るんでしょうか?
>>434 >>430 は確かに変なレスしてるが、
>>430 に文句があるならはっきり書け。
自分もバイナリしかないと一言も書いてないんだから、非は君にもあるんじゃないか?
「あほっぽい」質問しといて、そういうひねくれたレスは、なんか醜いぞ。
>>437 >【プログラム中の全てのスレッドは、
>常に同じ順序でロックを要求しなければならない】
手法の前に何故同じ順序でロックしなければないらないか考えて見よう。
それが分かれば、どうすれば良いかが分かるでしょう。w
>>431 ごめん、深読みして、スレッドを起こして監視するんだと思ってコード書いてたら
そのスレッド自体を止めるのかと考えがずれてしまった。
>>432 同意。
>>434 ほんとすまん。
スレッドまともに使えない癖にコード書いている香具師(全く排他処理しないとか、
TerminateThread使うとか)多くてイライラしてたんでつ。そういうことをやられて、
尻拭いしてみると、俺も気持ちも分かってもらえるかと。
>>438 変で悪かったなw 擁護無用。
>>439 互いに必要な資源を確保したまま、相手の資源を確保しようとして、デッドロックって感じですよね?
つーことは、キューを使って、スレッド・ロック・マネージャみたいなのを実現すればいいのん?
442 :
デフォルトの名無しさん :03/11/07 00:58
>>441 例えばロックを発生させるメソッドコールA,B,Cがあったとして、
全てのスレッドがA->B->C(A->Bだけ、B->Cだけ、A->Cだけも可)
の順序でそれらのメソッドをコールするようにすれば、デッドロック
はおきません。
なるべくこのルールで回避して、どうしてもダメなとき、例えば
A->B、B->Aが発生する時だけ、「A->B」「B->A」の呼び出し全体を
排他処理すればオケ。
443 :
デフォルトの名無しさん :03/11/07 01:23
>キューを使って、スレッド・ロック・マネージャみたいなの ってどんなことをするのを考えてるのですか?
>>443 ロックされてるリソースに対して優先順位をつけたいってことか?
>> 443 >> 444 こんなこと。 まず始めに、X個のジョブをジョブキューに格納。 次にメインスレッドがワーカスレッドを10匹作成。 【1:MAIN 】全てのワーカスレッドが、クリーンアップキューに格納されるまで待機(※1)。 【2:MAIN 】※2で待機しているワーカスレッドを一斉起動。 【3:MAIN 】ワーカスレッドとメインスレッドをjoin。 【1:worker】ジョブキューにジョブが存在する間、各ワーカはジョブを処理する。 【2:worker】ジョブキューが空っぽになったら、ワーカスレッドはクリーンアップキューに入り、待機(※2)。 このとき、最後に格納されたワーカスレッドが※1で待機しているメインスレッドにシグナルを贈り メインを起動させる。 メインスレッドが"【1:MAIN 】"のステップを踏む前に、 ワーカスレッドが"【2:worker】"のステップを踏んだ場合、 デッドロックになるよね? 今は、sleep()をワーカスレッドにつかって【1:MAIN 】→【2:worker】 ってなるようにしてるけど、ふつー、こんなアッフォなことしないだろうと。 いったい、どうすればいいのさ。 最近、スレッドプログラミング始めたばっかりの者なんで、 けっこう頭わるそうな、質問かもしれませんが、おおめに見てやってくださいな。
>>445 condition variableでも使えば。
>>445 セマフォが使えるなら、
■main
スレッド生成&起動10個;
P() x 10個
■worker
V();
みたいな感じ。セマフォってpthreadとかで使えるのかよくしらんので、
たいていこんな感じで作るかな。
■main
int flag[10] = {0,0,0,0, . . . }; // 同期用フラグ
スレッド生成&起動10個;
while(1) {
for(i = 0; i < 10; i++ ) {
if( flag[ i ] == 0 ) break;
}
if( i == 10 ) break;
yield() または sleep(1)
}
以下略
■worker
flag[ thread_id ] = 1;
. . .
>>445 pthread_barrier_wait が使える環境なら、それを使えば一発。
boost::threadを業務で使ってる人います?
それ以前にまともな神経ならboostなんて仕事で使えたもんではない。
boostのスレッド廻りはバグだらけだしね。
452 :
デフォルトの名無しさん :03/11/10 16:29
void *status; ..... pthread_create(&t_id, NULL, func, (void *)arg); ..... pthread_join(t_id, &status); printf("status:%d\n", (int)status); ってして、funcのなかで、 void *func(void *myArg){ return (void *)1; } ってしたら、 % status:1 って出力されるんだけど、これはなんで? プログラムは正しく動くけど、よく理解できません。 statusってアドレスだと思うんですけど... printf("status:%d\n", (int)*status); ってやると、ワーニングでるし... なんで?
>>452 マルチスレッド云々以前に、まずCの基本を勉強しよう。
454 :
デフォルトの名無しさん :03/11/10 16:52
すみませんでした。 ここにいるのは役に立たないクズばかりですね。 もういいです。
455 :
デフォルトの名無しさん :03/11/10 18:26
>>454 クズはお前!他人になりすまして、勝手にレスすんな!!
最近、友達から無視されて辛いのはわかるが、それは、自分がわるいからでしょ?
素直になれよ...
453へ、ほんとにすんません。
googleとかで調べて、勉強したんですが、良くわかりません。
どなたか御教授くださいな。
>>455 ちみの書いていることって、
void *status;
status = (void*)1;
printf("status:%d\n", (int)status);
って書いているのと同等だということが分からんか。
期待通りの動作だと思うぞ? コードの意味は不明だが。
そもそも、return (void *)1;って何? 素直に読むと絶対アドレスの1番地(に設定したvoid型ポインタ)を返す としか読めんが。組み込み以外でそんなコード書くことってあるのか?
462 :
デフォルトの名無しさん :03/11/17 01:27
スレッド間で共通のあるクラスのstaticなインスタンスに対して 複数スレッドがデストラクタを実行することってあるのでしょうか?
463 :
デフォルトの名無しさん :03/11/17 02:00
>>462 staticなインスタンスってどゆこと?
staticが消滅するのはプログラムの終了時じゃなかったっけ。
465 :
デフォルトの名無しさん :03/11/17 02:29
すみません。staticがどうと言うよりも デストラクタを複数スレッドが実行することが あるのかどうかが分かっていないのです。
466 :
デフォルトの名無しさん :03/11/17 03:18
ない
ように作る
故意にデストラクタ呼ばない限りdeleteするスレッドはひとつでしょ
471 :
デフォルトの名無しさん :03/11/17 14:52
BCB6 ProでMamimiみたいなものを作りたいのですが、 スレッドを次々に所定の数まで作るのはどうすればいいのでしょう? 私が持っているBCBの入門本では、別スレッドを1個しか作っておらず、 複数のスレッドの管理までは説明されていません。 よろしくお願いします。
472 :
デフォルトの名無しさん :03/11/18 02:46
CreateThreadを所定の数分ループしる!w
474 :
デフォルトの名無しさん :03/11/18 17:52
使おうとする関数が,スレッドセーフか否かって,ど→やって判断すんの?
たくさんのスレッドからその関数を使いまくっていじめてみる
>>475 標準ライブラリからインクルードして利用する関数も全部そうするの?
そこまで,暇人じゃあねーんです.
どなたか,御教授くださいな.
OS書いてねん。 WindowsならMSDN Solarisならman PC-UNIXはmanに明記してなければ、source読め、かのぉ〜
使用OSは linux redhat9.0 です.manを読みましたが,スレッドセーフかどうかまでは,記述されていませんでした. やっぱり,ソースを1つずつ読んでいくしかねーのかなー?
労を惜しむなよ
>>476 ,478
stdioはMT-Safe。glibcのmanual読んでね。
ところで、linuxじゃー、fprintf()とかfopen()とかのソースって、 どこに格納されてんの? アッフォなこと聞いて申し訳。
482 :
デフォルトの名無しさん :03/11/19 01:55
errnoを参照したりするとMT-Safeじゃなくなるかもね
errnoは今どきのマトモなOSなら実体は関数で、マクロ実装になってる筈。 strtokやtime.hの多くの関数群は、普通に実装すると非スレッドセーフになる ような腐ったインタフェースを持っているが、今どきはステートをTLSに 突っ込むことで解決しているか、リエントラント版の別関数が用意されてるのが 普通。 stdioはステートフルだが、今どきはMTSafeにした版も用意されている。 が、これは排他によって実現されており、古典的な実装に比べて恐ろしく 非効率なので、通常は古典的な実装と合わせて2つの種類が用意されている。 こういう種類の非効率を解決するためにJava2で新しいコレクションフレーム ワークが導入されたのは有名な話だな。 グレーゾーンでかつドキュメント化されてなければ、非スレッドセーフだと 考えた方が安全。しかし、状態を持つオブジェクトを複数スレッドから 触らなければ、通常は問題がない。 今どきスレッドセーフティに関する記述が一切なされていないような ライブラリは、その信頼性を疑うべきだろう。
unix方面だとgetaddrbynameなんかも該当するねー
>>451 boost::threadのバグって具体的にどこらへん?
既にboost::thread使って作ったもんがあるから(業務用じゃないが)不安になってきた。
487 :
デフォルトの名無しさん :03/11/27 00:32
スレッドセーブについて教えてください なに?何語??スレッドをセーブするの?? みたいな感じです。はい。 よろしく。
>>487 thread save = スレッド保存
永続化とか
>>421 まともなスレッドが実装されているOS
されていないOS
の例を教えてください。
>>490 まともなスレッドが実装されているOS ⇒ NT, Mach
されていないOS ⇒ Unix, Linux, *BSD
Win32でマルチスレッドプログラムを初めて作ってみたのですが、排他処理について質問させてください。 変数に対してクリティカルセクションとかで排他にするのは 書き込んでいる途中のオブジェクトを読み込むと変になってしまったりするからですよね。 ということはたとえば、終了フラグなどの単純な値は排他処理しなくてもいいのですか?
>>492 (゚Д゚)ハァ? って書いて欲しかったのか?
495 :
デフォルトの名無しさん :03/11/30 20:25
age
>>493 CPU + busがatomicであると保証している操作は排他する必要がない。
例えばword境界にwordを書き込む、などはほとんどのarchitctureでatomic.
kernel threadについて言えば、
まともなスレッドが実装されているOS ⇒ NT, Mach, Solaris, AIX, HP-UX, Tru 64, Linux, VxWorks...
されつつあるOS ⇒ *BSD
変なAPIを持つOS ⇒ NT
pthreadに適合しないthreadを持つOS ⇒ Linux, *BSD
>>497 概ね賛成だけど、初心者に対しては少し極論ではないかと思う。
>CPU + busがatomicであると保証している操作は排他する必要がない。
>例えばword境界にwordを書き込む、などはほとんどのarchitctureでatomic.
書きこむ時は、どっかのメモリにの内容をレジスタに読み出して目的のメモリ
に書き出すのが一般的だから、1命令で終わるとは思えないし、その間に
dispatchが発生したらおかしなことになりかねないと思う。
>>493 制御系とかのクリティカルな場面では排他制御をするかしないかは、フラグ
の使われ方を考慮して慎重に検討したほうがいいよ。
Win の場合どうかわからないけど。。。
Mach ってはじめて聞いた。 マルチスレッド界隈では有名なんですか?
>>497 ,
>>498 回答ありがとうございます。
なるほど、CPUの命令がどうなってるかで対応が変わるわけですね。
スレッドの割り込ませ方がどうなっているかをまったく知らないのでなんですが、
割り込みが起こらないことが保障されているなら排他しなくてもよいと。
質問です。 複数のクライアントからのTCP/IP接続をスレッドを作成して処理しているサーバーを作っています。 サーバー稼動中に、標準入力からコマンドを受け付けて各スレッドにそれを通知させる方法はありますか? コマンドに応じて繋いでいるクライアントに一斉ファイル送信、などの処理を行ないたいのです。 言語はC、環境は赤帽9、pthreadを使っています。 ご指導お願いします。
>>498 頼むよ! そりゃ「読み出しと」書き込みだよ!
Mulit processorでアセンブラ書くなら、基本単位の読み出しあるいは書き込み「だけ」でも、
load-linkedとかstore-conditionalとか気にする必要あるけど、
>>493 はVC++でWin32でしょ。
>>493 OSの本の排他制御を基礎から解説しているのを読んでみれ。
Deckerのアルゴリズムとか初歩的な概念から載ってる本な。一章分だけ読みゃ済むから。
岩波のシリーズのOSの分冊とか、タンネンバウムのOS本とかが手に入りやすい。
>>503 漏れはどっちかって言うとファーム屋で、過去に一度これでイタイ目にあったこ
とがあるんで、そんなこともあるよって注意を促しただけ。気に障ったらスマソ。
>>500 >スレッドの割り込ませ方がどうなっているかをまったく知らないのでなんですが、
漏れも知らんのだが、誰か知ってる人いたらおしえてください。
スレッドの割り込まれ方というより、
CPUの割り込みのレベルまで考えないと、
>>493 の知りたいことは知ることができない。
ただ、Win32ということなので、intの書き込みはatomicと思っていい。
むかし、バスが16ビットだったころはlong(2WORD)の値を書きこもうとしたら、 下位1WORD、上位1WORDと2回に分けて書きこまないといけなかった。 その間に割り込みが発生して別のルーチンが先に書きこんだ下位1WORD を書き換えてしまうと、おかしくなる。 32ビットバスだと1回で書きこみできるんでそんなことは発生しない。 ってことだね。
Win32ならInterlockedIncrementとかInterlockedDecrementとか InterlockedExchangeとか使っとけよ…。
それ(atomic inc./dec., atomic swap)が必要な場合ならば、それでよい。
そういえば以前WinNTでInterlocked系の関数がマルチプロセッサ 環境で例外を吐いてしまうってバグなかったっけ?
> ということはたとえば、終了フラグなどの単純な値は排他処理しなくてもいいのですか? 0か1かみたいな単純なフラグならスレッドが途中で切り替わったところで問題ないと 思うが俺の理解間違ってる?
「そのようなフラグへの書き込みそのものが、クリティカルセクションになることはない」 という答えでよろしいか? (って何様だ、俺…)
512 :
デフォルトの名無しさん :03/12/02 08:39
>>499 マルチスレッド界隈は知らんがOS界隈では有名だな。たぶん。
>>511 全ての環境でそれが保証されるわけでは無い
というのが答えでは。win32の32bit変数なら
多分OKだろうけど。
だからといって味噌糞にロックかけるのも
何なんで、atomic_flag見たいなクラスなり
関数なりを作って集中管理して、他環境に
移植する再にそれを修正するのが正しいと思う。
C/C++ならinlineがあるからそれが単純な関数だった
としても最適化されるだろうし。
atomic_tでいいだろ。
0か1かのフラグがアトミックじゃなくたって別に同期なんかいらないんだが
> ということはたとえば、終了フラグなどの単純な値は排他処理しなくてもいいのですか? 書くだけ、読むだけならたぶんだいじょうぶ。 読んで書くなら排他制御必要だとおもったほうがいい
>>516 了解しますた。
今回は一方で終了フラグをたて、もう一方ではそれを読んで終了するだけなので
排他制御は要らないようです。
それなら要らないな
519 :
デフォルトの名無しさん :03/12/06 18:36
マルチスレッドの勉強しようと思って_beginthreadex()使ってみたんだけど 最初の1回目の実行時のみ「スレッド内」が呼ばれるだけで 2回目以降は表示されません。 どうしてでしょう? unsigned __stdcall TestThread(void * param) { std::cout << "スレッド内" << std::endl; return 0; } void main() { DWORD id = 0; HANDLE hThread = (HANDLE)_beginthreadex(NULL, 0, TestThread, NULL, 0, (unsigned *)&id); std::cout << "スレッド呼ばれたかな?" << std::endl; return ; }
そりゃメインスレッドが終了しちゃあ・・・終わっちまうでしょ。
521 :
デフォルトの名無しさん :03/12/06 20:18
終わるにしても /*実行結果*/ スレッド内 スレッド呼ばれたかな? にはならないんですかね? 1度目の実行時には表示されるけど、 2回目以降実行すると /*実行結果*/ スレッド呼ばれたかな? で終わってしまう。
522 :
デフォルトの名無しさん :03/12/06 20:29
自己レス デバッグでブレークポイントをいろいろ変えてみたら 「スレッド内」が表示するタイミングがズレてるのが原因みたいでした。 おっしゃる通り、メインが終了してるからでしたね。 ごめんなさい。 TestThreadが呼ばれて実行するタイミングは必ずしも 順番通りというわけじゃないのでしょうか。
>>522 その通り。スレッドが作成されたからってOSがどうスケジューリングするかで
実行されたりされなかったりするね。そのコードだと。
524 :
デフォルトの名無しさん :03/12/06 21:04
>>523 勉強になりました。
ありがとうございました。
>>523 実際に作ってみると、だいたい新しいスレッドってなかなか実行開始しないんだよねー
デバッガでブレークかけてると(無駄に時間がたつので)すぐに実行されるので
大丈夫だったのがブレークやめたとたんにエラーになるとかいうのがよくある。
なかなか手ごわいです
スレッドのタイミングに依存するような書き方がまずいのです。 設計を考え直しませう。
まあ、普通はSUSPEND状態でスレッド作るわな。
>>527 この場合はメインスレッドのどっかで WaitForSingleObject(hThread) かなんかで
ワーカスレッドがチャンと終了するのを待ってやる方が正しいと思うが。
保守上げ
530 :
デフォルトの名無しさん :03/12/13 02:01
>>525 >実際に作ってみると、だいたい新しいスレッドってなかなか実行開始しないんだよねー
スレッドの優先度が低くなってるんじゃない?
スレッドが本当に並列で動くと勘違いしてるんじゃない? メインスレッドでビジーループしてると見た
とうか
>>525 の後半を読む。
そうすればこのレスは完全に無視していいことがわかる。
533 :
デフォルトの名無しさん :03/12/13 19:39
WinXP Proのスレッドはかなり画期的で高度な技術用いてるぞ。 マジ素晴らしい。UNIXのスレッドスケジューリングを遥かに超えている。
↓以後何事も無かったかのようにどうぞ↓
WinXP Proのスレッドはかなり画期的で高度な技術用いてるぞ。 マジ素晴らしい。UNIXのスレッドスケジューリングを遥かに超えている。
まさかlinuxなんかのと比べてないだろうな?
そういやW2kのコンソール立ち上げて、大量にコンソール 画面に出力する重い処理走らせると、一定時間タスク切り替えが できなくなるよな。あれはスケジュールングの話題に関係あるのか?
538 :
デフォルトの名無しさん :03/12/14 04:10
ルング
XEngine走らせると他のに切り替えられなくなるんだが、 これもスケジューリングの話題に関係あるのか?
>>533 Priority inheritance付きで?
543 :
デフォルトの名無しさん :04/01/07 08:07
スレッドではないんですが... shmget()やshmctl()を使って共有メモリを複数のプロセスから 同時にアクセスしたい。pthreadのmutex_lock()のように 相互排除ロックは必要なのでしょうか? 必要だとしたらどういう関数を使えばいいのですか?
そりゃ、必要な局面では必要だべ。 System V IPCのshm*は、単なる共有メモリであって同期機構はないからね。 lockingは、同じくSystem V IPCのsem*(semaphore)を使ってね。 これがない頃は、open(2)のO_CREAT | O_EXCLを使ってましたねえ。
545 :
デフォルトの名無しさん :04/02/10 07:22
pthreadにおいてスレッドが動作しているかどうか調べるためにはどうしたらいいですか?
2ちゃんねるもマルチスレッド? マジレス希望。
マルポって言ってんだよhage
>>544 ねーよ、pthreadにはな。
Javaのthreadにはあるけどな。
551 :
デフォルトの名無しさん :04/02/16 22:34
vb.netで、同じメソッドを複数のスレッドとして動かしています。 そのメソッド内でエラーをcatchし、呼び出し元にthrowしようとしたのですが うまくいきません。 .net Frameworkのスレッド特有の現象なのでしょうか?
throwはそのスレッド内でしか有効じゃないぞ。
553 :
デフォルトの名無しさん :04/02/17 09:02
>>552 そうですか、ありがとうございます。
何かそれについて説明されているサイトなどあるでしょうか?
>>551 > うまくいきません。
はやめなさい。状況を説明しる
555 :
デフォルトの名無しさん :04/02/17 15:43
ああもう全部読むのにスゲー時間かかったーーー。 なんつーかマルチスレッドって必要性感じ無かったナ。 んじゃね。
>>554 ご存知だと思いますが、
呼び出されているメソッド内で
try
・・・・・
catch ex as exception
throw ex
end try
とし、かつ、呼び出し元でtry,catchをしていれば
普通、ここでその例外をcatchできるんです。
でも、呼び出し元で
try
Dim t As New Thread(AddressOf 呼び出すメソッド名)
t.Start()
catch ex as exception
ex.tostring
end try
としても、呼び出されたメソッドで例外がスローされても
こちらに飛ばないんです。
>>554 ご存知だと思いますが、
呼び出されているメソッド内で
try
・・・・・
catch ex as exception
throw ex
end try
とし、かつ、呼び出し元でtry,catchをしていれば
普通、ここでその例外をcatchできるんです。
でも、呼び出し元で
try
Dim t As New Thread(AddressOf 呼び出すメソッド名)
t.Start()
catch ex as exception
ex.tostring
end try
としても、呼び出されたメソッドで例外がスローされても
こちらに飛ばないんです。
うわ、二重カキコです。 お許しを。
二重カキコです。お許しを。 しかも日本語が変です。 10行目 「普通、そこでこの例外をcatchできるんです。」 に訂正です。 最後の文もおかしいですね・・・
本当にすみません。逝ってきます。
>>557 案の定。
理由は
>>552 の通りで、新しいスレッド内でthrowされた例外は、
そのスレッド内でしかcatchできない。
557の後半のコードでcatchに来るとしたら、それはスレッドの生成に
失敗したときぐらいだろうね。
これが理解できないうちはスレッド使うのはやめといたほうがいい。
まあ、理解できたらできたでスレッドを使う気が失せると思うけど。
>>561 先輩、ありがとうございます。
引き続きアドバイスをよろしくお願いします。
563 :
デフォルトの名無しさん :04/02/21 12:15
誘導されてきました。
linux 上で pthread を使ったプログラムをしてみたくて、
http://www-6.ibm.com/jp/developerworks/linux/001222/j_posix2-index.html を見ながら試してたんだけど、その中の thread3.c が思った動作をしてくれません。
o..o..o.o..o..o.o.o.o.o..o..o..o.ooooooo のような結果を期待したのに、
....................oooooooooooooooooooo になってしまいます。
thread_function()中の sleep(1); を pthread_mutex_unlock(&mymutex); の下に
持って来ると期待した結果になります。
以上は、カーネル2.6 ですが、スケジューラの違いではとコメントがあったので
カーネル2.4 も試してみると、sleep の位置に関係なく期待どおりの動作でした。
カーネル2.6 での動作に違和感があるんだけど、なぜこんな動作になるんでしょう?
キャッシュが無駄にならないように、なるべく同じスレッドが割り付けられる ようになったんじゃなかったっけ。 SMPにすると2.6でも期待した結果になるかもよ。
>>564 SMP は、試したいけどその環境がないです。
>>565 仕様ですか・・。黙るしかないですね・・。
素人考えでは lock の期間が長いと頻繁に例と同じような状況になって問題に
なりそうだけど、特殊な例だったのかな?
知識と経験の不足が明らかになったんで、こういうもん、ってことにして、もう
少しいろいろ使ってみます。
>>566 lockしてる期間の方がしてない期間よりも圧倒的に長いってのは、
割と特殊かもしれん。
どうしてもスイッチさせたいなら、unlockしたとこでpthread_yield()してみれば。
mutexの奪い合いで適切にスイッチさせるのは無理があるような・・・ まあ、producer-consumerモデルだったら、同じスレッドが受け取ったほうが キャッシュ効率がよさそうだねえ。
>>568 >mutexの奪い合いで適切にスイッチさせるのは無理があるような・・・
無理あるどころじゃないだろw
このプログラムで交互に出力されると思い込むほうがバグの元。
単純にmutex使っただけでは順序を規定させることはできないでしょ?
>>563 sleep()してようが、pthread_yield()してようが、
mutexで保証されるのはlock〜unlockまでのcritical sectionを
同時に実行できるスレッドは1つしかないってことだけ。
タイミングを揃えたいなら、condition variableを使うか、
フラグ見つつbusy loop(←sleep()やpthread_yield()使っても意味は一緒)
する必要がある(condition variableがそんな実装でも構わないのかも)。
スレッド間でタイミングを決定する同期を行ってない以上、
片方のスレッドが完了した後にもう一方が実行されてもおかしくはない。
その実装が腐ってるとは文句言えても、間違ってるとは言えない。
>>569 > その実装が腐ってるとは文句言えても、
ご存じの通り、これは言う奴が馬鹿でしょ。
交互に実行させたければ二つmutex使って襷掛け、 これ常識だよな。
Win32なら軽いからタスク振り分け用スレッド立ててもいいけど。
>>571 んなアホな。
デッドロック一直線でんがな。
つか、pthread_mutex_lockの所で長時間待たされる可能性があるような実装は
ダサいと思う。
同期が必要ならpthread_cond_waitで待つようにすべきでしょ。
>>573 > んなアホな。
> デッドロック一直線でんがな。
???
575 :
デフォルトの名無しさん :04/02/27 18:22
スレッドローカルストレージって便利そうだという想像はつくんだけど、 "逆に便利すぎて怖い"&"互換性は?"ってことで敬遠してました。 積極的に使ってるって人っています?
スレッドローカルな作業域、属性などが必要な時に使ってます。 というか使わずにどうやって…自前でやるよりもずっといいし。
>>575 そういう考え方は良くないんでない?
特に互換性は問題ないでしょ。今現在で一般的なスレッドAPIって
POSIX ThreadsとWin32くらいでどっちも十分似た仕様だし。
ただ、TLS(TSD)をスレッドセーフなグローバル変数としてガンガン
使うってのはちょっとまずそうな。。。
>>576 >スレッドローカルな作業域、属性などが必要な時に使ってます。
それだとそのまんまな様な。できれば具体例希望。
>>577 そうですね。結局グローバル変数的になっちゃうような気がします。
気になるのは、TLSを使う処理がスレッド構成に依存しちゃいそうな事。
処理優先度の変更等でスレッド構成を変えた時にどんな影響がでるのか
読めないのが怖いです。
>>578 クライアントごとにスレッドを割り振るサーバで、
パケットを生成するときの作業領域。sprintfしたり、checksum計算したり。
他にもクライアントごとに必要なデータをまとめて。
スレッドプール版は、pointer間接を一段増やして管理。
ライブラリがスレッドセーフかそうじゃないかって何が基準なのでしょうか。 変数の更新があったらもうダメって訳ではないですよね。
こういうのはマルチスレッドセーフじゃない。 char * f(int i) { static buf[BUFSIZ]; sprintf(buf, "%10d", i); return buf; } gethostbyname(3)はこれに類するコードだったようで、 MT safeなgethostbyname_r(3)が新設された。
>>581 メモリ領域を特定して上書きする処理という事でしょうか。参照渡しの関数は
全滅なのかなぁ。
static と global が駄目ってこと?
これなら桶。 char * f(int i, buf) { sprintf(buf, "%10d", i); return buf; }
>>581 そういうのはマルチスレッドじゃなくても破綻するなぁ。
if ( strcmp( f(a), f(b) ) == 0 )
>>581 > gethostbyname(3)はこれに類するコードだったようで、
つーか、コード云々じゃなくて静的領域に値入れて返す奴は原理的に全滅だろ。
>>582 各スレッドで独立の領域を準備して参照渡しで処理してもらうなら問題ない。
(もちろん、内部でスレッドセーフなコーディングされていることが前提であるが。)
>>585 そのコーディングはマルチスレッド以前の話。
char * f(int i) { static char buf[BUFSIZ], *p; sprintf(buf, "%10d", i); p = malloc(strlen(buf)+1); // エラー処理はしょっとく stycpy(buf, p); return p; } でも、bufを排他してないから駄目。
C++で Linux / Win で互換性があるライブラリは boost::thread がデファクトスタンダードということで いいのでしょうか?
boostがデファクトスタンダード? まだ無理がないか? それ以前にthreadに互換性を求めること自体が・・・
POSIXサブシステムでpthreadと言ってみるテスト
前から疑問に思っていたのだが、スレッドを使って処理系非依存のコードを 書くことって可能なの? 例えば pthread 自体は POSIX の下で動作が定義されているのかもしれないが、 C言語の規格はローカル変数はスタック領域に保存しなくてはいけないという 決まりは無かったと思う。 つまり pthread を使ったところで、ローカル変数を使用した関数が スレッドセーフになるかどうかは処理系に依存してしまう訳だろ? 結局のところ、スレッドを使って処理系非依存のコードを書くことは 絶対に出来ないということになると思うのだが、そこのところどうよ
>>591 > つまり pthread を使ったところで、ローカル変数を使用した関数が
> スレッドセーフになるかどうかは処理系に依存してしまう訳だろ?
この環境では、(例えばshallow bindingなど)
スレッド政府な(ローカル変数を持つ)関数を書く事ができないので、
スレッドのポータビリティ検討対象から外してもいいのでは。
>>581 > gethostbyname(3)はこれに類するコードだったようで、
> MT safeなgethostbyname_r(3)が新設された。
gethostbyname(3)のアドレスファミリ独立版である(IPv4,v6どちらでも使える)
getaddrinfo(3)なら最初からスレッドセーフなので、
新しく書くプログラムならこっちを使ったほうがいいかも。
# もちろん対象のシステムにgetaddrinfo(3)があることが前提だが…
>>592 現実問題としてはその通りだろうけど・・・
基本的に処理系が保障していない動作を「見込んで」
プログラミングをするのって、何か怖くない?
>>594 あほですか?そんなことを気にすんならスレッドの方が桁違いに処理系依存だろ
そんなに気になるならK&R/ANSI C/C99の共通部分だけを厳密に使えば?
そしたら、コンソールやキーボードすら仮定できないよ?w
そもそも処理系が厳密に仕様を満たしてる保障もないわけだが。
正直って、APIがスレッドセイフかどうか明記してあるシステムで、
プログラマが記述した関数が、
>>591 で言うような理由で、(ローカル関数がスタック上にない)
スレッドセイフにならないってことはありえないんじゃないの?
もしそうだったならば、APIがスレッドセイフである意味がないもんね。
もうちょっと現実的なしちゅえいしょんを描いてくれないと…
>>588 > C++で Linux / Win で互換性があるライブラリは
Cだったgthreadなんかどうなんだろね。
gimpのためにいろいろなプラットフォームに移植されているみたいだけども。
>>595 >そんなことを気にすんならスレッドの方が桁違いに処理系依存だろ
これは、そういう意味での "処理系依存" という話ではない訳で・・・
コンソールやキーボードは、そのライブラリがあって、かつ言語の規格に
準拠したコードを書いてさえいれば、その規格を満たしたコンパイラなら
確実に意図した動作をするコードを吐いてくれる筈。
しかしこの場合、ライブラリがあって、規格準拠のコンパイラを使って、
どんなに行儀の良いコードを書いても、動く「保障」がない、
というのが気持ち悪い。
だめだこりゃ
>>599 んじゃ、コンソールやキーボードの規格に準拠している、
コンパイラが確実に意図した動作をするコードを吐いてくれる、
ってのを保障してくれるのはどなた?
WindowsとUnix系じゃ全く同じように標準出力に書いても、
エスケープシーケンスとかの関係で見た目変わるよ?
動く保障がないと言うんなら、コンソールに出力しようとしたが、
メモリ不足でバッファを確保できなかったとかの場合もあるし。
#何でこんな奴相手にしてんだろ Σ(´D`lll)
処理系非依存に拘りすぎるのは時間の浪費だと思うがなー スレッド、ソケット、ファイルシステム どれをとっても完全非依存は無理だよ おいらは、アプリケーション作者が「必要な互換性」を選択できるように なっているほうことが重要だと思うのよね。そういう意味では中途半端に 互換性を打ち出してるライブラリは、参考にはなれど、実用にはならん。
処理系依存という言葉を使ったのが悪かったかな・・・ 勿論、コンパイラ作者が「このコンパイラはローカル変数は 全てスタック領域(若しくはレジスタ)に貼り付けます」と 一言言ってくれて、プログラマが「このコードはそのような 処理系でのみ動作を保障します」と言いさえすれば全く問題がない。 ただ、現在の標準のCの規格だけでは、そうでもしない限り、 厳密に動作を保障することができないという事。 Cの規格が古いのがいけないのだろう。「Hosted環境」みたいに、 新たに「Threaded環境」というような概念を言語に組み込まないと いけないような気がする。
もう寝ろ
>>603 お前が心配してるような実装が仮にあったとすると、再入性すら保証できないだろ。
つまり、autoをサポートしない処理系について心配してるわけだな。
続きはCOBOLスレかFORTRANスレでやってくれ。
スレッドプーリングって、触手プレイと似てるよね。 女の子(処理)が来たら、触手(スレッド)がお出迎えさ。 いや、気にしないでくれ。
全然似てない。
むしろ、ソープ嬢の控室に似てる。
指名できる場合があるから違う。
出勤日のはずなのにいない時もある。 違うOSにマイグレートする事もある。
Javaのマルチスレッドとかどうなのでしょうか? > 処理系依存
いいんじゃないですか。
613 :
デフォルトの名無しさん :04/03/10 22:24
現行のAIXってタイムスライス実装してる? してないとしたら、スレッドはどういうライフサイクルになってる? AIX上でスレッドを実装するときに気をつけることは?
してる。 マニュアルを良く読む。 スケジューラの性質について勝手な空想をしない。
4バイトより大きい返り値を静的領域を使って返すC処理系があったな
616 :
デフォルトの名無しさん :04/03/10 23:26
すまん。マニュアル読むわ。
>>611 その挙動は環境に大きく依存する。
ちなみに pure java を名乗るためには、スケジューラの挙動に
依存してはならない。つまり、CPUを長時間占有するようなタスクは、
適宜 yield() を呼ばなければならない。
そりゃ、その程度ならどのマルチスレッドシステムだってそう。
野性味あふれるマルチスレッド
> 適宜 yield() を呼ばなければならない。 うわ、だっせー
なにが? 普通じゃないか。
yieldってWindows 3.1みたいなだ
昔には戻りたくないな。
Windows 3.1はyieldしないとCPUを離さない、これは仕様。 Javaの場合はそう決まっているわけではない。 実装によっては単にhintとして使ったり、無視して良い。
pure javaじゃなくなるじゃん。
↑文盲発見!
Win3.1はマルチタスクであってマルチスレッドではない。 スレッドの実装はwin32からだえお
>>617 お前pure javaを勘違いしてない?
普通は(直接的に)ネイティブコードを使わずに実装されてる事だと思うが。
それにスケジューラが平等だとかには依存しない方がいいのは確かだが、
yield()しなきゃコンテキストスイッチが起こらない可能性は考慮する必要なし。
Javaの仕様的にはそんな糞実装でも間違ってはないんだろうが・・・
> yield()しなきゃコンテキストスイッチが起こらない可能性は考慮する必要なし。 それじゃpure javaになりません。 pure javaでないjavaコードに存在価値なんてありません。
>>628 >yield()しなきゃコンテキストスイッチが起こらない可能性は考慮する必要なし。
>
>Javaの仕様的にはそんな糞実装でも間違ってはないんだろうが・・・
そんな事言っている奴らばかりだから
Java 厨は、"Write Once, Run Away" って蔑まれるんだよ。
>>629 ( ゚Д゚)ハァ?お前の言うpure javaの意味書いてみろよ
>>630 「yield()書かないとコンテキストスイッチしません」って
環境で作らなきゃならないんなら、必要に応じて組み込むが、
あるとしても一部の異常な実装だろ。
そもそもyield()しなきゃいけない状況の方が特殊だろ。
無駄にbusy loopしまくりなプログラムでも書くのか?
> そもそもyield()しなきゃいけない状況の方が特殊だろ。 勝手に限定しないでくださいね。
>>632 可愛そうに。。今時Non-preemptiveな環境で作ってるんだねぇ
それかまともな同期を実装できないおばかさんなんだね。
この規定はpure javaの規定であって、 実装系の話をされても困るんですがねぇ・・
>>634 >この規定はpure javaの規定であって、
>実装系の話をされても困るんですがねぇ・・
いや、もともと JAVA は環境というものについて
その程度の認識しか持たない(or 持てない)レベルの奴でも
必ず動くコードが書けるようになる、というのが設計理念だった筈。
だからこそ
>>631 みたいな厨がわらわらと JAVA に群がってきた訳で。
これは JAVA 自体の設計ミスだな。
だから、それのどこがPure Javaと関係あるんだっつーの 厨と言うなら、どこに問題があるのか正確に示してみろ
637 :
デフォルトの名無しさん :04/03/23 18:00
Soralis2.6でスレッドのプログラム作ろうと思っているんですが 2.6ってスレッドに不具合が無かったですか? 昔に聞いた事があるような気がするのですが。。 教えて下さい。
638 :
デフォルトの名無しさん :04/04/14 11:44
localtimeはスレッドセーフ関数では無いと聞いたのですが gettimeofdayはスレッドセーフなのでしょうか? 教えて下さい。よろしくお願いします。
環境に依存する マジレス
わざわざpthreadをWin32で使いたがる理由がわかんない cygwin向け?
後はportingとかね。
>>641 自分のソースの寿命が Win32 の寿命よりも長いと思っている香具師向け。
pthread on WinFXがなければその配慮も無駄になるわけだが
>>641 linuxとwin32で同じソースコードが使えれば便利じゃない?
646 :
デフォルトの名無しさん :04/04/22 17:36
windowsで_endthread(_endthreadex)などでスレッド終了させた場合、 そのスレッド内で作成されたオブジェクトのデストラクタが呼ばれないのは、 仕様ですか? class Hoge{ public: Hoge( int n_ ): n_ptr( new int(n_) ){ } ~Hoge(){ std::cout << "~Hoge" << std::endl; } boost::scoped_ptr<int> n_ptr; }; beginthreadexで呼び出す unsigned int __stdcall thread_test( void* data_ ){ Hoge hoge(100); _endthreadex( 0 ); return 0; } デストラクタが呼ばれれない・・・、メモリリークしやがる・・・。どうすればいいですかね? 別なところからこのスレッド終了させる場合に_endthreadexつかえないのは不便・・・。
これは、任意の時点で終了させたいってこと?
>>646 仕様っつーか、C++の想定範囲外。
exitでローカル変数のデストラクタ呼ばれるか?
きちんと廃棄させたいなら、例外投げるなり汁。
>>647 まぁ、そんな感じです。
>>648 ありがとうございます、そうしますわ。
てか、exitでデストラクタでないんすね。
使ったことないから知らなかったよ。
Linuxのスレッドはスケジューリングあたりに欠陥があると聞いてたんですが、 RedHat Linux9は大丈夫でしょうか?
誰から聞いたんだろうか・・・どうせスラドあたりかな
初めてお邪魔します。ちょっと変なことをお聞きするようですが、よろしく。 Basilisk II という 68K Mac のエミュレータがあります。インストールして 起動すると、Mac の画面が出て、Mac らしい操作ができますが、winXP で他の アプリケーションを起動して終えて元に戻ったとき、復帰しないことがあります。 win98 では、この現象が出ないように思えます。 エミュレーションは、ソースを見ると、起動後スレッドを次々に立てて、mutex で管理しているようです。(出てくる画面にはタイトルバーがありますが、 メニューはありません。full screen 指定ならタイトルバーもありません。) よくある API application に付く WinProc はありません。 質問は、mutex によるスレッド管理で、winXP になって、何か変わったことは あるのでしょうか。因みに Basilisk II は、winXP には正式に対応していな いふしがあります。
>>651 スラドって何?
Linuxスレッドの欠陥って有名な話じゃないんですか?
>>652 俺の知る限りはない。
つかあったら困る。
>スケジューリングあたりに欠陥があると聞いてた どのあたりだ?w
>>654 ありがとうございました。
よく分かっていないもんで、あれこれ疑心暗鬼になっています。
別の要因を当たってみます。
>>657 例えば、
>>656 が指してるあたりに書いてあるけど、
スレッド群がmutexの奪い合いでスイッチするような作りだと、
OSのバージョンによっては動作が変わるかもしれんよ。
XPになってからHT対応が入ってるし。
>>655 >>656 ちょっと違うような・・・
SMPでスレッドをスケジューリングするとき、今までキャッシュを持ってたCPUに
そのスレッドが再び割り当てられるとは限らないって聞いたんだけど。
Solarisなんかだとキャッシュを考慮して割り当てするらしいんだけど。
よくわからなかったら無視してください。
それは欠陥とは言わないような・・・
最新のLinuxでは改善されてるって聞いたけど知りませんか?
知ってどうするんだ? 別にcache coherenceに問題が出るわけでもなかろうが…
>>658 ぎくっ。また引き戻されそう。
スレッドに強くないところへ持って来て、他人の作ったものは余計分かりません。
ま、エミュレータで、ドライバを動かすところは、スレッド立ててブン投げれば
処理が楽になりそうですが、winXP 側の都合で Mac に例えば、UpdateWindow を
やらせるようには出来ませんから、変にはなるだろうと想像しています。
MASM があれば、再コンパイルして、記録を取って見たいところです。
>>662 どうしもしません。ただ知りたいだけです。
アルゴリズムの高速化のプログラム書こうとすると影響すると思うんですが・・・
自分で実験してたしかめてみます。
>>665 あ、そう。
じゃあ/usr/src/linux*/Documentation/sched-design.txt読みなよ。
後、sched_*(2)辺りのAPIも一通り。
あなたがどこかで読んだ
> Linuxのスレッドはスケジューリングあたりに欠陥がある
なんてのは、「〜は〜の局面で〜なので〜である」の
「〜である」だけ流布しているバカ話なので、
常に上で示したような原典に当たることをおすすめします。
それが出来ない人はprogrammerとしてはずっとタコのままなので。
それから、threadへのCPU割当て親密性のことはprocessor/thread affinityと言います。
googleする時はこの単語を使ってください。
固定の場合はhard processor affinityなんて言います。
>>666 アドバイスありがとうございます。
参考にします。
>>650 その通り、 Linuxは欠陥品です RedHatでもなんでも同じです。
Windowsでプログラミングをしてるんですが あるint型の変数xについて、スレッドT1は書き込みのみ x = a; スレッドT2は読み込みのみ b = x; このような場合は、xについてT1,T2を排他処理する必要が あるのでしょうか? いらないんじゃないかと思ったのですが… それから、xがレジスタ1個では表現できないおおきさの 構造体の変数だったとしても(例えばintを4つ含む構造体) やっぱりいらないのでしょうか?
以前、全く同じ質問を見た気がするのでログ読みよろしく
>>493 でされている質問とおなじかも
しりたかたったことがだいたいわかりました
>>669 > このような場合は、xについてT1,T2を排他処理する必要があるのでしょうか?
シングルプロセサなら排他不要。
マルチプロセサでもint型がバス幅以下でミスアライメントしてなければ排他不要。
> 構造体の変数だったとしても(例えばintを4つ含む構造体) やっぱりいらないのでしょうか?
その4個の int が1組で意味を持つ (例えば 128bit 整数値とか) なら排他は必要。
> シングルプロセサなら排他不要。 コレはウソ、というのが493あたりからで出てたぞ。
>>673 > コレはウソ、というのが493あたりからで出てたぞ。
>> 498 の
> 書きこむ時は、どっかのメモリにの内容をレジスタに読み出して目的のメモリに
> 書き出すのが一般的だから、1命令で終わるとは思えないし、その間に
> dispatch が発生したらおかしなことになりかねないと思う。
のことかな ?
>>498 が言う、「どっかのメモリ」と「目的のメモリ」が関連しているような場合は
当然排他が必要だけど、目的のメモリだけが共有されてるケースなら、「目的
のメモリに書き込むのは1命令で終わる」から、問題はないよ。
あと、i++ とかのケースは当然ダメだけど、
>>669 は「スレッドT1は書き込みの
み」って言ってるから、これは該当しないしね。
>>674 i++をするスレッドが一つだけで、他は全部iを読み込むだけだったら
問題ないんじゃない?
>>> 498 の >> 書きこむ時は、どっかのメモリにの内容をレジスタに読み出して目的のメモリに >> 書き出すのが一般的だから、1命令で終わるとは思えないし、その間に >> dispatch が発生したらおかしなことになりかねないと思う。 > >のことかな ? ちがう。ちゃんとスレ全部読め。
やだよ、そんな面倒なこと。 指摘したいなら、ちゃんとレス番書け。
680 :
デフォルトの名無しさん :04/05/16 16:18
C++でpthread_cleanup_push/popって使ってOKでしたっけ? docs.sun.com見ると、とりあえずSolarisは問題ないみたいなこと書いてありますが。
C++全般には何の規定もないでしょ。 $(GCC)/libstdc++-v3/testsuite/thread/pthread*.cc ではテストしてないね。
682 :
デフォルトの名無しさん :04/05/20 16:07
疑問なんだけど、マルチスレッドって、コンテクスト切り替えするためには、 ローカル変数とかも全部覚えておかないといけないわけなんだよね。 普通どうやって実装されてるの? スタックをスレッドの本数分確保して、スレッド切り替えのときに スタックポインタも変えてるの? ということは見方を変えれば、schemeとかの「継続」と一緒? なら、マルチスレッドで待ち合わせとかをうまく使えば、 C(C++)で、継続みたいなことが実現できるの? 結局やりたいのは、関数呼び出しの外から内へのlongjumpみたいのなんだけど。 漏れ、かなり理解が甘いと思うので、全然見当違いなことを言ってるかも。
見当違いじゃない。 継続をマルチスレッドでやるのは効率が悪い。やろうと思えば出来る。 マルチスレッド環境を継続で実現するのは、Schemeなんかで良く行われる。
Ruby の継続はスレッドの流用だった様な。
なるほど。一般的にはそうなんですね。 で、今やりたいことを具体的に書くと、 CAB圧縮ファイルの伸張ライブラリ(Microsoft CabSDK)を使ってるんだけど、 これって、メモリ上に展開できるのはいいんだけど、途中まで展開してその結果を逐次利用みたいなことができないみたい。 ちょっと省略してイメージ的に書くと、 FDICopy(char* cabfilename, void (*writefunc)(char* data, int size)); みたいな関数を呼ぶと、ある程度まとまった量が展開されるたびに、 展開が終了したdataとsizeを引数にして、writefuncで指定したコールバックが呼ばれる。 writefuncでユーザーがdataをファイルに書き出すなり、好きなとこにコピーするなりすればいい。 て感じの仕組みになってる。 で、問題なのは、ファイル全体を完全に展開し終わるまで、FDICopy()自体からはリターンしない。 なんで、結局メモリ上に展開しようとしたら、展開後のファイルの大きさのバッファを確保しておいて、 いったん完全にメモリいコピーするしかないみたい。 そうじゃなくて、zlibみたいにちょっとだけ展開してその結果を使ってなんかして、また展開みたいにしたい。 (かなり大きなファイルなので、全部メモリに展開するのは厳しい。) んで、FDICopy()を別スレッドで動かして、writefuncが呼ばれるたびに、 スレッドを切り替えて、途中結果を利用して終わったら、 またFDICopy()に戻る、みたいなことってできるのかな、っと思ったんだけど。 こういうのって、他に、なんかいい方法とかありまつか?
マルチスレッドなら、UNIXのpipe風にpipeline同期処理、 # 並列処理(あるいはOS)の教科書のring buffer見れば載っている。 シングルスレッドならdesign patternにずばりlazy evaluationってのがある。
なるほどずばり、pipeline同期ってのがあるんですね。 windows用のライブラリとかあるんですかね。 lazy evaluationってどんなやつですか? 値が必要になってから計算すること?Haskelみたいなやつ? それと、今回のとどう関係するのかわかんないです。 デザインパターンのlazy evaluationってのはどんなやつなんですか?
FDICopy()だけ別スレッドで動かすより writefuncでの処理も含めて全部別スレッドにして 親スレッドは処理の終了を待つだけにしたほうが シンプルで速いと思うけど。
>>682 Win32 を使っているのならば、スレッドではなく、Fiber を使ってみたらどうだろう?
>>680 > C++でpthread_cleanup_push/popって使ってOKでしたっけ?
> docs.sun.com見ると、とりあえずSolarisは問題ないみたいなこと書いてありますが。
例外とのからみでなんかあったかも。あとデストラクタが呼ばれるかとか
そのへんでもなんかあったかも。Boost.Threadはキャンセルサポートしてないね。
ACEはcancelあるみたいだけど、どういう仕組みになってんのかね。
695 :
デフォルトの名無しさん :04/05/24 01:13
NPTLのソースコードってどこからダウソできるんでしょうか? 教えてください。
WINNY
>>696 > WINNY
サンクス。FC2のglibcのsrc.rpmの中には入ってたわ。
sem_wait(sem); pthread_mutex_lock(mutex); この2つをアトミックにしたいのです sem_wait()から起き上がったら 誰にも邪魔されずにpthread_mutex_lock()できるように。 この間だけSCHED_FIFOの最高プライオリティにすることで 対処しようとしていますが、あってますか? 注 アトミックにすることなんて考えないで その2つをpthread_cond_wait()に置き換えるというのは もう除外されてます。
>>699 > もう除外されてます。
じゃあ無理です。
701 :
デフォルトの名無しさん :04/06/03 09:14
UNIX/Pthreadでのプログラミングについて参考となるソースコードを 探しています。しかしBindとApacheみたいな限定されたアプリケーションしか まだPthreadを使っていないですよね。UNIXのPthread対応がまちまちなのが 原因なのはよく分りますが。他に何か良いもの(コンパクトで良質なソース)が ありますでしょうか?
703 :
デフォルトの名無しさん :04/06/04 06:39
以下の仕様はスレッドセーフなのでしょうか? 複数のスレッドが参照するグローバル変数がある。 一つのスレッドのみがこの値を変えることができ、他のスレッドは参照するのみである。 クリティカルセッション等はいっさい使用していない。 よろしくお願いします。
そのグローバル変数がintであるなど、読み書きがアトミックであるなら。 # アトミックなアクセス=アクセス操作が二つに分割されない。 atomic dataのone write-locking, many read-lockingってやつです。
64bit以上やクラス変数等は結構やばいですな。
>>704 , 705
ありがとうございます。
素直に排他処理しときます。
Winだとその場合アトミックなアクセスはやはりCriticalSectionしかない? 実質。
win32なら32bit以下の整数型や浮動少数型なら問題ないだろ。
そろそろWin64も考えないといかんのでは?
なんで? Win64/x86ならWoWでWin32アプリ動くし制限もきつくなる方向じゃなくて緩くなる方向じゃないか。
>>707 スピンカウント
LONG spin_count = 0; // どっかグローバルなところ。
void Lock()
{
while( ::InterlockedExchange( &spin_count, 1 ) != 0 )
Sleep(0);
}
void UnLock()
{
::InterlockedExchange( &spin_count, 0 );
}
NT4あたりからCriticalSectionにスピンカウントの機能が 付いてなかったっけ?
>>712 のはスピンロック。
いや用語なんて人によってつけ方いろいろなんでどうでもいいんだけど。
>>713 最初からWin32のEnterCriticalSection/LeaveCrtiticalSection
の内部実装は基本的にスピンロックを使ってる。
しかもリカーシブ。
Win32用語のスピンカウントってのは
マルチプロセッサ時にあるカウントを超えてスピンしようとしたときに
セマフォによるブロッキングに代わる。そのカウントのこと。
そのカウントを指定できるようにしたのが
>>713 がいうスピンカウント機能付き。(だと思う)
InitializeCriticalSectionAndSpinCount(),
SetCriticalSectionSpinCount()
でもこのスピンカウントはAPIで指定しなくても
レジストリのどこかで指定できると思った。
今時の malloc() って普通に使ってもスレッドセーフなの?
マルチスレッドライブラリをリンクすれば大丈夫でしょ。
>>716 thanx.
古い本にスレッド下で問題のある関数の例に malloc() が出ていたんで心配してました。
threadをclassでつかいたいんですが コンパイルがうまく通らないみたいです。 どなたかご教授お願いします。 class CHoge { public: bool Initialize(); private: void * Thread(void* param); // Thread専用 pthread_mutex_t m_mutex; // ミューテックス pthread_t m_tidx; pthread_attr_t m_attr; } ----- bool CHoge::Initialize() { pthread_mutex_init(&m_mutex, NULL); pthread_attr_init(&m_attr); pthread_create(&m_tidx, &m_attr, Thread, (void *)NULL); //ここでコンパイルエラー } void * CHoge::Thread(void* param) { //あんなことやこんなことを・・・ }
static void* Thread(void* param);
bool CHoge::Initialize() { pthread_mutex_init(&m_mutex, NULL); pthread_attr_init(&m_attr); pthread_create(&m_tidx, &m_attr, CHogeThread, (void *)this); //ここでコンパイルエラー } static void * CHogeThread(void* param) { CHoge *hoge = static_cast<CHoge*>(param); hoge->.... //あんなことやこんなことを・・・ }
>>719 staticつけるとコンパイルは通るのですがメンバーへのアクセスがうまくできないためだめみたいです・・・
>>720 クラスからはずしてClassのポインタを渡して実行するという手ですね。
なるほどです。ためしてみたのですが
privateメンバーへのアクセスが直接できないためpublicに移動(これはだめでしょ・・)
するかすべてにGetなんたらという関数を作成する形になってしまいます。
これではすこしきびしいようです。
friendにするってのはどうよ
>>718 pthread_create(&m_tidx, &m_attr, CHoge::Thread, (void *)this); //ここでコンパイルエラー
class CHoge { public: bool Initialize(); private: static void *Thread(void *param); // Thread専用 pthread_mutex_t m_mutex; // ミューテックス pthread_t m_tidx; pthread_attr_t m_attr; }; bool CHoge::Initialize() { pthread_mutex_init(&m_mutex, NULL); pthread_attr_init(&m_attr); pthread_create(&m_tidx, &m_attr, CHoge::Thread, (void *)this); } void *CHoge::Thread(void* param) { return NULL; }
#include <utility> class CHoge { . private: static void* StaticThread(void* param); void * Thread(void* param); . }; bool CHoge::Initialize() { std::pair<CHoge*, void*>* param = new std::pair<CHoge*, void*>; param ->first = this; param ->second = NULL; pthread_attr_init(&m_attr); pthread_create(&m_tidx, &m_attr, Thread, (void*)param); } /*static*/ void* CHoge::StaticThread(void* param) { void* return_value; std::pair<CHoge*, void*>* param2 = static_cast<std::pair<CHoge*, void*>*>(param); return_value = param2 ->first ->Thread(param2 ->second); delete param; return return_value; } コンパイルチェックしてないけど、どう?
これって、マルチスレッドの問題ではなくて C++でスタティックなコールバック関数を thisポインタつきのメンバー関数にどう置き換えるのか という問題でスレ違いとおもうのだが。。。 すれ違いついでにいうと、CHoge::StaticThread(void*)で CHoge::Thread(void*) が例外を投げたときに delete paramされるようにしたほうがいいか。
いろいろと試行錯誤をした結果うまく動くことができました。 問題はstaticで宣言したルーチンでstaticではないものを使用しようとした結果 怒られてたみたいなので、そこからもうひとつ関数を呼び出すことで対処できました。 助言ありがとうございました。 class CHoge { public: bool Initialize(); private: static void * Thread(void* param); //こいつはstaticで void ThreadMain(); //こいつでThreadのメイン処理を行う。 // Thread専用 pthread_mutex_t m_mutex; // ミューテックス pthread_t m_tidx; pthread_attr_t m_attr; }
----- bool CHoge::Initialize() { pthread_mutex_init(&m_mutex, NULL); pthread_attr_init(&m_attr); pthread_create(&m_tidx, &m_attr, CHoge::Thread, (void *)this); } void * CHoge::Thread(void* param) { CHoge *hoge = static_cast<CHoge*>(param); hoge->ThreadMain(); } void CHoge::ThreadMain() { //あんなことやこんなことを・・・ }
あげ
730 :
デフォルトの名無しさん :04/07/12 13:04
Windowsで、シングルスレッド、マルチスレッド両方に対応した ソースコードはどうやって書いたらいいのでしょうか? #ifdef _REENTRANT マルチスレッドを考慮したコード #else シングルスレッドだけ考えた軽いコード #endif みたいな、コンパイラから渡される_REENTRANTのようなマクロって ありますか?
731 :
デフォルトの名無しさん :04/07/12 13:22
732 :
デフォルトの名無しさん :04/07/12 13:31
733 :
デフォルトの名無しさん :04/07/24 17:09
MacOSX 10.3.*でpthread使ったプログラムをコンパイルするときに、 gccにて-pthreadオプションが使えないんですが、pthreadを使った プログラムはどうやってコンパイルすればいいですか?
>>733 -pthreadなくてよかったんじゃなかった?
>>733 #include <pthread.h>のみ
man gccするとplatform固有のoption一覧あり。
>>734 >>735 普通にコンパイルするだけで動きました。
ありがとうございます。
#ライブラリがもともとthread safe に出来てるってことなのかなぁ?
>>736 > #ライブラリがもともとthread safe に出来てるってことなのかなぁ?
全てのライブラリ? まさか…
MT-Safeかどうかは、それぞれの関数のmanを参照せよ。
最近は_REENTRANTっていらないの?
OSによるんじゃない。 HP-UXでも11i辺りから「_REENTRANTはobsoleteだ」とかmanに 書いてあったような。
>> #ライブラリがもともとthread safe に出来てるってことなのかなぁ? > >全てのライブラリ? まさか… >MT-Safeかどうかは、それぞれの関数のmanを参照せよ。 それぞれのって、1個ずつ・・・orz libc_r..aみたいな、thread safeなライブラリ群ってないのですね。
MACH をベースに採用したのは成功だったのかな。
portベースのドラエもんとかアプリがあるよ。 portはpeerのidentityが分かるから認証系には有利だな。
743 :
デフォルトの名無しさん :04/08/28 02:34
保守
744 :
デフォルトの名無しさん :04/08/30 01:57
Win32(MFC)でプログラムを組んでおります。 Sleepからの復帰はResumeThreadでは無理なのでしょうか。
ポカーン
>>744 イベント使ってタイムアウト付で待機しとけ
747 :
デフォルトの名無しさん :04/08/30 20:54
>>746 ありがとうございました。
やはり処理系によってちがうのですね。
処理系関係ない 知ったかぶんな
>SuspendThread >解説 >関数が成功すると、スレッドのサスペンドカウントが 1 増やされます。 >ResumeThread >スレッドのサスペンドカウントを 1 減らします。サスペンドカウントが 0 になると、スレッドが実行されます。 そしてSleepの説明ではサスペンドカウントについて何も書かれていない。 頭悪いな。
Win32のクリティカルセクションで質問です いろいろサンプルを見た限りではInitializeCriticalSectionの後に 失敗したかどうかのチェックをしてないようなんですけど 失敗すると引数のポインタはNULLになってるとかいう事ってないんですか?
> 失敗すると引数のポインタはNULLになってるとかいう 呼び出し側のポインタを渡すんだが・・・何か勘違いしてないか?
MSDNみろ
InitializeCriticalSectionはエラーチェックできません。仕様です
そもそもエラーが出ること自体無いんだろうけど、 石橋を叩き壊すくらい用心深いならGetLastErrorを呼べばいい
なるほど・・・ あんまり気にしないで先に進みます
>>756 Windowsスレッドの場合定石以外に知っとくこと多いから
最大公約数的な本みてもあまり役に立たない。
スレッドとメッセージループの関係とか、カーネルハンドルとか・・
やっぱWinならオライリーのやつがええの?
重要なのはメッセージループでなくて、メッセージキューの作成されるタイミングでは? カーネルハンドルって何ぞや?
>>758-760 Winのスレッドの使い方と、マルチスレッドのパターンって全く分野が違うと思うんだが
なぜにそんな話が出てくるんだ?
> 全く分野が違うと んなこたーない
数論と試算くらい違う物じゃないか。
764 :
デフォルトの名無しさん :04/09/09 17:54
板違いかもしれませんが宜しくお願いします。 現在UNIXのforkを多用したマルチプロセスプログラムをWindows(VC++)に 移植しています。 親玉のプロセスが、画面や通信などシステム上必要な全てのプロセスをforkで 生成する構造です。 Windowsにはforkが無いので変わりにスレッドで代用しようと考えているの ですが、staticやグローバル変数の排他の問題を上手く対処さえすれば それ以外でスレッドに変えた事による問題はないのでしょうか? 他になにか考慮が必要な点などありましたらアドバイスお願いします。
スレッドがすっ飛ぶ=そのプロセスがすっ飛ぶ
設定による。SetErrorModeだかでスレッド単位で殺す事もできる。
>>764 fork()してヒープとスタックの複製が出来たということは、
単に排他をすればいいというものではなくて、
別のメモリオブジェクトになっているという事ですが、
それは了解済みですか?
それからFILE *の扱いは、
> staticやグローバル変数の排他の問題
には収まりきらない部分もあるので注意が必要です。
>767 ありがとうございます。 書かれた内容は「UNIX上では別オブジェクトで分かれていたメモリ領域が、 スレッドになる事によって1つになり共用されてしまう事の重要性」 と認識したのですが合っていますでしょうか? FILE*の扱いについてはよく分かりませんでした。 概要や調べるキーワードで結構ですので教えてもらえませんか。 構造をばらしてプロセス数分のプロジェクトを作ったほうが確実なのかと 思い始めてきました。目の前が暗いです。。。。
>768 別プロセスでいいならそのほうがいいんじゃない? 無駄だとは思うけど、堅牢性は上。
>>768 子プロセスへは記憶域をコピーできないので、
子プロセス起動時に環境変数にして渡すか、
親側で共有メモリを作っておいて子側で開始時に共有メモリを読み取る。
どっちにしろ親の設計が、記憶域にアドレス情報を含むオブジェクトだった場合は、かなり厳しい。
グローバル変数はこれでどうにかなるとして、問題は関数内のスタティック変数。
関数の設計から見なおす必要が出てくる危険もある。
ただ、多くの場合、子プロセスは親と同じプロシージャを全部必要とするわけではないので、
親と子で共通する変数・関数を各プロジェクトから独立したヘッダ&ソースに記述するのがよいでしょう。
771 :
デフォルトの名無しさん :04/09/27 17:13:54
MPIを学ぶのに最適なサイトなどを教えてください
>>771 「MPI並列プログラミング」って本がある.
あとは「MPI」「並列」とかでググればいくつか出てくるよ.
ってか,MPIとマルチスレッドって関係あった?
774 :
デフォルトの名無しさん :04/09/29 05:04:08
並列プログラミングスレを別に立てるべきだろうな
今ならグリッドじゃね?
776 :
デフォルトの名無しさん :04/09/29 12:21:55
マルチドレッス
>>764 スレッドをまたいでSendMessageするときは受け側(CreateWindowを呼び出した時のスレッド)がメッセージループ内にいなければならず
ロックしやすいかも
下のプログラムのように、グローバル変数でスレッドを制御するのは 問題ありますか? それとも、ちゃんとmutex使うかCANCELしたほうがいい? EXTERN func_C(); bool bLoop; // bLoopは参照のみ func_B() { while ( bLoop ) { func_C(); } } // スレッド生成&bLoopを操作 func_A() { pthread_t thread; bLoop = true; pthread_create( &thread, NULL, func_A, NULL ); sleep(10); bLoop = false; pthread_join( thread ); }
最悪
>789 何のためにmutexがあるのかよく読んで来い
mutex使うのが普通なんでしょうけど、高速化のテクニックにこういうの あるのかな?という質問です。(いなくなった人のソースなので、意図が・・) bLoopの操作はfunc_A()だけでアトミックだろうし、毎回bLoopをチェック するごとにロックしないでも誤動作しないかも?とか思っちゃったわけでして。
最悪
>>779 どうしてもやりたいなら
volatile bool bLoop;
自分はpthreadしらないけどfunc_Bはどっからよばれるの?
>>779 「グローバル変数をあまり使うな」という普通の注意を別にすれば、全く問題ないよ。
高速化がどうとかいう以前の普通のコード。このパターンで mutex は出番ないでしょ。
volatile はまぁ好みでつけた方がよいとは思うけど。
>779 そもそもこれは何をしたいの? いちどだけFUNC_Cを実行したいということ? 10ミリセクに根拠はないし、while(bloop)でチェックするまでに10ミリセク経たない保証はないし きわめて悪質なバグを誘発する可能性のあるコードでないの?
pthread_createがFUNC_Bを呼ぶという前提で
お答えありがとうございます。
>>785 pthread_create()中のfunc_Aはfunc_Bの間違いです。はずかし;
「ハイパースレッディング・マルチプロセッサのシステムでは動作しません」 というソフトウエアをたまに見るが、その理由をいま目の当たりにしている訳だな。
そんなしょぼいソフトウェアが世の中に出ているとはじつに悲しいことです。
漏れがいままで見てきたソフトはスレッドがらみで必ず バグがあった。変な同期処理とかもいっぱい見てきた。
>>787 あくまでも例なのですが、10秒間funcCを呼び続けます。
(本当は任意のタイミングでbLoop=falseになります。)
簡単にキリのいいところ(funcCを呼び出す前)でthreadを終了できるのが
メリットなのかも?
>794 プログラムでマクロ時間を根拠に大丈夫だろうコードを書いてるとそのうち痛い目にあいますよ
10秒ならSleep(10000);じゃ?と突っ込んでみるテスト。
釣られてやるか。 sleep(3) は***秒単位***だ。
>>796 藻前アフォだろ
大文字と小文字の区別もできないのか?
800 :
デフォルトの名無しさん :04/09/30 22:47:10
funcCがどんな処理なのかによるじゃん。 なかでsleepしてるならbLoopを落としてもそんなに早く、即!、抜けるわけじゃないし。 ビジーループだたらガクブル
802 :
デフォルトの名無しさん :04/09/30 22:49:53
>>787にミリセクって書いてあるじゃないか!
>>802 は適当なことを言う人を信用して痛い目にあうタイプ
そもそも
>>787 は質問者じゃないし自分で勝手に勘違いしてるだけ
そもそもナニコレ。マトリョーシカ? func_A() { pthread_create( &thread, NULL, func_A, NULL ); }
結局誰一人としてもここにまともにスレッドが分かる人はいませんでした。おしまい。
前にも spinlock 知らなくて「ビジーループしてるし(w」とか言ってた人とかいたしね。
(↑別スレかもしれん)
それはともかくとして、
>>779 はとりあえずセマフォで通知するようにでもしとけば、
SMP でも問題なくなると思う。
(゚Д゚)ハァ?
>>809 apacheのヤツ?あれは割禁してないとかそういう話しではないの?
812 :
デフォルトの名無しさん :04/10/02 11:16:18
>>779 func_A から例外を送出することは可能ですか?
強制的にスレッドを停止させずに終了処理したいところなんですが。
もしかしてfunc_Bに?
Javaなら可能なんですが
Win32のマルチスレッドPGについて質問します 以下の、ソースをコンパイルしようとしたのですが、 _beginthreadex が定義されていませんというエラーが出ます。 process.hはインクルードしてるのですが 何が問題なのでしょうか? コンパイラはVC6.0とBCC5.5です
/*----ソース前半*/ #include <windows.h> #include <process.h> #include <stdio.h> unsigned _stdcall ChildThreadProcedure(LPVOID lpMutex){ //引数をミューテックスバンドルに変換 HANDLE hMutex=(HANDLE)lpMutex; //このスレッドのID DWORD dwThreadId=GetCurrentThreadId(); //3回 for(int n=0; n<3 ; n++){ //ミューテックス獲得を待つ DWORD dwResult=WaitForSingleObject(hMutex,INFINITE); if(dwResult==WAIT_OBJECT_0){ printf("Thread 0x%08x - acquired the mutex.\n",dwThreadId); Sleep(500); printf("Thread 0x%08x - releasing the mutex.\n",dwThreadId); ReleaseMutex(hMutex); Sleep(500); }else{ printf("Thread 0x%08x - error calling WaitForSingleObject().\n", dwThreadId); return 0xffffffff; } } return 0; }
/*後半*/ int main(void){ HANDLE hChildThread[3]; HANDLE hMutex; //ミューテックス作成 hMutex=CreateMutex(NULL,FALSE,NULL); if(hMutex==NULL){ printf("Primart thread - error calling CreateMutex().\n"); exit(0xffffffff); } //子スレッド作成 unsigned uUnusedThreadId; hChildThread[0]=(HANDLE)_beginthreadex(NULL,0,ChildThreadProcedure,(void*)hMutex,0,&uUnusedThreadId); hChildThread[1]=(HANDLE)_beginthreadex(NULL,0,ChildThreadProcedure,(void*)hMutex,0,&uUnusedThreadId); hChildThread[2]=(HANDLE)_beginthreadex(NULL,0,ChildThreadProcedure,(void*)hMutex,0,&uUnusedThreadId); if(!hChildThread[0] || !hChildThread[1] || !hChildThread[2]){ printf("Primary thrad - error creating child thread.\n"); exit(0xffffffff); } //全てのハンドルを閉じる CloseHandle(hMutex); CloseHandle(hChildThread[0]); CloseHandle(hChildThread[1]); CloseHandle(hChildThread[2]); return 0; } /*以上*/
>815 process.hを胃袋に穴が開くほどよく読め。
>818 process.hにはプロトタイプ宣言 unsigned long _RTLENTRY _EXPFUNC _beginthreadex(void *__security_attr, unsigned __stksize, unsigned (__stdcall *__start)(void *), void *__arg, unsigned __create_flags, unsigned *__thread_id); がありますが、やはりよく分かりません。 もう少しヒントお願いします。
>819 それはまだ胃袋に穴が開くほど読んでいない。 が、それだけだとあんまりなのでヒント。 "CPPを使ってみな。"
コンソールアプリをウィザードでプロジェクト作成した場合、
シングルスレッドとしてコンパイルする設定になる。
>>815 はデフォルトのままでプロジェクトをビルドしようとしているに、10000ペソ。
コンパイルオプションが必要だったのですね。 オプションを設定したら、コンパイルできました。 ありがとうございました。
>822 なんで解答*だけ*を教えるような真似するかな。。。 それだと何が起きてるかさっぱり理解できないままだから 何も力が付かないんだけどな。
>>824 いいんだよそれで。力のつく人間はほっといても力がつく。
ここは学校じゃないしね。
そもそも「_beginthreadex 定義」で検索するとすぐ出てくるしな。
たぶんエラーメッセージも
> '_beginthreadex' : 定義されていない識別子です。
> 外部シンボル "__beginthreadex" は未解決です。
で、
>>815 > _beginthreadex
> が定義されていませんというエラーが出ます。
正確には写してないんだろうな。
>>824 そんなことはないだろ。お前のやり方は単なる時間のムダだ。
お前に新人指導は無理。
>>822 はヒントを言ったが、どこの項目をどう変更すべきかは一切触れてない。
>>820 にみたいに的外れな"CPP"がどうとか言ってたのはお前じゃないよな?
天然で"CPP"と回答したとしたらかなり笑える。プゲラ
>>820
漏れは殆どの場合、答えだけを教えてやる。 しかも ad-hoc な解決法だけだ。 少し苦労してでも調べれば、根本の部分から解決できる問題を 調べもせずに質問するような中途半端な似非クソグラマには 「本当の力」なんてつけさせてやんねー。 質問地獄に陥るって? 漏れなら別にかまわん。 面倒くさい時は「わかんねー。ごめんなw」で済ませている。 プロジェクトが滞ってるのは、その似非クソグラマのせいだ。 ちなみに真の意味での世界最臭のクソは、漏れだw
>820のいっている CPPを使えっていう意味がさっぱりわからんのだが、 どういう意味なんだ? C++使えって意味か? ソースみれば、C++で書かれてるのなんて明らかじゃないか。
というか、コンパイルオプションを設定するかどうかのどの辺が 問題解決の本質的問題なのかと 子一時間問い詰めたい。
>>829 アレな言い分ではあるけど、たぶんインクルードしたヘッダで確かに _beginthreadex が
宣言されているかどうか、cpp 通したあとの出力を見てみろ、ということだと思う。
漏れの手元の処理系には cpp なんて無いけどね。
・自分が苦しんだ以上に他人を苦しめたい。
・若い芽を摘み取りたい。
・最近とみに目が霞んで、若手よりコーディングが遅くなって危機感に襲われている。
このうちのどれだ?
>>824 よ。
他人をオモチャにして遊びたいだけでしょ。
834 :
デフォルトの名無しさん :04/10/06 18:00:51
メモリモデルについて教えてください。
http://blogs.msdn.com/cbrumme/archive/2003/05/17/51445.aspx いまこの記事を読んでいるんですが、結論としては、「x86や(現在の)IA64
では、メモリバリアなしのdouble checked lockingが安全」なのでしょうか?
あ、JavaやC#ではなくC++で書いた場合を想定しています。
また、実際に上記のようなdouble checked lockingが誤動作するプロ
セッサはあるのでしょうか?ARMやPPCやAlphaでは誤動作します?
コンパイラは妙なinstructionのreorderをしないと仮定してかまいません。
よろしくおねがいします。
>>834 Linux Kernel 関連のメーリングリストを読むと、どのようなプロセッサであっても、
(上のリンクや IBM のドキュメントにあるような理由とは異なりますが)チェック対象のメモリへの
書き込みが遅延させられることによる誤動作は発生し得ます・・・
ただし、メモリバリア処理を行わない排他手段が存在すれば、の話です。
実際には、クリティカルセクションに入るための処理、出るための処理は必然的にメモリバリアと
なるため、C++ やアセンブラでの double checked locking は(正しく書かれれば)常に正常に動作します。
↑は変な書き方でスマソ。 要は、Java や C# にあるような初期化に先んじてポインタ値がメモリに書かれるようなことが無ければ、 C# でいうところの lock {} 等のアセンブラレベルでの実装がメモリバリアを(必然的に)兼ねてしまうので 問題の起こしようがない、というようなことです。
837 :
834 :04/10/06 23:10:56
>>836 レスありがとうございます。
まず、クリティカルセクション(やpthread_mutex_lock/unlock)がメモリバリアになるという点は了解です。
クリティカルセクションの入退場があれば、そこをまたぐようなreorder(コンパイラ/CPU両方の)は行わ
れないのですよね。
(
http://www.microsoft.com/whdc/driver/kernel/MPmem-barrier.mspx にもその旨明記してありました)
> 要は、Java や C# にあるような初期化に先んじてポインタ値がメモリに書かれるようなことが無ければ、
まさにそこ、「コンストラクタが走るより前にポインタ値がメモリに書かれる」ことがないか心配してます。
if(!instance) {
lock;
if(!instance) {
tmp = new T;
// (*)ここにメモリバリアを置かなくてOK?
instance = tmp;
}
unlock;
}
return instance;
の(*)の部分を心配しているという感じです。如何でしょうか?
>>835 > Linux Kernel 関連のメーリングリストを読むと、どのようなプロセッサであっても、
> (上のリンクや IBM のドキュメントにあるような理由とは異なりますが)チェック対象のメモリへの
> 書き込みが遅延させられることによる誤動作は発生し得ます・・・
ソースキボンヌ
>>837 C++ では代入文の中には sequence point が無いので、
一旦 temp に受けないとまずそうですよね。
でもメモリバリアは要らないんじゃないですか?
tmp = net T; の末尾が sequence point になるので、
instance = tmp より先に実行されることが C++ 的には保証されているから。
841 :
デフォルトの名無しさん :04/10/07 00:01:47
instance = new T; で問題ない
つーか、メモリバリア以前にコンパイラの最適化を理解してないみたいだな
845 :
デフォルトの名無しさん :04/10/07 00:32:13
834=841=842=元質問者です。
sequence point をキーにしたら良いペーパーを発見できました。
ありがとう>840さん
>Double-Checked Locking, Threads, Compiler Optimizations, and More
>
http://www.nwcpp.org/Downloads/2004/DCLP_notes.pdf が凄くすばらしいです。Scott Mayersさんがthanks to Doug Leaで書いたものなので
信用します。私の疑問にことごとく答えていますし。
結論としては、メモリバリアが必要ということで(p.29)。
ありがとうございました。
>>840 > tmp = net T; の末尾が sequence point になるので、
> instance = tmp より先に実行されることが C++ 的には保証されているから。
カレントスレッドからはそのように見えることが保証される、ってだけで
他のスレッドからもそのような順序で見えるってことまでは保証されていないはず。
何言ってんだこのバカは
もう池沼かよ
>結論としては、メモリバリアが必要ということで(p.29)。 おまえとんだ誤解してるぞ
854 :
834 :04/10/07 00:57:41
>>853 読み間違っていますか?特に移植性は問題にしてないんですが…。
特定のCPUで動けば。
あ、それとも参照している先の文章が間違っている?
tmp = net T; instance = tmp ; まずこの式がこのままである保障は全くない。 tmpの値が他で使われなければ省略される。 シーケンスポイント(副作用完了点)はこの場合関係ない。 よって instance = net T; と等価。
856 :
834 :04/10/07 01:15:27
>>855 (=853?)
それは承知してます(例のpdfのp.16でも言及されています)。
メモリバリアを挟むことを前提で
>>837 はtmpを使って書きました。
他にもなにかあればお願いします。
言葉が足りないかもしれないので補足。 コンパイラの最適化を妨げる、コンパイラに固有のなにかを挿入するつもりです。 例えばgcc+IA64なら tmp = new T; __asm__ __volatile__("mf":::"memory"); instance = tmp; どうでしょう?
そもそも837のソースはtmp不要 外側のif(!instance) {も不要
>>858 > そもそも837のソースはtmp不要
> 外側のif(!instance) {も不要
その通りなんですが、パフォーマンスを稼ぎたいんですよね。
…正確に言うと、某CPUが数発のマシンでDCLを(バリアなしで)使ってる人に、バリア使うか858のように書き直せと言いたいんです。そのための調査をしていまして。
自分はどちらかというと858派ですと付け加えておきます。基本的にはパフォーマンスより安全・確実な方を選びたいですね。
#完全synchronizeのペナルティがイヤならTLSにでもポインタいれとけばぁ?と思う。
>>858 元質問は↓コレな罠
>「x86や(現在の)IA64
>では、メモリバリアなしのdouble checked lockingが安全」なのでしょうか?
おあとがよろしいようで。
じゃあ、外側のif(!instance) {は安全。 Lockにコスト掛かるならそれでいいよ。 それとLock中にinstanceをどう扱おうがメモリバリアは不要。 つまりtmp不要。
>>862 つまり
if(!instance) {
lock;
if(!instance) {
instance = new T;
}
unlock;
}
return instance;
で良いということ?
>>863 IA32,IA64共にそれで問題ない。
>>864 >ARMやPPCやAlphaでは誤動作します?
は?
@じゃあ、外側のif(!instance) {は安全。 AそれとLock中にinstanceをどう扱おうがメモリバリアは不要。 2の主張は正しいよ。でも、1のinstance参照はLockを伴っていないよ?なんで安全と思うのか知りたいところだ
volatile char *tmp = (char *)new T, *p = (char *)instance; int i; for (i < sizeof(instance)) *tmp++ = *p++; とかしない限り問題ない。
逆だった for (i < sizeof(instance)) *p++ = *tmp++;
(゚Д゚)ハァ?
寝ぼけてた int i = sizeof(instance); while (i--) *p++ = *tmp++;
突然何の話してるの?本気でわからん。
>>843 =844=850=855=858=862=864=867=868=870
872 :
ageてみる :04/10/07 02:04:32
個人的には865のみ重要
>>866 なんで安全じゃないと思うんだ?
思い込みばっかしてないで仕様書よめ。
875 :
デフォルトの名無しさん :04/10/07 02:29:19
>>837 > if(!instance) {
> lock;
> if(!instance) {
> tmp = new T;
> // (*)ここにメモリバリアを置かなくてOK?
> instance = tmp;
> }
> unlock;
> }
> return instance;
>
> の(*)の部分を心配しているという感じです。如何でしょうか?
厳密には、(*)にメモリバリアを置いただけでは不十分。
(*)だけだと「メインメモリへの書き出し順序」は保証されるが、
他のCPUがそれを読み込む順序までは保証されない。
とはいえ、IA32やIA64ではそんな心配は無用だが。
> ARMやPPCやAlphaでは誤動作します?
確かAlphaでは上記の現象が問題になる可能性があったと思うが、
ソースを失念した。スマソ。
876 :
デフォルトの名無しさん :04/10/07 02:36:23
話の流れだと Keyboard* Keyboard::instance() { Keyboard* temp = pInstance; // read pInstance Perform acquire; // prevent visibility of later mem. ops. // from preceding pInstance’s read if (temp == 0) { Lock L(args); if (pInstance == 0) { temp = new Keyboard; Perform release; // prevent visibility of earlier mem. ops // from succeeding pInstance’s write pInstance = temp; // write pInstance } } return pInstance; } らしい。 >875 SPARC系ってどうなんすかね
>>858 > 外側のif(!instance) {も不要
おいおい。
元々のお題がSingletonパターンなんだよ。
毎回lockしたらinstance()が遅いだろ。
878 :
デフォルトの名無しさん :04/10/07 12:05:43
>>875 > 厳密には、(*)にメモリバリアを置いただけでは不十分。
> (*)だけだと「メインメモリへの書き出し順序」は保証されるが、
> 他のCPUがそれを読み込む順序までは保証されない。
>
> とはいえ、IA32やIA64ではそんな心配は無用だが。
IA32/64でも、(*)の部分のバリアだけは必要なんでつか?
おしえてください。
>>875 つまりこういう問題がある?
・CPU A は首尾よく instance の初期化を完了。メモリバリアでメモリへ全てを書き出す。
・CPU B は Double-Checked Locking を開始。変数 instance がキャッシュに乗っていなくてメモリから読む
・instance の指す先のメモリはたまたまCPU Bのキャッシュに残っていて(内容はゴミ)、instance->bar() とかでアボーン。
よく考えれば、変数 instance だけではなく、それが指すオブジェクト自体他のCPUでコンストラクトされている(可能性がある)わけだから、
利用に先立って少なくともreadキャッシュの無効化が必要だよなぁ。
>>877 > おいおい。
> 元々のお題がSingletonパターンなんだよ。
> 毎回lockしたらinstance()が遅いだろ。
SingletonパターンというかDCLパターンだね。
つーか
>>843 =844=850=855=858=862=864=867=868=870=873 は放置の方向で。
>>879 WindowsやPOSIX準拠OSが動く環境は、普通はcache coherentです。
つまりreadキャッシュの無効化だとかなんだとかはH/Wで自動解決されるから
プルグルマは気にしなくていい。
気にしないといけないのは、"他CPUからみて、自CPUがどのような順番でメモリ
を読み書きしたように見えるか"。そういう他CPUの観測具合を制御するのがメモリ
バリア。
細かいけど…。
あと、クリティカルセクションとかPOSIXのmutex_lock/unlockなどは暗に メモリバリアだから、「複数スレッドが触る変数を操作するのは常にクリ ティカルセクション内にする」を徹底すればプルグルマは楽をできる。 というか、普通のプログラマにハードウェアの詳細、メモリモデルについ て知っておけというのはムリなので、そうするのが良いアイディア。bool 変数だからロックしなくていいよね?とかよく聞かれるけど、俺は常に ダメだちゃんとロック汁と返答しがち。 DCLもプロファイリングしてボルトネークになってることが確定しない 限りは考えないほうがいいようにおもう。どっかで出てたように最悪 TLSでキャッシュすればよろし。
>>880 酷い言われようだが、俺が突っ込んだ書き込みして呼び水にならなかったら
おまえらは全然動かなかったろ。>865辺りからやっと湧いて出たアホども
ありがたく思えよ>834
837の神は840じゃないのかなぁ。843は口調が煽りすぎでしょ。
ところで、
「
>>840 は間違っていて tmp = XXX; instance = tmp は結局 instance = XXX;
に最適化される(してもよい)ので無意味」
って感じのレスがあったけど、これ本当ですか?
XXX が副作用をともなうコードであって、かつ ; のところが end of full expression でシーケンスポイントなんだから、
最適化によって instance = XXX と同じコードになろうがなるまいが、instance への書き込みがオブジェクトの
初期化に先んじることはないと思うんだけど(SMPでのメモリバリアの問題は別として)。
哲学者の食事って有名なんですか?
有名と思うよ。大学の講義でも真っ先に出てきたし。
まるちスレッドの本なら大抵その小話が入る
> > ARMやPPCやAlphaでは誤動作します?
> 確かAlphaでは上記の現象が問題になる可能性があったと思うが、
ソース見つけた。
http://www.cs.umd.edu/~pugh/java/memoryModel/AlphaReordering.html つーか>841のページからおもいっきりリンクされてるし。
>>882 > DCLもプロファイリングしてボルトネークになってることが確定しない
> 限りは考えないほうがいいようにおもう。どっかで出てたように最悪
> TLSでキャッシュすればよろし。
もしくは、pthread_once(3)のようなシステムが用意してくれてるAPIを使うとか。
DCLが有効なアーキテクチャではpthread_once()の内部でDCLを使ってるかもしれんが、
使う側からはそういう内部実装を一切気にしなくて良い。
>>878 > IA32/64でも、(*)の部分のバリアだけは必要なんでつか?
> おしえてください。
他の人も言っているように、IA32/64なら(*)の部分のバリア無しでもちゃんと動く。
ただし、IA32ならMTRRという機能があって、こいつを使うと
Out of Orderなメモリ書き出しなどができるようになる。
これを使うと、メモリアクセスの性能は大幅に向上する(XFree86 3.xを使ってた人なら
よく知ってるだろう)が、DCLのようなアルゴリズムは全く動かなくなってしまう。
>>889 LinuxThreadsのpthread_onceの実装はモロに使ってます>DCL
MTRRってそういう意味だったのか!!!
目から鱗〜
ところで
>>834 のリンク先のblogを見ると、IA64は本来weak ordering
なのだが現在のCPUはそうなってないとか書いてあるけど、そのへん
どう思います?
よみ違ってたらスマソ
893 :
デフォルトの名無しさん :04/10/08 13:08:12
MTRRについて詳しく書いてあるページないですか
マルチスッドレリアルリアリティ
もってロリロリ
そういやそろそろ超先生の一周忌だね
正直、どうでもいい
おらいりの
900 :
デフォルトの名無しさん :04/10/09 12:22:23
まるちすれっどって難しいですね みなさんが仕事でマルチスレッドを使う割合ってどれぐらいですか?
7306ぐらい。
おれはJSPを使っているから自動的に使っていることになるな。
JSPてナニ?
Japan Super Prototype
Japanese Sweet Pussy
Jewish Smelly Penis
>>907 それはSunのコンパイラが使いものにならないことの証明でしかない。
>>907 まぁCPUによらず、コンパイラの最適化抑制はしときましょうってことで。
gccなら asm("":::"memory");
911 :
デフォルトの名無しさん :04/10/10 19:26:50
>910 VC++とSun純正のC++コンパイラの場合は?
元記事よくよめよアフォ
915 :
デフォルトの名無しさん :04/10/11 11:06:48
おしえてよ
スレッドを複数起動してそれぞれのスレッドを任意に一時停止、再開したり するにはどうしたら良いですか? 例えばa,b,cのスレッドがあってまずスレッドaを起動して何処か途中 任意でスレッドbにスイッチ(スレッドaはそこで一時停止)、同じ様に スレッドbからスレッドcにスイッチ、スレッドcからスレッドaへスイッチすると スレッドaの途中から再開みたいな動きです。
あ、すんません。 環境:VC++6.0 OS:Windows2000 CPU:Pen4 って感じです。
>>919 ファイバですか・・・ちょっと調べてみます。
ありがとうございました。
ファイバ.NETからでも使えるのか?
922 :
デフォルトの名無しさん :04/10/11 13:02:25
コルーチソ
ファイバとマイクロスレッドの違いがわかりません
924 :
デフォルトの名無しさん :04/10/11 14:33:33
一緒
マイクロスレッドの利点がいまいち見えない コンテキスト切り替えを任意のタイミングでできると 何かうれしいことがあるの?
926 :
デフォルトの名無しさん :04/10/11 14:45:09
>>925 発想が逆。
スレッドは落とし穴が多いし重い(マイクロスレッドより)から使いたく
ないけど、並列処理もどきは行いたいことがある。コンテキスト切り替え
が嬉しいのではなくて、コンテキスト切り替えの面倒を被ってでも「気楽
で軽いスレッド」が欲しい。
…といったところか?
おまえ質問に対する回答の仕方がなってないな 疑問符で終らすなヴォケ
>>925 コルーチン(マイクロスレッド、ファイバ)パターンで記述すると
楽なものに対して使う。
________ /::::::/l:l ─- 、::::;;;;;;;;;`゙゙''‐ 、 __,,,,......,,,,_/:::::::::/: !| . : : : : : : `゙'ヽ、:::゙ヾ´::::::::::::::::::::::`゙゙゙'''‐'、. l| 、、 . : : : : : : : : r'":::::::::::::::::::::::::,r':ぃ::::ヽ::::::::ヽ! ,、- 、 .ヽ:゙ヽ; : : : : : :ノ:::::::::::::::::::::;;、-、、゙::: rー-:'、 / }¬、 . \::゙、: : : :./::::::::::::::;、-''":::::::::: ,...,:::,::., :::':、 _,,/,, ,、.,/ } ヽ:ヽ、 /::::::::::::::::::::::::: _ `゙''‐''" __,,',,,,___ /~ ヾ::::ツ,、-/ `ヽ、:::::::::;;;、、--‐‐'''''',,iニ- _| 、-l、,},,  ̄""'''¬-, ' ''‐-、 .,ノ'゙,i';;;;ツ _,,,、-‐l'''"´:::::::' ,、-'" ,.X,_,,、-v'"''゙''yr-ヽ / ゙゙'ヽ、, ,.' j゙,,, ´ 7 ,、-''" .l:::::::::::;、-''" ,.-' ゙、""ヾ'r-;;:l 冫、 ヽ、 / __,,.ノ:::::ヽ. / パターンだって。(ヴァカ?) l;、-'゙: ,/ ゞ=‐'"~゙゙') ./. \ / '''"/::::;:::;r-''‐ヽ ,、‐゙ ヽ:::::..,.r'゙ ,,. ,r/ ./ ヽ. ,' '、ノ''" ノ ,、‐'゙ ン;"::::::. "´ '゙ ´ / ゙、 ,' / ' //::::::::: {. V / / ./::::::::::::: ', / / . / /:::::::::::::::::. ',. / ,.、 /
ヽ、.三 ミニ、_ ___ _,. ‐'´//-─=====-、ヾ /ヽ
,.‐'´ `''‐- 、._ヽ /.i ∠,. -─;==:- 、ゝ‐;----// ヾ.、
[ |、! /' ̄r'bゝ}二. {`´ '´__ (_Y_),. |.r-'‐┬‐l l⌒ | }
゙l |`} ..:ヽ--゙‐´リ ̄ヽd、 ''''  ̄ ̄ |l !ニ! !⌒ //
. i.! l .::::: ソ;;:.. ヽ、._ _,ノ' ゞ)ノ./
` ー==--‐'´(__,. ..、  ̄ ̄ ̄ i/‐'/
i .:::ト、  ̄ ´ l、_/::|
! |: |
ヽ ー‐==:ニニニ⊃ !:: ト、
おれたちはとんでもない思い違いをしていたようだ。これを見てみろ。
まず「クソスレ」を英字で表記する
『KUSOSURE』
これを逆にすると、
『ERUSOSUK』
そしてこれを更に日本語に直すと
『エルソサク』
スレを立てたのが
>>1 と言う事を考えれば末尾に『クソスレ』を加えるのが当然だ。
すると導き出される解は
『エルソサククソスレ』
そして最後の仕上げに意味不明な文字『エルソサク』
これはノイズと考えられるので削除し残りの文字を取り出す。
するとできあがる言葉は・・・・・・『クソスレ』。
つまり!『クソスレ』とは『まさにこのスレッド』を表す言葉だったのだ!!
>>925 [cppll:6196] マイクロスレッド
を見るのがいいとおもうんだけど、いま過去ログサーバが落ちてるね。
>931 始めてみた.吹いた.不覚だ。。。orz
始めてみた 初めてみた
936 :
デフォルトの名無しさん :04/10/14 13:23:37
pthreadを使ったもっとも簡単なプログラムを教えてください
#include <pthread.h> int main () { pthread_exit(0); }
自作のライブラリ作る時、スレッドセーフかどうか ちゃんと確認して作ってますか?
君は確認してなかったの?
スレッドセーフなコードしか書かない
スレッドセーフと言っても色々ある リエントラントにしただけのもあるし、 スレッド間で共有するリソースの競合まで吟味したものもある 最初から意識して作るしかないだろう
スレッドセーフかどうか自分のソースコードを見ても確認できないなどというのはおかしい。 潜在するロジック上のバグと違い、スレッド関連は明らかにヒューマンエラー。
>>943 ええっ!?
ロッキングロジック上の馬具は一体何?
ヒューマンエラー
結局シングルトンのインスタンスはどう返せばいいんだろ
class Singleton { private: static Singleton instance; Singleton(); public: static Singleton getInstance(); }; Singleton::Singleton() { } static Singleton Singleton::getInstance() { if(instance == null){ LOCK(); if(instance == null){ instance = new Singleton(); } UNLOCK(); } return instance; }
DCLなんてしてないでイニシャライズとファイナライズをmainとかに書いとけばいいじゃん。 シンプルだし、最適化がどーのなんて悩まないで済むんだし。
それはシングルトンの場合でしょ。 それで済むときはそれで構わない。 # 但しシングルトンの時も、シングルトン間の初期化の順序を制御したい場合、 # 動的に確保されるシングルトンの場合はダメ。 またDCLはオブジェクトがある条件を満たした時に、 初めて行われるポインタメンバーの初期化などに必要。
>>942 > 最初から意識して作るしかないだろう
同一のインスタンスに対する並行アクセスはダメ、というケースはよく見るね
使う側からすると、下手にロックされても困る場合もあるから
ライブラリの設計は難しい・・・
過疎スレなのにそんなに早く次スレ立ててどうするの?
950過ぎたんだから別に何時立とうがどうでもいい話だな
スレッド立てる前にちゃんとロックしてね。
いやむしろマルチスレッドで
デッドロックする予感
食学者の哲事問題で
Pthread_mutex_lock(CriticalSection);
Pthread_mutex_lock(CriticalSection);
960 :
デフォルトの名無しさん :04/10/18 08:45:36
駄目な環境と宝刀#ifdefで区切ればいいじゃん
#ifdef LINUX #include <linux/compiler.h> barrier(); #elifdef XXX XXX(); #else #error Unknown system about memory barrier!!! #endif
どうやら話が振り出しに戻ったようですな。
966 :
デフォルトの名無しさん :04/10/18 23:17:34
俺はもうひらき直ってインスタンス返却関数に毎回ロック掛けてます
KeMemoryBarrier()が使えるのはドライバのみ?
>947 2重チェックなんか無駄でしょう。 このメソッドを連続して複数回呼ぶとしたらそのつくりがおかしい メソッド全体にロックかければ十分
>>969 すでにインスタンス作ったのにインスタンス取得の度にロックするほうが時間の無駄でしょうが
getInstanceをループの中で毎回呼ぶのですか? そうはしないし、それならば多少時間がかかっても問題がない。 無意味な最適化をするとバグを混入する原因となりかねないのでシンプルにしたほうがいいと考えています。
>>971 >getInstanceをループの中で毎回呼ぶのですか?
ハァ?(゚Д゚)
>>getInstanceをループの中で毎回呼ぶのですか? > >ハァ?(゚Д゚) ハァ?(゚Д゚)。Lock処理で何ミリセク処理時間が増えるか知らんが、その呼び出しが問題になるほど繰り返し呼び出すとしたら呼び出してるほうが問題なんだろうが。 キャッシュするなりすればいいという意味だろ。
>>973 なるべく透過的にキャッシュしたいね、という話をしているわけだが。
俺としてはガイシュツのTLSがいいとおもうね。
976 :
デフォルトの名無しさん :04/10/19 15:14:08
DCLもしらん厨房は早く寝ろ。
>>977 $ WRITE SYS$OUTPUT "VMS使いのおじいさんですか?"
>>977 DCL使ってプロジェクトを破滅に追いやるオマエ茂名。
980 :
デフォルトの名無しさん :04/10/20 11:53:49
windowsでもunixでもコンパイルできるマルチスレッドプログラムはどのように書けばよいのでしょうか?
Ruby!!!!!!!!!!!!
そーいや、なんでRubyなんだろうな。 まともな言語だって思ってたんだけど、2ch見てるとHSPと同じような位置にしか見えない。 C++なぞ問題外発言の所為?
スレッドをどのくらいまでなら作っても大丈夫なんですかね。 木構造の接点それぞれにスレッドを割り当てるプログラムで、 枝接点は、ほとんど何もしないラッパー的なスレッドで、 主な処理は、葉接点にあたるスレッドが行うというものですが、 重い葉接点スレッドの実行数を制限すれば、全体で数百〜千スレッド逝っても大丈夫でしょうか。
環境依存
>>983 >木構造の接点それぞれにスレッドを割り当てるプログラムで、
>枝接点は、ほとんど何もしないラッパー的なスレッドで、
>主な処理は、葉接点にあたるスレッドが行うというものですが、
まあ、話のタネに聞いておくが、
何でそんなものが必要なんだ?
>>982 アンチC++やアンチPerl色が強すぎてある意味宗教じみてた頃があったからかな?
今はどうなのか知らないけど
>>985 汎用的な処理を行うシェルのようなプログラムを作成しているのですが、
階層別にグループ化が必須なので。
で、スレッド暴走時の対処や、ある階層以下のすべてのスレッドに命令、セキュリティは?
とか考えると、ルートを一つにするよりも、全部スレッドにしたほうがいいかなと思いまして。
まあ、どっちにしろ最大スレッド数あたりを設定して、そこからあふれた場合はキューにためておいて、
スレッド数が減ってきたら、キューから読んでスレッド作成という動作を実装する必要がありますが。
スレッド必要な理由がよくわからんのですが・・・
selectやpollでwaitできないデバイスを扱うのに必要なんだよ。ボウヤ。
shellならprocess作って走らせるだけだからthreadは複数要らんってことなんじゃね?
pthread_barrier_init(&b, NULL, 8人); pthread_barrier_wait(&b); std::2ch << "1000ゲット!!" << std::endl;