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

このエントリーをはてなブックマークに追加
1デフォルトの名無しさん
マルチスレッドプログラミングについて語るスレ。
OS・言語・環境は問わないが、それゆえ明記すべし。

これといったリンク先がないので>>2はブラクラ。
22:02/11/19 01:20
つーか前スレのリンクぐらい貼れバーカ。
3デフォルトの名無しさん:02/11/19 01:21
重複してる(;_;)
41:02/11/19 01:29
重複したのでこちらは「マルチタレントプログラミング相談室」となります。
重複したのでこちらは「マルチのプログラミング相談室」となります。
後の始末はオタな方々が行ってくれるでしょう。
61:02/11/19 01:31
ええと、ここが最初に立ったっぽいので、ここを残して他は削除依頼を
だします。すみませんです。
前スレのリンクぐらい貼れバカ

マルチスレッドプログラミング相談室
http://pc3.2ch.net/test/read.cgi/tech/997345868/
スレ立て荒らしの1をアクセス規制するよう要望板に報告してきます。
91:02/11/19 01:36
>>7
ハァ? 逝けや
>>8
おながいします。
111:02/11/19 01:38
削除依頼出しました。
>>7
ありがとうございます。
マルチたんハァハァ
マルチのプログラムを作ってくれるのはこのスレですかっ!?
ここは削除依頼を出しました。

こちらが本スレになる予定です
http://pc3.2ch.net/test/read.cgi/tech/1037636602/l50

お手数かけてすみません。
763復活希望
重複したのでこちらは「マルチすれっど対策プログラミング相談室」となります。
後の始末は削除な方々が行ってくれるでしょう。
↓この「移転したよ。。。」ってスレ何なの?
C/C++で、pthread_mutex_lock(...) した関数から抜けるとき、
unlock(...)することを保証するにはどうしたらよいでしょう?
returnで返る前には自分でunlockしていますが、longjmpやthrow
のときにはunlockされないので困っています。
C++なんかで保証させようと思う方が間違っている。
>>18
無理。Java使え。
longjmpされると不可能だが、throwだと「全部catchする」っていう書き方がなかったっけ?
↑ブラクラ
>>18
throwならデストラクタは実行される。
つーかそんなの全然マルチスレッドに限った話題じゃない。
デストラクタじゃだめだと思うけど…
出るときにロック壊しちゃって委員会?
ちがう。コンストラクタでlock、デストラクタでunlockするオブジェクトを作
るってこと。
C++のidiomを知らないんならARMから読み直せ。
27736:02/11/19 10:21
>>15
>763復活希望

×763
○736
2818:02/11/19 10:22
Cでは無理なんですね。
素直にJavaを使って書くことにします。
AutoLock {
public:
 AutoLock() { lock(); }
 ~AutoLock() { unlock(); }
};

F()
{
 try {
  AutoLock autoLock;
 } catch (...) {
  throw;
 }
}
>>27
763==736だがな。

>>28
つーか、スレ違い。
>>29
try, catchは要らないはず。
>>28
そうだぞ。正しいunlock()の仕方なんてスレ違いだぞ。
>>30
マルチスレッドに限った話題じゃないが、マルチスレッド
プログラミングで必要な話題ではあるだろう。
なにが「カラアゲうまうま」だあほじゃねーの?
えっらそーに。
>>33
すまん、それもそうだ。
>>34
カラアゲを冒涜すると頃すぞ。
また香ばしいのが虚勢をはってるなぁ
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.

意味不明なんですが
49736:02/11/22 13:39
よう!
カスども元気か?
>>48
PVOIDとLONGのサイズが一緒じゃない場合があるからだろ。
M$の64ビット環境では、longは32ビットのままじゃなかったっけ?
5148:02/11/22 15:35
>>50
そういう事ですか。さんくす。
64bitだと、intは32bitもしくは64bitでlongも64bitだと思ってました。
そういえば、LONG LONGなんてのがありましたね。
52デフォルトの名無しさん:02/11/22 20:49
Ruby以外のsureddoは糞
sureddo・・・( ´,_ゝ`)プッ
お前らのマルチスレッドプログラムで、XeonのHyperThreadingで
劇的に速くなった香具師はいますか?
5550:02/11/22 23:36
>>51
LONG LONGではなく、LONGLONGだね。

M$の場合は、longが32bitで、__int64が64ビット。
__int128なんかも予約されていたような気がする。

普通の64bitな処理系ではlongが64bit。
普通って何?
>>56
LP64という慣習に従った処理系。
>>56
50=55の脳内処理系のことでしょう。
少なくとも普通じゃない。
LP64って慣習だったのか・・・
6050:02/11/23 01:05
>>58
んじゃ、そうじゃない処理系挙げてみ。
64bit環境なら、SolarisもLinuxもTru64もHP-UXもlongは64bitだよ。
LP64は規格だよね。SUSの。
SUSって何?
ローカル規格団体?
Single Unix Specification
>>63
THX. unix方面限定ってことね。
>>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
>>68
それぞれどういう意味?
>>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
>>70
コンパイラはそれぞれ何?
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サポートしてるのは政府の入札を受けるためなんだから
そんな半端なことしては意味がないと思うんだが
strictly followsと言い切ってるが規格の年度まで述べてるのでセーフ。
http://support.microsoft.com/default.aspx?scid=KB;en-us;q149902
> The POSIX interface on Windows NT strictly follows
> the POSIX 1003.1-1990 standards.
つまり1003.1-1990 comformantであって1003.1:1990 comformant
ではないと。
間違えた
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
犬厨って何?
8785じゃないけど:02/12/01 02:26
>>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
>>105
× げいいん
○ げんいん(原因)
↓「おざなり」と「なおざり」の違いを述べよ。
ウリナラ
>>115
おまいは 「がいしゅつ」 とかもいちいち訂正するのかと
>>118
× がいしゅつ
○ きしゅつ(既出)
>>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 は大いに馬鹿にしたい。
138137:02/12/10 02:48
すまん。123。


でも、132 を馬鹿にしたいというのも正しいw
>>133
「ハードで」ならマルチスレッド化は可能?
>>139
マルチスレッドの意味わかってるか?
>>140
2Pとか3Pとか乱交とかそういう意味だろ?
インテルのHTってチムポが2本になるんだよな?
>>141
その通り。


おまいの脳内においてのみナー。
>>139
MultiscalerとかSKYとかの事を言ってるなら、
あれも「自動マルチスレッド化」ではない。
どの処理を並列実行できるか解析して自動的にマルチスレッド化してくれる OS、
いやせめてソースのトランスレータでもあれば随分ありがたいな。

・・・ほとんどあり得ないと思うけど。
プログラムがソースコードあるいは中間コード形式で配布されるようになれば、
並列最適化しながら実行することもできる・・・

かもしれない
>>145
まさか。だったらJavaでできてるはず。
C++でマルチスレッドを扱っているのですが、
クラス関数をスレッドとすることはできないのでしょうか

_beginthread(&LoadCharacterData, 0, NULL);

とやると
error C2276: '&' : 仮想関数のアドレスを取ろうとしました。
と起こられてしまいます
>>147
static関数にインスタンスのポインタを渡して、そっからメンバ関数を呼ぶ。
(´-`).。oO(微妙にマルチスレッドとは違う話だな。。。)
150144:02/12/11 17:42
> ・・・ほとんどあり得ないと思うけど。

つまり、人間に最適化できるならコンピュータにも最適化させる事ができるという事だ。
誰か挑戦する猛者は居ないか?
>>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
マルチスレッドなんだから
スレがいくつか平行に存在してていいじゃないか。
160 :02/12/17 05:47
>>158

TLS はそういうものじゃないし、効率はスタックの方がいいよ。
そもそも 158 の考えている使い方なら TLS なんかいらないでしょ。
>Thread-Specific Storage

Lどこー?
>>158
TLSって

Thread Local Storage

じゃなかったのか?
呼び名が混じってるな

TSD Thread Specific Data - pthread
TLS Thread Local Storage - Win32

どっちも同じもの。
164160:02/12/17 14:02
>>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みたいなことをしていれば足りなくなる可能性もある
>>169
プラグイン方式だったりしてもやばい
フライング方式に見えて一瞬何の事かわかりませんですた
172デフォルトの名無しさん:02/12/26 01:56
printfの遅さで、挙動が変わるような通信アプリ
のデバッグってどうやればよいのでしょうか?
>>172
それって
前スレとか前々スレとかで見かけた気がするぞ。
ネタか?
>>173

教えてやってよ
マルチスレッドと何か関係あるのか?
たしかに以前のスレで見た気がするな。
ネタじゃねえの。
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*);

とスレッド関数を作って内部で呼び出しても大丈夫でしょうか?
193192:03/01/07 17:36
パケットモニタソフトを作っているのですが、
ネットワークアダプタが複数ある場合、アダプタ毎にWSARecvするので
マルチスレッドを考えてるのですが、この場合マルチスレッドは必要ないでしょうか?
複数アダプタが検出された場合、クラスラッピングしておけば用意に必要本数ができるので上記の質問をしたのですが
何分知識不足で的外れな質問かもしれません・・

後、和書か訳本でマルチスレッドのお勧めの本とかありましたら宜しければ教えてください。<(_ _)>
>>192
VC++なら大丈夫。
195IP記録実験:03/01/08 22:22
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

     *  ※ ☆  ※   ※   ※  ☆ ※  *
    * ※ ☆ ※   ※ ☆ ※  ※ ☆ ※ *      
   * ※ ☆ ※  ※ ☆  .☆ ※  ※ ☆ ※ *
  * ※ ☆ ※ ※☆     ☆※ ※ ☆ ※ *
  * ※キタ━━━━━(゚∀゚)━━━━━ !!!※ *    
  * ※ ☆ ※ ※☆     ☆※ ※ ☆ ※ *
   * ※ ☆ ※  ※☆  .☆※  ※ ☆ ※ *   
    * ※ ☆ ※   ※ ☆ ※  ※ ☆ ※ *   
     *  ※ ☆  ※   ※   ※  ☆ ※  *
>>315
どうせネタだし
AA貼り付けそうな予感
>>443
できないです>責任逃れ
                   /\        /\
                   /:::::::ヽ____/::::::::ヽ、
                  丿 ::.__  .:::::::::::::  __  ::::ヽ_
                 / /。 ヽ_ヽ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
> マルチスレッドを考えてるのですが、

すればいいじゃん。その方が自然だし。
233山崎渉:03/01/13 18:29
(^^)
既出です
235山崎渉:03/01/15 17:53
(^^)
236デフォルトの名無しさん:03/01/18 08:18
山崎渉は逝ってよし!!
http://piza.2ch.net/test/read.cgi/comic/960295739/
何課あちこちのスレでスレと関係無いカキコが多いなー
NullPointerException が発生したら 「ぬるぽ」 と出力するようにしますた。
239山崎渉:03/01/23 20:11
(^^)
>>238
「もうぬるぽ」にしろ
>>238 >>240
ガッ
242デフォルトの名無しさん:03/01/27 00:53
HTA(JScript)でActiveXコンポーネントを利用して
ダウンローダを作ろうとしてます。

IEコンポーネントにURLを渡してhtmlファイルをDLすると
大量のURLがDL対象だと時間がかなりかかってしまいます・・。

そこで、複数のURLを配列に入れて、その配列を引数で渡したら
マルチスレッドで、それらのページ(画像とかじゃなくhtmlファイル)を
うりゃ〜っと高速DLしてくれるようなActiveXが作りたいのですが、
何をどうしていいのやら・・。

・このActiveX作成に最適な言語
・参考となりそうなサイトor書籍
・ヒント全般
・答え

など、教えていただけないでしょうか?
> うりゃ〜っと高速DL

( ゚д゚) ポカーン
OpenIrvineのソースでもみれば?
マルチスレッド化するだけで劇的に速くなると思ってるのだろうか?
レスポンス待ち時間の分くらいしか速くならないのに。
むしろ、コネクション数をうまく調整しないと却って遅くなるぞ。
CPU8個積んでますが何か?
>>246
だから何?
>>246
それで何?
>>246
つまり何?
>>246
すると何?
>>246
ならば何?
>>246
ぬるぽ何?
>>246
御何?
254名無し@沢村:03/01/28 01:32
>>246
呼んだ?
>>246
無効の竹垣に竹立てかけたのは竹立てかけたかったから?
>>246
256ゲットですが何か?
>>246
ひざまずけ、命乞いをしろ?
258名無し@沢村:03/01/28 23:58
>>246
MUTEXマンセー
このスレは今から、
>>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で同じコンテナインスタンスの反復子を
それぞれいじくっても平気か、ということだ。

>>265
もちつけ。
>>264がいいたいのはそういうことでは無いと思われ。
メインスレッドがBeginPaint()を実行して
サブスレッドがGetDC()を実行して
サブスレッドがGetDC()を実行しても
いいのでしょうか?

これらのAPIは、裏で排他処理をしていますか?

それともプログラマが排他処理をするべきですか?
>>267
Win32と仮定するが、オブジェクトによっては、それを作成した
スレッド以外のスレッドからのアクセスを禁止しているものがある。
通常は明示されているが、それぞれについて調べるしかない。

記述がない、確証がない、バグの原因になりそうならば、
排他するしかないだろう。
269267:03/02/16 20:16
>>268
Win32です。

質問が下手だったです…
えと、メインスレッドではWM_PAINTに応答を
しています。
ワーカースレッドで計算処理をしています。
この計算処理をすぐに表示したいときに
どうしようかなと…

ワーカースレッドでGetDC()をしようと思った時に
メインスレッドがWM_PAINTに応答しているかどうか
チェックするべきなのでしょうか?

私の勝手な予想だと、BeginPaint()がロックしているので
GetDC()が少しの間待機していて、EndPaint()が終了したら
GetDC()の待機が解けてGetDC()が成功するのでは…と
思っています。

ワーカースレッドが複数あったら、GetDC()の
取り合いが起きそうだけど…あっていますでしょうか?
GetDCとマルチスレッドの関係について調べたか?
調べてからにしてくれ。
271267:03/02/16 20:38
>>270
出直してきます…
ワーカースレッドで表示まで一緒にやらせようってのがそもそも
> メインスレッドがWM_PAINTに応答しているかどうか
> チェックするべきなのでしょうか?

応答してないような時にはきっと、描画なんかしてちゃいかんのだろうな。
>>267
取りあえず
http://msdn.microsoft.com/library/en-us/vcsample98/html/_sample_mfc_mtgdi.asp
辺りが参考になるかもね。
275267:03/02/18 21:41
ヘルプのマルチスレッドのところ読んできたよ…
>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 の環境です。
284283:03/04/03 02:01
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 では。
287283:03/04/03 03:22
>>285
1CPUだと256MBの初期化に0.50秒かかるのですが2CPUだと
0.43秒ぐらいになります。何度も呼ばれるので少しは効果が
あると思って。それにP4とかはHTがあるのでひょっとして
効果があるかも。
自業自得
289283:03/04/03 04:07
beginthreadex()を使うように変更したら
まったく固まらないようになりました。
お騒がせしました。

何が違うんだろ・・・?
クローズしたスレッドハンドルを操作したら
どうなるか想像もできないのか
コードも汚いしスレッド以前の問題だ
291283:03/04/03 05:26
http://www.microsoft.com/japan/msdn/library/default.asp?url=/japan/msdn/library/ja/vclib/html/_crt__beginthread.2c_._beginthreadex.asp
MSDNに_beginthreadexを使え、と書いてあった。

> _beginthread が作成したスレッドの終了が早すぎると、_beginthread の呼び出し元に返されるハンドルが無効となる可能性や
>>291
MSDNくらいよく読め。
基本だろ。
なんだライブラリのバグか。
>>293
バグではないのだが
>>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){}
>>300
ベンチ取ってから物言え
>>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 になってるから。
ただし排他は必要。
321316:03/04/14 17:03
>>317-320
皆さんありがとうございます。handle_ は
class Thread {
 HANDLE handle_;

となっていてコンストラクタで NULL に初期化されます。書き忘れ
失礼致しました。

_beginthreadex() が成功した時点でそれが保証されるんですね。
うまく行くということだと助かります。必要な排他処理というのは
begin() の入口と出口のことですよね。
この二つに分割して考えた方が分かりやすいんじゃ…
(1)スレッドが終了したらスレッドのハンドルを閉じる
(2)前のスレッドのハンドルが有効なら次のスレッドを開始しない
>>316
begin()を呼んでいるスレッドが複数あったりすると、それでは問題あるね。
まぁ、そんな実装しないと思うけど。
324山崎渉:03/04/17 15:26
(^^)
325山崎渉:03/04/20 04:32
   ∧_∧
  (  ^^ )< ぬるぽ(^^)
保守
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 がでてんなら、直接的な原因はわかるだろうからそこから逆に追っていけばいいんでは ?
331328:03/05/01 19:52
>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とうまく共存させる方法、
もしくは目的と達成する代替手段はないものでしょうか?
この辺、きちんと理解・解決するための、
何か良い資料等ございましたらお教えいただけないでしょうか?
335bloom:03/05/03 19:13
usleep?
usleepよりは nanosleepの方がいいような。
>>334
> signal, setitimer, sigpause 等を使っていたのが原因でした。

自分のプログラミングのせいじゃないと主張なさるわけか?
>>334
> 何とかpthreadとうまく共存させる方法、

仕様に従ってきちんと使う。
340334:03/05/04 17:17
>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準拠ちゃんと調べます。
正直、だいぶ昔に作ったパーツの使い回しだったので
この辺の問題、すっかり忘れてました。
>>340
> POSIX準拠ちゃんと調べます。

IBMのNGPT取り込んだkernelじゃないとPOSIX準拠にはならないけど、
http://www-124.ibm.com/pthreads/
たぶんどっちでも変わらん。
selectに関してはpthreadと併用できるはず.
POSIX 1003.1
ttp://www.linux.or.jp/JM/html/LDP_man-pages/man2/select.2.html
メンドッチイネ
timeGetTimeを複数のスレッドで使いたいんですが
その場合timeBeginPeriodを
そのスレッド数分やるべきでしょうか?
それともどれかのスレッドで一回だけやれば十分?
>344
一応、一回で十分。
timeBeginPeriod() はスレッドをまたいでも有効。
それどころか、プロセスをまたいでも有効。
>>344
何やるのかしんないけど、この辺は極めて怪しげ仕様なので、MSDNを熟読のこと。
というかMSDNさえ信用できない世界だ
timeBeginPeriodでぐぐるとサイトによって相反することが書いてたりするし
この場合MSDNに書いてあることがすべてだろ。

マルチスレッドだろうがなんだろうがtimeBeginPeriodを使ったら
それに対応するtimeEndPeriodを呼ばなければならない。

一回最初にやって複数スレッドで使いまわすなら、
すべてのスレッドが終わった後で最後にtimeEndPeriodを一回呼べばよい。

なんか実験してるサイトもあるが、みた感じ日本語のサイトはどれも
場当たり的で参考にならない。ゲーム系のプログラマってみんな
あんな感じなのか?
349デフォルトの名無しさん:03/05/10 16:30
UNIXのマルチスレッドプログラミングの勉強をしようと思うのですが、
どの本がオススメでしょうか?

私のレベルは、ようやくスレ立てと削除依頼が出せるようになった程度で
ageとsageをうまく使いこなせません。

現在使用している書籍は、Pthreadsプログラミング
ttp://www.amazon.co.jp/exec/obidos/ASIN/4900900664/ref=pd_bxgy_text_2/249-7564093-3835560
で、勉強したい内容は、
(銀行のシステムのように)ロックをかけて厳密な制御を施すよりは、
むしろ、負荷に応じてスレッドの優先順位をうまく調整するあたりなので、
もう一冊購入しようと考えています。

辞書的に使える本、ビギナーに優しい本なども紹介していただけると幸いです。
あと、この本は地雷だぞ、という情報についても……
>>349
> UNIXのマルチスレッドプログラミングの勉強をしようと思うのですが、

> 私のレベルは、ようやくスレ立てと削除依頼が出せるようになった程度で
> ageとsageをうまく使いこなせません。

ネタと言うことで良いか ?
> 負荷に応じてスレッドの優先順位をうまく調整する

UNIXでそれやるのはキツいような気がするナー
OS側の制約に翻弄されそうな予感。
OSやスレッドモデルによってスレッドの制御がどのように行われるか
よく理解した上でないとだめな場合もあるから、よく注意してやるがよい
353349:03/05/10 20:22
>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スレッド」って時点で怪しいよな。
>357
ほぼ非同期のスレッドが二つ並んでいて、
二つのCPUにそれぞれスレッドを割り当て
(つまり事実上、タスクスイッチしない)でも、
無理かな?

スレッドの優先順位を(root権限で)強制的に上げてやると、
ttp://kumagai.homeip.net/masaaki/research/library/linux/tips.html#setscheduler
10ms以下の制御が可能らしく、実際に試してそれを確認したのだが、
CPU一個だと他のタスクが完全に凍る。
でも、このホームページ曰く、マルチプロセッサだと
(ヲレは環境がなくて試せないが)他のタスクも機能してくれるらしい。
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使うなら変わらないと思うが。
374369:03/05/15 10:33
>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
>>398
逆です。あなたの言っているのはpthreadの仕様の方です。

linuxthreadはpthread規格に適合してません。
詳しくはhttp://pauillac.inria.fr/~xleroy/linuxthreadsで
400400:03/05/27 23:50
400
401山崎渉:03/05/28 12:34
     ∧_∧
ピュ.ー (  ^^ ) <これからも僕を応援して下さいね(^^)。
  =〔~∪ ̄ ̄〕
  = ◎――◎                      山崎渉
402デフォルトの名無しさん:03/05/28 21:39
ageとく
403t-akiyama:03/06/18 21:08
携帯ゲーム機"プレイステーションポータブル(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 最 強
保守
406山崎 渉:03/08/02 02:39
(^^)
407山崎 渉:03/08/15 17:20
    (⌒V⌒)
   │ ^ ^ │<これからも僕を応援して下さいね(^^)。
  ⊂|    |つ
   (_)(_)                      山崎パン
保守
マルチスレッドにおけるC++の例外処理の挙動ってどうなってるんでしょうか?
まずは自分で実験しる( ゚Д゚) とか言われそうですが、
コンパイラやOS依存とかだったらアレなので・・。
410 :03/09/20 13:59
例外処理はスレッド、というかスタックに対し行われるものだから、
スレッドごとにスタックが完全に独立していれば何も問題ない"はず"

あるスレッドで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
417414:03/09/25 11:39
>>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のスレッドはまともだと思うが。
423418:03/11/02 02:02
>>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はサードパーティのやつなんでバイナリしかない...)
429426:03/11/04 13:42
>>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
440430:03/11/06 22:42
>>431
ごめん、深読みして、スレッドを起こして監視するんだと思ってコード書いてたら
そのスレッド自体を止めるのかと考えがずれてしまった。

>>432
同意。

>>434
ほんとすまん。
スレッドまともに使えない癖にコード書いている香具師(全く排他処理しないとか、
TerminateThread使うとか)多くてイライラしてたんでつ。そういうことをやられて、
尻拭いしてみると、俺も気持ちも分かってもらえるかと。

>>438
変で悪かったなw 擁護無用。
441437:03/11/06 23:53
>>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
ロックされてるリソースに対して優先順位をつけたいってことか?
445441:03/11/07 15:01
>> 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
単にキャストしてるだけだろ。

以降はこのへんへ。

C言語なら私に聞け! Part 66
http://pc2.2ch.net/test/read.cgi/tech/1066560665/
C言語の第一歩
http://pc2.2ch.net/test/read.cgi/tech/1031374980/
>>450
どの辺が使えないんでしょうか?
>>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するスレッドはひとつでしょ
>>460
あふぉか
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
使おうとする関数が,スレッドセーフか否かって,ど→やって判断すんの?
たくさんのスレッドからその関数を使いまくっていじめてみる
476474:03/11/18 19:43
>>475
標準ライブラリからインクルードして利用する関数も全部そうするの?
そこまで,暇人じゃあねーんです.
どなたか,御教授くださいな.
OS書いてねん。
WindowsならMSDN
Solarisならman
PC-UNIXはmanに明記してなければ、source読め、かのぉ〜
478474:03/11/18 21:29
使用OSは linux redhat9.0 です.manを読みましたが,スレッドセーフかどうかまでは,記述されていませんでした.
やっぱり,ソースを1つずつ読んでいくしかねーのかなー?
労を惜しむなよ
>>476,478
stdioはMT-Safe。glibcのmanual読んでね。
481474:03/11/19 01:48
ところで、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使って作ったもんがあるから(業務用じゃないが)不安になってきた。
486 :03/11/26 23:35
487デフォルトの名無しさん:03/11/27 00:32
スレッドセーブについて教えてください

なに?何語??スレッドをセーブするの??

みたいな感じです。はい。
よろしく。
>>487
thread save = スレッド保存
永続化とか
>>421
まともなスレッドが実装されているOS
されていないOS
の例を教えてください。

>>490
必死だな(w
>>490
まともなスレッドが実装されているOS ⇒ NT, Mach
されていないOS ⇒ Unix, Linux, *BSD
Win32でマルチスレッドプログラムを初めて作ってみたのですが、排他処理について質問させてください。
変数に対してクリティカルセクションとかで排他にするのは
書き込んでいる途中のオブジェクトを読み込むと変になってしまったりするからですよね。

ということはたとえば、終了フラグなどの単純な値は排他処理しなくてもいいのですか?
>>492
(゚Д゚)ハァ? って書いて欲しかったのか?
495デフォルトの名無しさん:03/11/30 20:25
age
>>494
何か間違いでも?
>>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の命令がどうなってるかで対応が変わるわけですね。
スレッドの割り込ませ方がどうなっているかをまったく知らないのでなんですが、
割り込みが起こらないことが保障されているなら排他しなくてもよいと。
>>499
MkLinuxとか知らんのけ?
質問です。
複数のクライアントからの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走らせると他のに切り替えられなくなるんだが、
これもスケジューリングの話題に関係あるのか?
>>535
ソースきぼんぬ
>>533
もしかしてようやく優先順位キューが?
>>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
>>548
どうして禿だとわかった!?
>>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
としても、呼び出されたメソッドで例外がスローされても
こちらに飛ばないんです。
558556:04/02/18 00:51
うわ、二重カキコです。
お許しを。
559557:04/02/18 00:55
二重カキコです。お許しを。
しかも日本語が変です。

10行目
「普通、そこでこの例外をcatchできるんです。」
に訂正です。

最後の文もおかしいですね・・・
560559:04/02/18 00:57
本当にすみません。逝ってきます。
>>557
案の定。

理由は >>552 の通りで、新しいスレッド内でthrowされた例外は、
そのスレッド内でしかcatchできない。
557の後半のコードでcatchに来るとしたら、それはスレッドの生成に
失敗したときぐらいだろうね。

これが理解できないうちはスレッド使うのはやめといたほうがいい。
まあ、理解できたらできたでスレッドを使う気が失せると思うけど。
562557:04/02/18 17:06
>>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でも期待した結果になるかもよ。
pthreadでは明示的にpolicyとかを指定しない限り、
どのようにスケジューリングされるかは完全にシステム依存だからなあ。
だから、どんなに違和感があろうとも、Linux2.6の挙動は仕様的にアリですな。

スケジューリング方法をもっと細かく操作したいのなら、
pthread_setschedparam()とかで明示的にscheduling policyなどを
指定するしかない。
でも、現在のLinuxでは PTHREAD_SCOPE_SYSTEM なスレッドしか作れないから、
厳密なスケジューリングを期待するのはやっぱり難しい。

ttp://www.opengroup.org/onlinepubs/007904975/functions/xsh_chap02_08.html#tag_02_08_04
ttp://www.opengroup.org/onlinepubs/007904975/functions/xsh_chap02_09.html#tag_02_09_04_02
>>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)をスレッドセーフなグローバル変数としてガンガン
使うってのはちょっとまずそうな。。。
578575:04/02/28 01:03
>>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のためにいろいろなプラットフォームに移植されているみたいだけども。
>>593
というか、POSIX 1003.1-2003ではgethostbynameはObsolescentとされているし、
gethostbyname_rはそもそもない。
ttp://www.opengroup.org/onlinepubs/007904975/functions/gethostbyaddr.html
>>595
>そんなことを気にすんならスレッドの方が桁違いに処理系依存だろ
これは、そういう意味での "処理系依存" という話ではない訳で・・・

コンソールやキーボードは、そのライブラリがあって、かつ言語の規格に
準拠したコードを書いてさえいれば、その規格を満たしたコンパイラなら
確実に意図した動作をするコードを吐いてくれる筈。

しかしこの場合、ライブラリがあって、規格準拠のコンパイラを使って、
どんなに行儀の良いコードを書いても、動く「保障」がない、
というのが気持ち悪い。
だめだこりゃ
601595:04/03/02 00:31
>>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" って蔑まれるんだよ。
631628:04/03/14 02:22
>>629
( ゚Д゚)ハァ?お前の言うpure javaの意味書いてみろよ

>>630
「yield()書かないとコンテキストスイッチしません」って
環境で作らなきゃならないんなら、必要に応じて組み込むが、
あるとしても一部の異常な実装だろ。

そもそもyield()しなきゃいけない状況の方が特殊だろ。
無駄にbusy loopしまくりなプログラムでも書くのか?
> そもそもyield()しなきゃいけない状況の方が特殊だろ。

勝手に限定しないでくださいね。
633628:04/03/14 19:19
>>632
可愛そうに。。今時Non-preemptiveな環境で作ってるんだねぇ
それかまともな同期を実装できないおばかさんなんだね。
この規定はpure javaの規定であって、
実装系の話をされても困るんですがねぇ・・
>>634
>この規定はpure javaの規定であって、
>実装系の話をされても困るんですがねぇ・・

いや、もともと JAVA は環境というものについて
その程度の認識しか持たない(or 持てない)レベルの奴でも
必ず動くコードが書けるようになる、というのが設計理念だった筈。
だからこそ >>631 みたいな厨がわらわらと JAVA に群がってきた訳で。

これは JAVA 自体の設計ミスだな。
636628:04/03/14 22:34
だから、それのどこがPure Javaと関係あるんだっつーの
厨と言うなら、どこに問題があるのか正確に示してみろ
637デフォルトの名無しさん:04/03/23 18:00
Soralis2.6でスレッドのプログラム作ろうと思っているんですが
2.6ってスレッドに不具合が無かったですか?
昔に聞いた事があるような気がするのですが。。
教えて下さい。
638デフォルトの名無しさん:04/04/14 11:44
localtimeはスレッドセーフ関数では無いと聞いたのですが
gettimeofdayはスレッドセーフなのでしょうか?
教えて下さい。よろしくお願いします。
環境に依存する
マジレス
これ使ってる人います?
POSIX Threads for Win32
http://sources.redhat.com/pthreads-win32/
わざわざ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でローカル変数のデストラクタ呼ばれるか?
きちんと廃棄させたいなら、例外投げるなり汁。
649646:04/04/23 09:46
>>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
>>563-574辺りの話かね?
657652:04/04/24 06:50
>>654
ありがとうございました。
よく分かっていないもんで、あれこれ疑心暗鬼になっています。
別の要因を当たってみます。
>>657
例えば、>>656が指してるあたりに書いてあるけど、
スレッド群がmutexの奪い合いでスイッチするような作りだと、
OSのバージョンによっては動作が変わるかもしれんよ。
XPになってからHT対応が入ってるし。
>>655 >>656
ちょっと違うような・・・
SMPでスレッドをスケジューリングするとき、今までキャッシュを持ってたCPUに
そのスレッドが再び割り当てられるとは限らないって聞いたんだけど。
Solarisなんかだとキャッシュを考慮して割り当てするらしいんだけど。

よくわからなかったら無視してください。
それは欠陥とは言わないような・・・
最新のLinuxでは改善されてるって聞いたけど知りませんか?
知ってどうするんだ?
別にcache coherenceに問題が出るわけでもなかろうが…
>>660
禿道w
664652:04/04/24 15:37
>>658
ぎくっ。また引き戻されそう。
スレッドに強くないところへ持って来て、他人の作ったものは余計分かりません。
ま、エミュレータで、ドライバを動かすところは、スレッド立ててブン投げれば
処理が楽になりそうですが、winXP 側の都合で Mac に例えば、UpdateWindow を
やらせるようには出来ませんから、変にはなるだろうと想像しています。
MASM があれば、再コンパイルして、記録を取って見たいところです。
>>662
どうしもしません。ただ知りたいだけです。
アルゴリズムの高速化のプログラム書こうとすると影響すると思うんですが・・・
自分で実験してたしかめてみます。
666662:04/04/25 00:18
>>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つ含む構造体)
やっぱりいらないのでしょうか?
以前、全く同じ質問を見た気がするのでログ読みよろしく
671669:04/05/03 14:31
>>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を読み込むだけだったら
問題ないんじゃない?
>>675
それは>>674の最後の段落の繰り返しじゃない…
>>675
そだね。
>>> 498 の
>> 書きこむ時は、どっかのメモリにの内容をレジスタに読み出して目的のメモリに
>> 書き出すのが一般的だから、1命令で終わるとは思えないし、その間に
>> dispatch が発生したらおかしなことになりかねないと思う。
>
>のことかな ?

ちがう。ちゃんとスレ全部読め。
679単なる煽りかな ?:04/05/09 10:57
やだよ、そんな面倒なこと。
指摘したいなら、ちゃんとレス番書け。
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 の継続はスレッドの流用だった様な。
685682:04/05/21 02:35
なるほど。一般的にはそうなんですね。
で、今やりたいことを具体的に書くと、
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ってのがある。
687682:04/05/21 02:58
なるほどずばり、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あるみたいだけど、どういう仕組みになってんのかね。

>>691
スッドレには関係なさそうなお燗
>>692
http://www.dre.vanderbilt.edu/Doxygen/Current/html/ace/Asynch__Connector_8h-source.html
のコメントに「POSIXからは他のスレッドからキャンセルできる」って書いてあるよ。
695デフォルトの名無しさん:04/05/24 01:13
NPTLのソースコードってどこからダウソできるんでしょうか?
教えてください。
WINNY
>>696
> WINNY
サンクス。FC2のglibcのsrc.rpmの中には入ってたわ。
>>695
glibcに入ってるよ。
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対応がまちまちなのが
原因なのはよく分りますが。他に何か良いもの(コンパクトで良質なソース)が
ありますでしょうか?
>>701
?
703デフォルトの名無しさん:04/06/04 06:39
以下の仕様はスレッドセーフなのでしょうか?

複数のスレッドが参照するグローバル変数がある。
一つのスレッドのみがこの値を変えることができ、他のスレッドは参照するのみである。
クリティカルセッション等はいっさい使用していない。

よろしくお願いします。
そのグローバル変数がintであるなど、読み書きがアトミックであるなら。
# アトミックなアクセス=アクセス操作が二つに分割されない。

atomic dataのone write-locking, many read-lockingってやつです。
64bit以上やクラス変数等は結構やばいですな。
706703:04/06/04 08:31
>>704, 705
ありがとうございます。
素直に排他処理しときます。
Winだとその場合アトミックなアクセスはやはりCriticalSectionしかない?
実質。
win32なら32bit以下の整数型や浮動少数型なら問題ないだろ。
そろそろWin64も考えないといかんのでは?
なんで?
Win64/x86ならWoWでWin32アプリ動くし制限もきつくなる方向じゃなくて緩くなる方向じゃないか。
>>707
semaphore, mutex
>>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); //ここでコンパイルエラー
724723:04/06/14 20:18
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;
}
コンパイルチェックしてないけど、どう?
726725:04/06/14 20:29
これって、マルチスレッドの問題ではなくて
C++でスタティックなコールバック関数を
thisポインタつきのメンバー関数にどう置き換えるのか
という問題でスレ違いとおもうのだが。。。

すれ違いついでにいうと、CHoge::StaticThread(void*)で
CHoge::Thread(void*) が例外を投げたときに
delete paramされるようにしたほうがいいか。
727718:04/06/15 21:30
いろいろと試行錯誤をした結果うまく動くことができました。
問題は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;
}
728718:04/06/15 21:31
-----
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
>>730
#ifdef _MT
732デフォルトの名無しさん:04/07/12 13:31
>>731
ありがとう。早速やってみます。
733デフォルトの名無しさん:04/07/24 17:09
MacOSX 10.3.*でpthread使ったプログラムをコンパイルするときに、
gccにて-pthreadオプションが使えないんですが、pthreadを使った
プログラムはどうやってコンパイルすればいいですか?
>>733
-pthreadなくてよかったんじゃなかった?
>>733
#include <pthread.h>のみ

man gccするとplatform固有のoption一覧あり。
736733:04/07/24 17:41
>>734
>>735
普通にコンパイルするだけで動きました。
ありがとうございます。

#ライブラリがもともとthread safe に出来てるってことなのかなぁ?
>>736
> #ライブラリがもともとthread safe に出来てるってことなのかなぁ?

全てのライブラリ? まさか…
MT-Safeかどうかは、それぞれの関数のmanを参照せよ。
最近は_REENTRANTっていらないの?
OSによるんじゃない。
HP-UXでも11i辺りから「_REENTRANTはobsoleteだ」とかmanに
書いてあったような。
740733:04/07/26 10:42
>> #ライブラリがもともと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
ありがとうございました。
やはり処理系によってちがうのですね。
処理系関係ない
知ったかぶんな
749723:04/08/30 22:14
>SuspendThread
>解説
>関数が成功すると、スレッドのサスペンドカウントが 1 増やされます。

>ResumeThread
>スレッドのサスペンドカウントを 1 減らします。サスペンドカウントが 0 になると、スレッドが実行されます。

そしてSleepの説明ではサスペンドカウントについて何も書かれていない。
頭悪いな。
Win32のクリティカルセクションで質問です

いろいろサンプルを見た限りではInitializeCriticalSectionの後に
失敗したかどうかのチェックをしてないようなんですけど
失敗すると引数のポインタはNULLになってるとかいう事ってないんですか?
> 失敗すると引数のポインタはNULLになってるとかいう

呼び出し側のポインタを渡すんだが・・・何か勘違いしてないか?
MSDNみろ
InitializeCriticalSectionはエラーチェックできません。仕様です
そもそもエラーが出ること自体無いんだろうけど、
石橋を叩き壊すくらい用心深いならGetLastErrorを呼べばいい
755750:04/09/07 13:33
なるほど・・・
あんまり気にしないで先に進みます
ttp://www.hyuki.com/dp/cat_index.html#thread
こんな感じの、マルチスレッドの定石みたいなものを記したページってどこかに無いでしょうか?
>>756
その本買えば?
>>756
Windowsスレッドの場合定石以外に知っとくこと多いから
最大公約数的な本みてもあまり役に立たない。
スレッドとメッセージループの関係とか、カーネルハンドルとか・・
やっぱWinならオライリーのやつがええの?
重要なのはメッセージループでなくて、メッセージキューの作成されるタイミングでは?
カーネルハンドルって何ぞや?
>>758-760
Winのスレッドの使い方と、マルチスレッドのパターンって全く分野が違うと思うんだが
なぜにそんな話が出てくるんだ?
> 全く分野が違うと

んなこたーない
数論と試算くらい違う物じゃないか。
764デフォルトの名無しさん:04/09/09 17:54
板違いかもしれませんが宜しくお願いします。
現在UNIXのforkを多用したマルチプロセスプログラムをWindows(VC++)に
移植しています。
親玉のプロセスが、画面や通信などシステム上必要な全てのプロセスをforkで
生成する構造です。
Windowsにはforkが無いので変わりにスレッドで代用しようと考えているの
ですが、staticやグローバル変数の排他の問題を上手く対処さえすれば
それ以外でスレッドに変えた事による問題はないのでしょうか?
他になにか考慮が必要な点などありましたらアドバイスお願いします。
765在日参政権反対:04/09/09 18:01
スレッドがすっ飛ぶ=そのプロセスがすっ飛ぶ
設定による。SetErrorModeだかでスレッド単位で殺す事もできる。
>>764
fork()してヒープとスタックの複製が出来たということは、
単に排他をすればいいというものではなくて、
別のメモリオブジェクトになっているという事ですが、
それは了解済みですか?

それからFILE *の扱いは、

> staticやグローバル変数の排他の問題

には収まりきらない部分もあるので注意が必要です。
>767
ありがとうございます。

書かれた内容は「UNIX上では別オブジェクトで分かれていたメモリ領域が、
スレッドになる事によって1つになり共用されてしまう事の重要性」
と認識したのですが合っていますでしょうか?

FILE*の扱いについてはよく分かりませんでした。
概要や調べるキーワードで結構ですので教えてもらえませんか。

構造をばらしてプロセス数分のプロジェクトを作ったほうが確実なのかと
思い始めてきました。目の前が暗いです。。。。
769在日参政権反対:04/09/10 04:47
>768
別プロセスでいいならそのほうがいいんじゃない?
無駄だとは思うけど、堅牢性は上。
770デフォルトの名無しさん:04/09/13 02:20:22
>>768
子プロセスへは記憶域をコピーできないので、
子プロセス起動時に環境変数にして渡すか、
親側で共有メモリを作っておいて子側で開始時に共有メモリを読み取る。

どっちにしろ親の設計が、記憶域にアドレス情報を含むオブジェクトだった場合は、かなり厳しい。
グローバル変数はこれでどうにかなるとして、問題は関数内のスタティック変数。
関数の設計から見なおす必要が出てくる危険もある。

ただ、多くの場合、子プロセスは親と同じプロシージャを全部必要とするわけではないので、
親と子で共通する変数・関数を各プロジェクトから独立したヘッダ&ソースに記述するのがよいでしょう。
771デフォルトの名無しさん:04/09/27 17:13:54
MPIを学ぶのに最適なサイトなどを教えてください
772デフォルトの名無しさん:04/09/27 21:28:30
>>771
「MPI並列プログラミング」って本がある.
あとは「MPI」「並列」とかでググればいくつか出てくるよ.
ってか,MPIとマルチスレッドって関係あった?
773デフォルトの名無しさん:04/09/28 07:16:18
774デフォルトの名無しさん:04/09/29 05:04:08
並列プログラミングスレを別に立てるべきだろうな
775デフォルトの名無しさん:04/09/29 09:27:50
今ならグリッドじゃね?
776デフォルトの名無しさん:04/09/29 12:21:55
マルチドレッス
777デフォルトの名無しさん:04/09/29 22:19:07
>>764
小さなグローバル変数ならTLS( _declspec( thread ) )が便利。ただし fork のように値がコピーされないのが難。
http://support.microsoft.com/default.aspx?scid=kb;ja;409547
778デフォルトの名無しさん:04/09/29 22:28:32
>>764
スレッドをまたいでSendMessageするときは受け側(CreateWindowを呼び出した時のスレッド)がメッセージループ内にいなければならず
ロックしやすいかも
779デフォルトの名無しさん:04/09/30 13:49:09
下のプログラムのように、グローバル変数でスレッドを制御するのは
問題ありますか?
それとも、ちゃんと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 );
}
780デフォルトの名無しさん:04/09/30 13:52:09
最悪
781在日外国人参政権反対:04/09/30 13:59:18
>789
何のためにmutexがあるのかよく読んで来い
782779:04/09/30 14:17:33
mutex使うのが普通なんでしょうけど、高速化のテクニックにこういうの
あるのかな?という質問です。(いなくなった人のソースなので、意図が・・)

bLoopの操作はfunc_A()だけでアトミックだろうし、毎回bLoopをチェック
するごとにロックしないでも誤動作しないかも?とか思っちゃったわけでして。
783デフォルトの名無しさん:04/09/30 14:20:22
最悪
784デフォルトの名無しさん:04/09/30 14:42:25
>>779
どうしてもやりたいなら
volatile bool bLoop;
785デフォルトの名無しさん:04/09/30 20:44:34
自分はpthreadしらないけどfunc_Bはどっからよばれるの?
786デフォルトの名無しさん:04/09/30 20:54:48
>>779
「グローバル変数をあまり使うな」という普通の注意を別にすれば、全く問題ないよ。
高速化がどうとかいう以前の普通のコード。このパターンで mutex は出番ないでしょ。
volatile はまぁ好みでつけた方がよいとは思うけど。
787デフォルトの名無しさん:04/09/30 21:57:19
>779
そもそもこれは何をしたいの?
いちどだけFUNC_Cを実行したいということ?
10ミリセクに根拠はないし、while(bloop)でチェックするまでに10ミリセク経たない保証はないし
きわめて悪質なバグを誘発する可能性のあるコードでないの?
788787:04/09/30 21:58:08
pthread_createがFUNC_Bを呼ぶという前提で
789デフォルトの名無しさん:04/09/30 21:58:58
>>779
これSMPだとまずいんじゃないの?
790779:04/09/30 22:00:35
お答えありがとうございます。

>>785
pthread_create()中のfunc_Aはfunc_Bの間違いです。はずかし;
791デフォルトの名無しさん:04/09/30 22:06:16
「ハイパースレッディング・マルチプロセッサのシステムでは動作しません」
というソフトウエアをたまに見るが、その理由をいま目の当たりにしている訳だな。
792デフォルトの名無しさん:04/09/30 22:09:20
そんなしょぼいソフトウェアが世の中に出ているとはじつに悲しいことです。
793デフォルトの名無しさん:04/09/30 22:15:35
漏れがいままで見てきたソフトはスレッドがらみで必ず
バグがあった。変な同期処理とかもいっぱい見てきた。
794779:04/09/30 22:21:32
>>787
あくまでも例なのですが、10秒間funcCを呼び続けます。
(本当は任意のタイミングでbLoop=falseになります。)
簡単にキリのいいところ(funcCを呼び出す前)でthreadを終了できるのが
メリットなのかも?

795デフォルトの名無しさん:04/09/30 22:40:03
>794
プログラムでマクロ時間を根拠に大丈夫だろうコードを書いてるとそのうち痛い目にあいますよ
796デフォルトの名無しさん:04/09/30 22:45:04
10秒ならSleep(10000);じゃ?と突っ込んでみるテスト。
797デフォルトの名無しさん:04/09/30 22:46:23
釣られてやるか。

sleep(3) は***秒単位***だ。
798デフォルトの名無しさん:04/09/30 22:46:44
>>796
藻前アフォだろ
大文字と小文字の区別もできないのか?
799デフォルトの名無しさん:04/09/30 22:47:08
>>796
sleep(3)
800デフォルトの名無しさん:04/09/30 22:47:10
funcCがどんな処理なのかによるじゃん。
なかでsleepしてるならbLoopを落としてもそんなに早く、即!、抜けるわけじゃないし。
ビジーループだたらガクブル
801デフォルトの名無しさん:04/09/30 22:49:36
>>796はwindowsしか知らない
802デフォルトの名無しさん:04/09/30 22:49:53
>>787にミリセクって書いてあるじゃないか!
803デフォルトの名無しさん:04/09/30 22:50:50
>>787もwindowsしか知らない
804デフォルトの名無しさん:04/09/30 22:51:05
>>802は適当なことを言う人を信用して痛い目にあうタイプ
805デフォルトの名無しさん:04/09/30 22:51:34
そもそも>>787は質問者じゃないし自分で勝手に勘違いしてるだけ
806デフォルトの名無しさん:04/09/30 22:53:39
そもそもナニコレ。マトリョーシカ?
func_A()
{
 pthread_create( &thread, NULL, func_A, NULL );
}
807デフォルトの名無しさん:04/09/30 22:54:23
808デフォルトの名無しさん:04/09/30 22:55:04
結局誰一人としてもここにまともにスレッドが分かる人はいませんでした。おしまい。
809デフォルトの名無しさん:04/09/30 23:21:55
前にも spinlock 知らなくて「ビジーループしてるし(w」とか言ってた人とかいたしね。
(↑別スレかもしれん)

それはともかくとして、>>779 はとりあえずセマフォで通知するようにでもしとけば、
SMP でも問題なくなると思う。
810デフォルトの名無しさん:04/10/01 14:14:07
(゚Д゚)ハァ?
811デフォルトの名無しさん:04/10/02 10:58:13
>>809
apacheのヤツ?あれは割禁してないとかそういう話しではないの?
812デフォルトの名無しさん:04/10/02 11:16:18
>>779
func_A から例外を送出することは可能ですか?
強制的にスレッドを停止させずに終了処理したいところなんですが。
813デフォルトの名無しさん:04/10/02 11:20:48
もしかしてfunc_Bに?
814デフォルトの名無しさん:04/10/02 12:54:21
Javaなら可能なんですが
815デフォルトの名無しさん:04/10/03 18:43:49
Win32のマルチスレッドPGについて質問します
以下の、ソースをコンパイルしようとしたのですが、
_beginthreadex
が定義されていませんというエラーが出ます。
process.hはインクルードしてるのですが
何が問題なのでしょうか?

コンパイラはVC6.0とBCC5.5です
816デフォルトの名無しさん:04/10/03 18:45:34
/*----ソース前半*/
#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;
}
817デフォルトの名無しさん:04/10/03 18:47:17
/*後半*/
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;
}
/*以上*/
818デフォルトの名無しさん:04/10/03 19:02:28
>815
process.hを胃袋に穴が開くほどよく読め。
819デフォルトの名無しさん:04/10/03 20:46:22
>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);
がありますが、やはりよく分かりません。
もう少しヒントお願いします。
820デフォルトの名無しさん:04/10/03 21:02:31
>819
それはまだ胃袋に穴が開くほど読んでいない。
が、それだけだとあんまりなのでヒント。
"CPPを使ってみな。"
821デフォルトの名無しさん:04/10/03 21:09:28
>>815
というかそんなのはググれよ!
822デフォルトの名無しさん:04/10/03 21:20:21
コンソールアプリをウィザードでプロジェクト作成した場合、
シングルスレッドとしてコンパイルする設定になる。
>>815はデフォルトのままでプロジェクトをビルドしようとしているに、10000ペソ。
823デフォルトの名無しさん:04/10/04 00:41:56
コンパイルオプションが必要だったのですね。
オプションを設定したら、コンパイルできました。
ありがとうございました。
824デフォルトの名無しさん:04/10/04 08:38:47
>822
なんで解答*だけ*を教えるような真似するかな。。。
それだと何が起きてるかさっぱり理解できないままだから
何も力が付かないんだけどな。
825デフォルトの名無しさん:04/10/04 08:47:57
>>824
いいんだよそれで。力のつく人間はほっといても力がつく。
826デフォルトの名無しさん:04/10/04 09:32:02
ここは学校じゃないしね。
そもそも「_beginthreadex 定義」で検索するとすぐ出てくるしな。

たぶんエラーメッセージも
> '_beginthreadex' : 定義されていない識別子です。
> 外部シンボル "__beginthreadex" は未解決です。
で、

>>815
> _beginthreadex
> が定義されていませんというエラーが出ます。

正確には写してないんだろうな。
827デフォルトの名無しさん:04/10/04 10:04:55
>>824
そんなことはないだろ。お前のやり方は単なる時間のムダだ。
お前に新人指導は無理。
>>822はヒントを言ったが、どこの項目をどう変更すべきかは一切触れてない。
>>820にみたいに的外れな"CPP"がどうとか言ってたのはお前じゃないよな?
天然で"CPP"と回答したとしたらかなり笑える。プゲラ>>820
828デフォルトの名無しさん:04/10/04 14:39:47
漏れは殆どの場合、答えだけを教えてやる。
しかも ad-hoc な解決法だけだ。
少し苦労してでも調べれば、根本の部分から解決できる問題を
調べもせずに質問するような中途半端な似非クソグラマには
「本当の力」なんてつけさせてやんねー。

質問地獄に陥るって? 漏れなら別にかまわん。
面倒くさい時は「わかんねー。ごめんなw」で済ませている。
プロジェクトが滞ってるのは、その似非クソグラマのせいだ。

ちなみに真の意味での世界最臭のクソは、漏れだw
829デフォルトの名無しさん:04/10/04 18:23:50
>820のいっている
CPPを使えっていう意味がさっぱりわからんのだが、
どういう意味なんだ?

C++使えって意味か?
ソースみれば、C++で書かれてるのなんて明らかじゃないか。
830デフォルトの名無しさん:04/10/04 18:25:49
というか、コンパイルオプションを設定するかどうかのどの辺が
問題解決の本質的問題なのかと
子一時間問い詰めたい。
831デフォルトの名無しさん:04/10/04 18:38:40
>>829
アレな言い分ではあるけど、たぶんインクルードしたヘッダで確かに _beginthreadex が
宣言されているかどうか、cpp 通したあとの出力を見てみろ、ということだと思う。

漏れの手元の処理系には cpp なんて無いけどね。
832デフォルトの名無しさん:04/10/04 19:44:26
・自分が苦しんだ以上に他人を苦しめたい。
・若い芽を摘み取りたい。
・最近とみに目が霞んで、若手よりコーディングが遅くなって危機感に襲われている。

このうちのどれだ?>>824よ。
833デフォルトの名無しさん:04/10/04 22:40:39
他人をオモチャにして遊びたいだけでしょ。
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をしないと仮定してかまいません。
よろしくおねがいします。
835デフォルトの名無しさん:04/10/06 22:49:09
>>834
 Linux Kernel 関連のメーリングリストを読むと、どのようなプロセッサであっても、
(上のリンクや IBM のドキュメントにあるような理由とは異なりますが)チェック対象のメモリへの
書き込みが遅延させられることによる誤動作は発生し得ます・・・

ただし、メモリバリア処理を行わない排他手段が存在すれば、の話です。
実際には、クリティカルセクションに入るための処理、出るための処理は必然的にメモリバリアと
なるため、C++ やアセンブラでの double checked locking は(正しく書かれれば)常に正常に動作します。
836デフォルトの名無しさん:04/10/06 22:52:56
↑は変な書き方でスマソ。
要は、Java や C# にあるような初期化に先んじてポインタ値がメモリに書かれるようなことが無ければ、
C# でいうところの lock {} 等のアセンブラレベルでの実装がメモリバリアを(必然的に)兼ねてしまうので
問題の起こしようがない、というようなことです。
837834: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;

の(*)の部分を心配しているという感じです。如何でしょうか?
838デフォルトの名無しさん:04/10/06 23:22:45
>>835
>  Linux Kernel 関連のメーリングリストを読むと、どのようなプロセッサであっても、
> (上のリンクや IBM のドキュメントにあるような理由とは異なりますが)チェック対象のメモリへの
> 書き込みが遅延させられることによる誤動作は発生し得ます・・・
ソースキボンヌ
839デフォルトの名無しさん:04/10/06 23:43:26
>>838
ソースは無いので取り消します。
840デフォルトの名無しさん:04/10/06 23:48:57
>>837
C++ では代入文の中には sequence point が無いので、
一旦 temp に受けないとまずそうですよね。
でもメモリバリアは要らないんじゃないですか?
tmp = net T; の末尾が sequence point になるので、
instance = tmp より先に実行されることが C++ 的には保証されているから。
841デフォルトの名無しさん:04/10/07 00:01:47
>>840
C++処理系が別CPUからのvisibilityまで考慮してくれるかというと微妙じゃないですか?

有名なこのURLを見ると、C++でもバリア使えとかいてあるですよ(Making it work with explicit memory barriers のトコ)
http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html
842デフォルトの名無しさん:04/10/07 00:18:37
まだ読んでいないけどsequence point関連でぐぐってひっかかったものを貼ってみるテスト

Double-Checked Locking, Threads, Compiler Optimizations, and More
http://www.nwcpp.org/Downloads/2004/DCLP_notes.pdf

Memory caching and synchronization
http://discuss.fogcreek.com/joelonsoftware/default.asp?cmd=show&ixPost=22908

Boost.Thread Memory Visibility
http://www.boost.org/regression-logs/cs-win32_metacomm/doc/html/threads.html
843デフォルトの名無しさん:04/10/07 00:23:25
instance = new T;
で問題ない
844843:04/10/07 00:26:55
つーか、メモリバリア以前にコンパイラの最適化を理解してないみたいだな
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)。
ありがとうございました。
846デフォルトの名無しさん:04/10/07 00:34:01
>>843-844
解説を。
847デフォルトの名無しさん:04/10/07 00:35:40
>>837
必要ない。;がseq. point。
848デフォルトの名無しさん:04/10/07 00:37:24
>>840
> tmp = net T; の末尾が sequence point になるので、
> instance = tmp より先に実行されることが C++ 的には保証されているから。

カレントスレッドからはそのように見えることが保証される、ってだけで
他のスレッドからもそのような順序で見えるってことまでは保証されていないはず。
849デフォルトの名無しさん:04/10/07 00:38:13
>>848
ですね。
850デフォルトの名無しさん:04/10/07 00:39:39
何言ってんだこのバカは
851デフォルトの名無しさん:04/10/07 00:42:17
もう池沼かよ
852sage:04/10/07 00:49:39
>>850は誰に逝ってんの?
853デフォルトの名無しさん:04/10/07 00:54:39
>結論としては、メモリバリアが必要ということで(p.29)。
おまえとんだ誤解してるぞ
854834:04/10/07 00:57:41
>>853
読み間違っていますか?特に移植性は問題にしてないんですが…。
特定のCPUで動けば。

あ、それとも参照している先の文章が間違っている?
855デフォルトの名無しさん:04/10/07 01:08:45
tmp = net T;
instance = tmp ;
まずこの式がこのままである保障は全くない。
tmpの値が他で使われなければ省略される。
シーケンスポイント(副作用完了点)はこの場合関係ない。
よって
instance = net T;
と等価。
856834:04/10/07 01:15:27
>>855(=853?)
それは承知してます(例のpdfのp.16でも言及されています)。
メモリバリアを挟むことを前提で>>837はtmpを使って書きました。

他にもなにかあればお願いします。
857834:04/10/07 01:20:46
言葉が足りないかもしれないので補足。
コンパイラの最適化を妨げる、コンパイラに固有のなにかを挿入するつもりです。

例えばgcc+IA64なら

tmp = new T;
__asm__ __volatile__("mf":::"memory");
instance = tmp;

どうでしょう?
858デフォルトの名無しさん:04/10/07 01:26:47
そもそも837のソースはtmp不要
外側のif(!instance) {も不要
859834:04/10/07 01:32:59
>>858
> そもそも837のソースはtmp不要
> 外側のif(!instance) {も不要
その通りなんですが、パフォーマンスを稼ぎたいんですよね。

…正確に言うと、某CPUが数発のマシンでDCLを(バリアなしで)使ってる人に、バリア使うか858のように書き直せと言いたいんです。そのための調査をしていまして。
自分はどちらかというと858派ですと付け加えておきます。基本的にはパフォーマンスより安全・確実な方を選びたいですね。

#完全synchronizeのペナルティがイヤならTLSにでもポインタいれとけばぁ?と思う。
860デフォルトの名無しさん:04/10/07 01:36:05
>>858
元質問は↓コレな罠
>「x86や(現在の)IA64
>では、メモリバリアなしのdouble checked lockingが安全」なのでしょうか?
861デフォルトの名無しさん:04/10/07 01:42:50
おあとがよろしいようで。
862デフォルトの名無しさん:04/10/07 01:46:39
じゃあ、外側のif(!instance) {は安全。
Lockにコスト掛かるならそれでいいよ。
それとLock中にinstanceをどう扱おうがメモリバリアは不要。
つまりtmp不要。
863デフォルトの名無しさん:04/10/07 01:50:18
>>862
つまり

if(!instance) {
 lock;
 if(!instance) {
  instance = new T;
 }
 unlock;
}
return instance;

で良いということ?
864デフォルトの名無しさん:04/10/07 01:52:45
>>863
IA32,IA64共にそれで問題ない。
865デフォルトの名無しさん:04/10/07 01:53:53
>>864
>ARMやPPCやAlphaでは誤動作します?
は?
866デフォルトの名無しさん:04/10/07 01:54:24
@じゃあ、外側のif(!instance) {は安全。
AそれとLock中にinstanceをどう扱おうがメモリバリアは不要。

2の主張は正しいよ。でも、1のinstance参照はLockを伴っていないよ?なんで安全と思うのか知りたいところだ
867デフォルトの名無しさん:04/10/07 01:55:26
volatile char *tmp = (char *)new T, *p = (char *)instance;
int i;

for (i < sizeof(instance)) *tmp++ = *p++;

とかしない限り問題ない。
868デフォルトの名無しさん:04/10/07 01:56:02
逆だった
for (i < sizeof(instance)) *p++ = *tmp++;
869デフォルトの名無しさん:04/10/07 01:57:09
(゚Д゚)ハァ?
870デフォルトの名無しさん:04/10/07 01:57:48
寝ぼけてた
int i = sizeof(instance);
while (i--) *p++ = *tmp++;
871デフォルトの名無しさん:04/10/07 02:01:15
突然何の話してるの?本気でわからん。
>>843=844=850=855=858=862=864=867=868=870
872ageてみる:04/10/07 02:04:32
個人的には865のみ重要
873デフォルトの名無しさん:04/10/07 02:05:36
>>866
なんで安全じゃないと思うんだ?
思い込みばっかしてないで仕様書よめ。
874デフォルトの名無しさん:04/10/07 02:15:19
>>873
> なんで安全じゃないと思うんだ?
> 思い込みばっかしてないで仕様書よめ。

ISO/IEC 14882:2003 にスレッドの話題は出てこない。IEEE Std 1003.1, 2004 4.10 では必ずロックしろと書いてある。
ロックしないで変数触る場合はプラットフォーム固有の何かをしないとダメ。その方法については
http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html
http://www.nwcpp.org/Downloads/2004/DCLP_notes.pdf
でガイシュツ。IA32で問題ないのはそのとおり。が、問題ないCPUばかりじゃないから此処で今話題になってる。

あ、>>834はWindowsみたいだがUNIXの話題ですまんね。
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系ってどうなんすかね
877デフォルトの名無しさん:04/10/07 08:37:32
>>858
> 外側のif(!instance) {も不要

おいおい。
元々のお題がSingletonパターンなんだよ。
毎回lockしたらinstance()が遅いだろ。
878デフォルトの名無しさん:04/10/07 12:05:43
>>875
> 厳密には、(*)にメモリバリアを置いただけでは不十分。
> (*)だけだと「メインメモリへの書き出し順序」は保証されるが、
> 他のCPUがそれを読み込む順序までは保証されない。
>
> とはいえ、IA32やIA64ではそんな心配は無用だが。

IA32/64でも、(*)の部分のバリアだけは必要なんでつか?
おしえてください。
879デフォルトの名無しさん:04/10/07 12:21:07
>>875
つまりこういう問題がある?

・CPU A は首尾よく instance の初期化を完了。メモリバリアでメモリへ全てを書き出す。
・CPU B は Double-Checked Locking を開始。変数 instance がキャッシュに乗っていなくてメモリから読む
・instance の指す先のメモリはたまたまCPU Bのキャッシュに残っていて(内容はゴミ)、instance->bar() とかでアボーン。

よく考えれば、変数 instance だけではなく、それが指すオブジェクト自体他のCPUでコンストラクトされている(可能性がある)わけだから、
利用に先立って少なくともreadキャッシュの無効化が必要だよなぁ。
880デフォルトの名無しさん:04/10/07 12:28:01
>>877
> おいおい。
> 元々のお題がSingletonパターンなんだよ。
> 毎回lockしたらinstance()が遅いだろ。
SingletonパターンというかDCLパターンだね。
つーか >>843=844=850=855=858=862=864=867=868=870=873 は放置の方向で。
881デフォルトの名無しさん:04/10/07 12:32:26
>>879
WindowsやPOSIX準拠OSが動く環境は、普通はcache coherentです。
つまりreadキャッシュの無効化だとかなんだとかはH/Wで自動解決されるから
プルグルマは気にしなくていい。

気にしないといけないのは、"他CPUからみて、自CPUがどのような順番でメモリ
を読み書きしたように見えるか"。そういう他CPUの観測具合を制御するのがメモリ
バリア。

細かいけど…。
882881:04/10/07 12:39:48
あと、クリティカルセクションとかPOSIXのmutex_lock/unlockなどは暗に
メモリバリアだから、「複数スレッドが触る変数を操作するのは常にクリ
ティカルセクション内にする」を徹底すればプルグルマは楽をできる。

というか、普通のプログラマにハードウェアの詳細、メモリモデルについ
て知っておけというのはムリなので、そうするのが良いアイディア。bool
変数だからロックしなくていいよね?とかよく聞かれるけど、俺は常に
ダメだちゃんとロック汁と返答しがち。

DCLもプロファイリングしてボルトネークになってることが確定しない
限りは考えないほうがいいようにおもう。どっかで出てたように最悪
TLSでキャッシュすればよろし。
883843:04/10/07 19:22:10
>>880
酷い言われようだが、俺が突っ込んだ書き込みして呼び水にならなかったら
おまえらは全然動かなかったろ。>865辺りからやっと湧いて出たアホども
ありがたく思えよ>834
884デフォルトの名無しさん:04/10/07 19:33:34
837の神は840じゃないのかなぁ。843は口調が煽りすぎでしょ。
885デフォルトの名無しさん:04/10/07 20:35:00
ところで、
>>840 は間違っていて tmp = XXX; instance = tmp は結局 instance = XXX;
 に最適化される(してもよい)ので無意味」
って感じのレスがあったけど、これ本当ですか?

XXX が副作用をともなうコードであって、かつ ; のところが end of full expression でシーケンスポイントなんだから、
最適化によって instance = XXX と同じコードになろうがなるまいが、instance への書き込みがオブジェクトの
初期化に先んじることはないと思うんだけど(SMPでのメモリバリアの問題は別として)。
886デフォルトの名無しさん:04/10/07 21:04:26
哲学者の食事って有名なんですか?
887デフォルトの名無しさん:04/10/07 21:05:26
有名と思うよ。大学の講義でも真っ先に出てきたし。
888デフォルトの名無しさん:04/10/07 21:40:46
まるちスレッドの本なら大抵その小話が入る
889875:04/10/07 22:59:34
> > 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を使ってるかもしれんが、
使う側からはそういう内部実装を一切気にしなくて良い。
890875:04/10/07 23:15:27
>>878
> IA32/64でも、(*)の部分のバリアだけは必要なんでつか?
> おしえてください。
他の人も言っているように、IA32/64なら(*)の部分のバリア無しでもちゃんと動く。

ただし、IA32ならMTRRという機能があって、こいつを使うと
Out of Orderなメモリ書き出しなどができるようになる。
これを使うと、メモリアクセスの性能は大幅に向上する(XFree86 3.xを使ってた人なら
よく知ってるだろう)が、DCLのようなアルゴリズムは全く動かなくなってしまう。
891デフォルトの名無しさん:04/10/07 23:40:27
>>889
LinuxThreadsのpthread_onceの実装はモロに使ってます>DCL
892デフォルトの名無しさん:04/10/07 23:43:53
MTRRってそういう意味だったのか!!!
目から鱗〜

ところで>>834のリンク先のblogを見ると、IA64は本来weak ordering
なのだが現在のCPUはそうなってないとか書いてあるけど、そのへん
どう思います?

よみ違ってたらスマソ
893デフォルトの名無しさん:04/10/08 13:08:12
MTRRについて詳しく書いてあるページないですか
894デフォルトの名無しさん:04/10/08 14:05:02
マルチスッドレリアルリアリティ
895デフォルトの名無しさん:04/10/08 14:05:44
もってロリロリ
896デフォルトの名無しさん:04/10/08 14:11:17
そういやそろそろ超先生の一周忌だね
897デフォルトの名無しさん:04/10/08 21:03:51
正直、どうでもいい
898デフォルトの名無しさん:04/10/08 23:21:04
おらいりの
899デフォルトの名無しさん:04/10/09 00:50:51
900デフォルトの名無しさん:04/10/09 12:22:23
まるちすれっどって難しいですね
みなさんが仕事でマルチスレッドを使う割合ってどれぐらいですか?
901デフォルトの名無しさん:04/10/09 12:35:23
7306ぐらい。
902デフォルトの名無しさん:04/10/09 13:50:08
おれはJSPを使っているから自動的に使っていることになるな。
903デフォルトの名無しさん:04/10/09 14:00:38
JSPてナニ?
904デフォルトの名無しさん:04/10/09 15:34:37
Japan Super Prototype
905デフォルトの名無しさん:04/10/09 17:14:51
Japanese Sweet Pussy
906デフォルトの名無しさん:04/10/09 18:38:06
Jewish Smelly Penis
907デフォルトの名無しさん:04/10/10 01:50:02
>>890
> > IA32/64でも、(*)の部分のバリアだけは必要なんでつか?
> > おしえてください。
> 他の人も言っているように、IA32/64なら(*)の部分のバリア無しでもちゃんと動く。

あくまで、「コンストラクタ実行の後に変数instanceへの代入を行うコードを
コンパイラが必ず生成する」という前提があればの話ね。

でも、でも必ずしもそうとは限らないようだ。
ttp://www.nminoru.jp/~nminoru/diary/2004/10.html#2004-09-06
908デフォルトの名無しさん:04/10/10 02:37:36
>>907
それはSunのコンパイラが使いものにならないことの証明でしかない。
909デフォルトの名無しさん:04/10/10 15:43:29
>>908
もまいは問題を理解していないようだな
910デフォルトの名無しさん:04/10/10 19:22:42
>>907
まぁCPUによらず、コンパイラの最適化抑制はしときましょうってことで。
gccなら asm("":::"memory"); 

911デフォルトの名無しさん:04/10/10 19:26:50
>910
VC++とSun純正のC++コンパイラの場合は?
912デフォルトの名無しさん:04/10/10 21:02:27
913デフォルトの名無しさん:04/10/10 21:25:35
>>912
さんくす子。ところで>>837
>まず、クリティカルセクション(やpthread_mutex_lock/unlock)がメモリバリアになるという点は了解です。
>クリティカルセクションの入退場があれば、そこをまたぐようなreorder(コンパイラ/CPU両方の)は行わ
>れないのですよね。
>(http://www.microsoft.com/whdc/driver/kernel/MPmem-barrier.mspx にもその旨明記してありました)
KeMemoryBarrier()が使えるのはドライバのみ?
914デフォルトの名無しさん:04/10/11 03:29:17
元記事よくよめよアフォ
915デフォルトの名無しさん:04/10/11 11:06:48
おしえてよ
916デフォルトの名無しさん:04/10/11 11:15:50
スレッドを複数起動してそれぞれのスレッドを任意に一時停止、再開したり
するにはどうしたら良いですか?
例えばa,b,cのスレッドがあってまずスレッドaを起動して何処か途中
任意でスレッドbにスイッチ(スレッドaはそこで一時停止)、同じ様に
スレッドbからスレッドcにスイッチ、スレッドcからスレッドaへスイッチすると
スレッドaの途中から再開みたいな動きです。
917デフォルトの名無しさん:04/10/11 11:18:32
>>916
環境は?OSは?CPUは?
918デフォルトの名無しさん:04/10/11 11:22:38
あ、すんません。
環境:VC++6.0
OS:Windows2000
CPU:Pen4
って感じです。
919デフォルトの名無しさん:04/10/11 11:30:09
>>916 ファイバ
920デフォルトの名無しさん:04/10/11 11:39:58
>>919
ファイバですか・・・ちょっと調べてみます。
ありがとうございました。
921デフォルトの名無しさん:04/10/11 12:12:50
ファイバ.NETからでも使えるのか?
922デフォルトの名無しさん:04/10/11 13:02:25
コルーチソ
923デフォルトの名無しさん:04/10/11 13:35:20
ファイバとマイクロスレッドの違いがわかりません
924デフォルトの名無しさん:04/10/11 14:33:33
一緒
925デフォルトの名無しさん:04/10/11 14:35:47
マイクロスレッドの利点がいまいち見えない
コンテキスト切り替えを任意のタイミングでできると
何かうれしいことがあるの?
926デフォルトの名無しさん:04/10/11 14:45:09
>>925
発想が逆。

スレッドは落とし穴が多いし重い(マイクロスレッドより)から使いたく
ないけど、並列処理もどきは行いたいことがある。コンテキスト切り替え
が嬉しいのではなくて、コンテキスト切り替えの面倒を被ってでも「気楽
で軽いスレッド」が欲しい。

…といったところか?
927デフォルトの名無しさん:04/10/11 15:02:07
おまえ質問に対する回答の仕方がなってないな
疑問符で終らすなヴォケ
928デフォルトの名無しさん:04/10/11 15:04:47
>>927
答えられないなら黙ってろよ
929デフォルトの名無しさん:04/10/11 15:33:06
>>925
コルーチン(マイクロスレッド、ファイバ)パターンで記述すると
楽なものに対して使う。
930デフォルトの名無しさん:04/10/11 15:36:52
________              /::::::/l:l
─- 、::::;;;;;;;;;`゙゙''‐ 、    __,,,,......,,,,_/:::::::::/: !|
  . : : : : : : `゙'ヽ、:::゙ヾ´::::::::::::::::::::::`゙゙゙'''‐'、. l|
、、 . : : : : : : : : r'":::::::::::::::::::::::::,r':ぃ::::ヽ::::::::ヽ!                 ,、- 、
.ヽ:゙ヽ; : : : : : :ノ:::::::::::::::::::::;;、-、、゙:::     rー-:'、                /   }¬、
. \::゙、: : : :./::::::::::::::;、-''"::::::::::   ,...,:::,::., :::':、            _,,/,,  ,、.,/   }
   ヽ:ヽ、 /:::::::::::::::::::::::::     _  `゙''‐''"  __,,',,,,___       /~   ヾ::::ツ,、-/
     `ヽ、:::::::::;;;、、--‐‐'''''',,iニ-    _|  、-l、,},,   ̄""'''¬-, '  ''‐-、 .,ノ'゙,i';;;;ツ
   _,,,、-‐l'''"´:::::::'  ,、-'" ,.X,_,,、-v'"''゙''yr-ヽ / ゙゙'ヽ、,    ,.'      j゙,,, ´ 7
,、-''"    .l:::::::::::;、-''"  ,.-'  ゙、""ヾ'r-;;:l  冫、     ヽ、 /    __,,.ノ:::::ヽ. /   パターンだって。(ヴァカ?)
       l;、-'゙:   ,/      ゞ=‐'"~゙゙') ./. \    /  '''"/::::;:::;r-''‐ヽ
     ,、‐゙ ヽ:::::..,.r'゙         ,,. ,r/ ./    ヽ.   ,'     '、ノ''"   ノ  
   ,、‐'゙     ン;"::::::.       "´ '゙ ´ /      ゙、 ,'            /
  '     //:::::::::            {.        V           /
        / ./:::::::::::::            ',       /         /
.    /  /:::::::::::::::::.            ',.      /   ,.、     /




931デフォルトの名無しさん:04/10/11 15:41:42
  ヽ、.三 ミニ、_ ___ _,. ‐'´//-─=====-、ヾ       /ヽ
        ,.‐'´ `''‐- 、._ヽ   /.i ∠,. -─;==:- 、ゝ‐;----// ヾ.、
       [ |、!  /' ̄r'bゝ}二. {`´ '´__ (_Y_),. |.r-'‐┬‐l l⌒ | }
        ゙l |`} ..:ヽ--゙‐´リ ̄ヽd、 ''''   ̄ ̄  |l   !ニ! !⌒ //
.         i.! l .:::::     ソ;;:..  ヽ、._     _,ノ'     ゞ)ノ./
         ` ー==--‐'´(__,.   ..、  ̄ ̄ ̄      i/‐'/
          i       .:::ト、  ̄ ´            l、_/::|
          !                           |:    |
             ヽ     ー‐==:ニニニ⊃          !::   ト、
おれたちはとんでもない思い違いをしていたようだ。これを見てみろ。
まず「クソスレ」を英字で表記する
『KUSOSURE』
これを逆にすると、
『ERUSOSUK』
そしてこれを更に日本語に直すと
『エルソサク』
スレを立てたのが>>1と言う事を考えれば末尾に『クソスレ』を加えるのが当然だ。
すると導き出される解は
『エルソサククソスレ』
そして最後の仕上げに意味不明な文字『エルソサク』
これはノイズと考えられるので削除し残りの文字を取り出す。
するとできあがる言葉は・・・・・・『クソスレ』。

つまり!『クソスレ』とは『まさにこのスレッド』を表す言葉だったのだ!!
932デフォルトの名無しさん:04/10/11 15:48:53
>>925
[cppll:6196] マイクロスレッド
を見るのがいいとおもうんだけど、いま過去ログサーバが落ちてるね。
933925:04/10/11 15:51:04
>>926
>>929
>>932
なるほど
レスありがとうございます

自分でも色々調べてみます
934デフォルトの名無しさん:04/10/11 15:54:02
>931 始めてみた.吹いた.不覚だ。。。orz
935デフォルトの名無しさん:04/10/11 17:31:24
始めてみた

初めてみた
936デフォルトの名無しさん:04/10/14 13:23:37
pthreadを使ったもっとも簡単なプログラムを教えてください
937デフォルトの名無しさん:04/10/14 17:14:03
#include <pthread.h>
int main () { pthread_exit(0); }
938デフォルトの名無しさん:04/10/15 12:18:09
自作のライブラリ作る時、スレッドセーフかどうか
ちゃんと確認して作ってますか?
939デフォルトの名無しさん:04/10/15 16:03:37
君は確認してなかったの?
940デフォルトの名無しさん:04/10/15 18:54:02
>>938
どうやって確認してます?
941デフォルトの名無しさん:04/10/15 19:00:29
スレッドセーフなコードしか書かない
942デフォルトの名無しさん:04/10/15 20:51:48
スレッドセーフと言っても色々ある
リエントラントにしただけのもあるし、
スレッド間で共有するリソースの競合まで吟味したものもある
最初から意識して作るしかないだろう
943デフォルトの名無しさん:04/10/15 21:26:53
スレッドセーフかどうか自分のソースコードを見ても確認できないなどというのはおかしい。
潜在するロジック上のバグと違い、スレッド関連は明らかにヒューマンエラー。
944デフォルトの名無しさん:04/10/15 23:42:22
>>943
ええっ!?
ロッキングロジック上の馬具は一体何?
945デフォルトの名無しさん:04/10/16 00:28:36
ヒューマンエラー
946デフォルトの名無しさん:04/10/16 01:22:10
結局シングルトンのインスタンスはどう返せばいいんだろ
947デフォルトの名無しさん:04/10/16 01:44:14
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;
}
948デフォルトの名無しさん:04/10/16 06:26:24
DCLなんてしてないでイニシャライズとファイナライズをmainとかに書いとけばいいじゃん。
シンプルだし、最適化がどーのなんて悩まないで済むんだし。
949デフォルトの名無しさん:04/10/16 06:39:18
それはシングルトンの場合でしょ。
それで済むときはそれで構わない。
# 但しシングルトンの時も、シングルトン間の初期化の順序を制御したい場合、
# 動的に確保されるシングルトンの場合はダメ。

またDCLはオブジェクトがある条件を満たした時に、
初めて行われるポインタメンバーの初期化などに必要。
950デフォルトの名無しさん:04/10/16 10:47:58
>>942
> 最初から意識して作るしかないだろう

同一のインスタンスに対する並行アクセスはダメ、というケースはよく見るね
使う側からすると、下手にロックされても困る場合もあるから
ライブラリの設計は難しい・・・
951デフォルトの名無しさん:04/10/16 16:15:43
>>950
次スレよろ
参考リンクも何もないな

以下テンプレ



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

その1 http://pc3.2ch.net/test/read.cgi/tech/997345868/
その2 http://pc5.2ch.net/test/read.cgi/tech/1037636153/
952デフォルトの名無しさん:04/10/16 16:34:01
過疎スレなのにそんなに早く次スレ立ててどうするの?
953デフォルトの名無しさん:04/10/16 18:09:46
950過ぎたんだから別に何時立とうがどうでもいい話だな
954デフォルトの名無しさん:04/10/16 20:47:06
スレッド立てる前にちゃんとロックしてね。
955デフォルトの名無しさん:04/10/16 20:55:40
いやむしろマルチスレッドで
956デフォルトの名無しさん:04/10/16 22:42:44
デッドロックする予感
957デフォルトの名無しさん:04/10/16 23:30:33
食学者の哲事問題で
958デフォルトの名無しさん:04/10/17 00:17:04
Pthread_mutex_lock(CriticalSection);
959デフォルトの名無しさん:04/10/17 00:17:55
Pthread_mutex_lock(CriticalSection);
960デフォルトの名無しさん:04/10/18 08:45:36
>>947
だからそれじゃだめだと何度言ったら…
961デフォルトの名無しさん:04/10/18 09:06:31
駄目な環境と宝刀#ifdefで区切ればいいじゃん
962gccで:04/10/18 10:47:26
#ifdef LINUX
#include <linux/compiler.h>
barrier();
#elifdef XXX
XXX();
#else
#error Unknown system about memory barrier!!!
#endif
963あれば:04/10/18 10:51:16
964デフォルトの名無しさん:04/10/18 19:35:53
>>960
何がダメなのよ?
965デフォルトの名無しさん:04/10/18 20:26:57
どうやら話が振り出しに戻ったようですな。
966デフォルトの名無しさん:04/10/18 23:17:34
>>965
ループするのはやめときます。
967デフォルトの名無しさん:04/10/18 23:19:10
俺はもうひらき直ってインスタンス返却関数に毎回ロック掛けてます
968デフォルトの名無しさん:04/10/19 08:15:06
KeMemoryBarrier()が使えるのはドライバのみ?

969デフォルトの名無しさん:04/10/19 10:23:46
>947
2重チェックなんか無駄でしょう。
このメソッドを連続して複数回呼ぶとしたらそのつくりがおかしい
メソッド全体にロックかければ十分
970デフォルトの名無しさん:04/10/19 12:33:00
>>969
すでにインスタンス作ったのにインスタンス取得の度にロックするほうが時間の無駄でしょうが
971デフォルトの名無しさん:04/10/19 12:47:10
getInstanceをループの中で毎回呼ぶのですか?
そうはしないし、それならば多少時間がかかっても問題がない。
無意味な最適化をするとバグを混入する原因となりかねないのでシンプルにしたほうがいいと考えています。
972デフォルトの名無しさん:04/10/19 12:51:58
>>971
>getInstanceをループの中で毎回呼ぶのですか?

ハァ?(゚Д゚)
973デフォルトの名無しさん:04/10/19 13:02:13
>>getInstanceをループの中で毎回呼ぶのですか?

>ハァ?(゚Д゚)

ハァ?(゚Д゚)。Lock処理で何ミリセク処理時間が増えるか知らんが、その呼び出しが問題になるほど繰り返し呼び出すとしたら呼び出してるほうが問題なんだろうが。
キャッシュするなりすればいいという意味だろ。
974デフォルトの名無しさん:04/10/19 13:58:27
>>973
なるべく透過的にキャッシュしたいね、という話をしているわけだが。
俺としてはガイシュツのTLSがいいとおもうね。
975デフォルトの名無しさん:04/10/19 15:13:57
>>968
手持ちのDDKには無かったぞ?
976デフォルトの名無しさん:04/10/19 15:14:08
次スレはこんな感じで


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


マルチスレッドプログラミングについて語るスレ。 
OS・言語・環境は問わないが、それゆえ明記すべし。

その1 http://pc3.2ch.net/test/read.cgi/tech/997345868/ 
その2 http://pc5.2ch.net/test/read.cgi/tech/1037636153/ 

Pthread -- POSIX Thread Mailing List
http://www.media.osaka-cu.ac.jp/mailman/listinfo/pthread
977デフォルトの名無しさん:04/10/19 23:47:37
DCLもしらん厨房は早く寝ろ。
978デフォルトの名無しさん:04/10/20 00:20:51
>>977
$ WRITE SYS$OUTPUT "VMS使いのおじいさんですか?"
979デフォルトの名無しさん:04/10/20 00:50:11
>>977
DCL使ってプロジェクトを破滅に追いやるオマエ茂名。
980デフォルトの名無しさん:04/10/20 11:53:49
windowsでもunixでもコンパイルできるマルチスレッドプログラムはどのように書けばよいのでしょうか?
981デフォルトの名無しさん:04/10/20 11:59:16
Ruby!!!!!!!!!!!!
982デフォルトの名無しさん:04/10/20 13:18:24
そーいや、なんでRubyなんだろうな。
まともな言語だって思ってたんだけど、2ch見てるとHSPと同じような位置にしか見えない。
C++なぞ問題外発言の所為?
983デフォルトの名無しさん:04/10/20 13:51:25
スレッドをどのくらいまでなら作っても大丈夫なんですかね。
木構造の接点それぞれにスレッドを割り当てるプログラムで、
枝接点は、ほとんど何もしないラッパー的なスレッドで、
主な処理は、葉接点にあたるスレッドが行うというものですが、
重い葉接点スレッドの実行数を制限すれば、全体で数百〜千スレッド逝っても大丈夫でしょうか。
984デフォルトの名無しさん:04/10/20 13:55:25
環境依存
985デフォルトの名無しさん:04/10/20 14:14:39
>>983
>木構造の接点それぞれにスレッドを割り当てるプログラムで、
>枝接点は、ほとんど何もしないラッパー的なスレッドで、
>主な処理は、葉接点にあたるスレッドが行うというものですが、

まあ、話のタネに聞いておくが、
何でそんなものが必要なんだ?
986デフォルトの名無しさん:04/10/20 14:47:40
>>982
アンチC++やアンチPerl色が強すぎてある意味宗教じみてた頃があったからかな?
今はどうなのか知らないけど
987983:04/10/20 17:02:11
>>985
汎用的な処理を行うシェルのようなプログラムを作成しているのですが、
階層別にグループ化が必須なので。
で、スレッド暴走時の対処や、ある階層以下のすべてのスレッドに命令、セキュリティは?
とか考えると、ルートを一つにするよりも、全部スレッドにしたほうがいいかなと思いまして。
まあ、どっちにしろ最大スレッド数あたりを設定して、そこからあふれた場合はキューにためておいて、
スレッド数が減ってきたら、キューから読んでスレッド作成という動作を実装する必要がありますが。
988デフォルトの名無しさん:04/10/20 18:24:52
スレッド必要な理由がよくわからんのですが・・・
989デフォルトの名無しさん:04/10/20 19:20:44
selectやpollでwaitできないデバイスを扱うのに必要なんだよ。ボウヤ。
990デフォルトの名無しさん:04/10/20 19:25:40
shellならprocess作って走らせるだけだからthreadは複数要らんってことなんじゃね?
991950:04/10/20 19:35:05
次スレをcreateしました。

http://pc5.2ch.net/test/read.cgi/tech/1098268137/l50

関連URL他にないですかねぇ。
992デフォルトの名無しさん
pthread_barrier_init(&b, NULL, 8人);
pthread_barrier_wait(&b);
std::2ch << "1000ゲット!!" << std::endl;