乙
4ね
5免蒙る
pthreadで排他制御やりたいときはmutexしか選択肢は無いんでしょうか?
condition,semaphore
8 :
デフォルトの名無しさん :2006/09/18(月) 01:43:12
本とかはもういいとして、このソースのthread部分は秀逸だっていうの 教えてください
apache2(ウソ)
Windowsのスレッドのタイムスライスは、上限が20msと聞きますが これを制限する方法はありませんか? できれば、3〜5msに押さえたいのです。
NT4.0を使って、boot.iniで設定。 Windows Embeddedならどっかで設定できたような。 Vistaは割り込み頻度を変えるAPIがあったかもしれず。
Fiber使ってで明示的にスイッチするとか
>>11 ありがとうございます。
こちらでも調べてみたのですが
win9x/2000でのスレッド単位での設定は出来ないようですね。
スレッドスケジューラを少しいじれば、可変に出来る気がするのですが
あんまり需要無いんですかね。
>>12 ファイバを使ってsuspendを置くか、スレッド関数にSleepを置くか、
結局のところ、これしかしかないのですね……
どちらか採用して、今のプロジェクトを進めようと思います。
>>10 たしか、どっかにVistaのタイムスライスに関する blogがあったな。
××をすると、スイッチが最小時間になると適らないとか。
どっかの、MVPの blogだったと思う。
InsideWindowsには [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\PriorityControl] のWin32PrioritySeparation をいじればいいと書いてある
ってスレッド単位で制御したいのか そりゃ無理っぽいな
18 :
デフォルトの名無しさん :2006/10/07(土) 12:26:02
ほ
19 :
デフォルトの名無しさん :2006/10/10(火) 14:57:19
>>14 kernel修正すればいいじゃん。
2.6.xなら安定してるしNPTLを使えばOKだし
?
21 :
デフォルトの名無しさん :2006/10/26(木) 16:02:30
マルチプロセスのプログラムはWindowsで作れますか?
>>21 が意図してるものとは異なるかもしれんが、マルチプロセスのアプリケーションなら作れる。
しかし
>>21 の質問の仕方からして、
>>21 には到底無理だろう。
23 :
デフォルトの名無しさん :2006/11/04(土) 17:13:38
質問させてください。 Win32APIのSuspendThread()に自スレッドを指定して、 自分自身を眠らせるということは可能でしょうか?
試せばいいじゃん
どうやって起こすの? イベントオブジェクト作ってWaitForしたほうがマシだと思うが・・・
>>24 すいません、「可能」は「アリ」に置き換えてくださいorz
一応動くんですが、何かマズイんじゃないかなぁと思いまして。
>>25 仰るとおり実用的ではないですが、ちょっと気になったもので…
>>23 他スレッドからResumeThreadしようとしたとき、Resumeしても SuspendThread の直前だったため
Resume後即 Suspend してしまうケースがある。 → 解決するためには「スレッドのステート(idle,busyなど)」を設けて、
排他的に操作する必要あり。適切なイベントオブジェクトを使って待つ方が良い。
それでもまぁ他のスレッドを Suspend するのに比べればはるかに罪は少ない。
28 :
デフォルトの名無しさん :2006/11/07(火) 09:09:31
967 名前:923[sage] 投稿日:2006/09/09(土) 17:29:41
>>959 >intrinsicはスルーか。
済みません、仰りたいことの意味が良く分りませんでした。
このプログラムの要点は、
volatile long a = 0x00001111;
void thread1(){
while(1)a=0x00001111;
}
void thread2(){
while(1)a=0x22220000;
}
int main(){
_beginthread(thread1);
_beginthread(thread2);
while(1)if(a != 0x00001111 && a != 0x22220000)エラー;
return 0;
}
です。組み込み命令云々の余地があるのでしょうか?
main, thread1, thread2が開始される。
〜〜〜時間が十分経過〜〜〜
thread2が動き出す。a=0x22220000が実行される。
mainが動き出す。a!=0x00001111の評価をする。真であった。
thread1が動き出す。a=0x00001111が実行される。
mainが動き出す。a!=22220000の評価をする。真であった。
mainが動き出す。エラー処理を行う・・・???。
複数のスレッドを起動する場合、 システムに異常が発生しても全てのスレッドを 必ずきちんと終了させたい場合、各スレッドで try catch 入れるんでしょうか? それとも別に良い常套手段があるんでしょうか?
システムに異常が発生した事を検知する関数が真を返したらすべてのスレッドが自主的に終了するようにしたらいいんちゃうん?
ええんちゃう? 最高ちゃう?
33 :
デフォルトの名無しさん :2006/11/10(金) 09:56:27
volatile最強伝説復活wwwwwwwwwwwwwww
このスレも自主的に終了するようにしたらいいんちゃうん?
ええんちゃう? 最高ちゃう?
>>29 while(1)if(a != 0x00001111 && a != 0x22220000)エラー;
を分解して
while ( true )
{
if ( a != 0x00001111 ) // a is 0x22220000
{
if ( a != 0x22220000 ) // a is 0x00001111
{
throw std::runtime_error("死んでしまえ");
}
}
}
>>36 こうすりゃいいんじゃね?
while(1){
int _a = a;
if(_a != 0x00001111 && _a != 0x22220000)エラー;
}
要は00001111か22220000以外が見つかればエラーにしたいんだから。
>>29 指摘のコンテキストスイッチによる嘘エラー検出は回避できる。
38 :
デフォルトの名無しさん :2006/11/19(日) 14:18:42
初心者です。 スレッドの状態(実行中・サスペンド中など)を知るAPIってありますか? State = ResumeThread( th_handle ) 又は State = SuspendThread( th_handle ) として サスペンドカウントを見て状態を更新させています。 状態を監視する別スレッドがこのStateを見て、レジューム・サスペンドの実行をおこなっているのですが、 どーやら、状態を監視するスレッドが見ているStateと実際の状態が異なるらしく、 レジューム中のスレッドにResumeThread を実行したり、サスペンド中のスレッドにSuspendThread を実行しちゃったりしています。 なにかアドバイスもらえませんか? おねがいします。 OS : Window XP Home 言語: C++ 環境: VC++6.0
resume/suspendよりも、event objectやwindow messageを使って 眠らせることをオススメするよ。
40 :
38 :2006/11/19(日) 14:35:34
>>39 アドバイス、ありがとうございます。
イベント使って、再設計してみます。
それと、色々さがしたんすけど、やっぱりスレッド状態を知るAPIとかは
ないんすかね?
知ったところでどうしょうもない、とだけ言っておこう。 だからないのよ。
42 :
38 :2006/11/19(日) 14:45:36
>>41 了解です。ありがとうございます。
助かります〜
>>40 状態を調べたところでその次のステップで状態が変わってる可能性もあるわけで、
結局、排他やロックなどが必要になるわけです。
だったらはじめから
>>39 の方法の方が妥当なのです。
44 :
38 :2006/11/19(日) 23:36:56
38です。 イベント使って再設計したとこ、なんとか思い通りに動いてくれました。 みなさん、どうもありがとう。 いい勉強になりました〜
linux上のC言語での質問です。 pthread_create を使ってスレッドを生成すると、そのスレッドが完了しても 1個スレッドが残るんですが、これって開放出来ないんですか? デバッガで調べると「pthread_managear」というスレッドのようなのですが。
>>45 スレッドマネージャもためらいきずばかりなんだよね
自殺はよくない
どのlinux? それなくなったとか聞いたんだが
>47 Red Hat Linux 7.3 です。
pthread_joinしてないとかそういう話じゃないの?
>49 joinはしてます。 あと 、pthread_detach も試して見ましたが変わらずでした。
windows c言語です。 _beginthreadexでスレッドを数千つくろうとしてるのですが、 スレッド数400ぐらいこえたところで、_beginthreadが0を返しだすので仕方なくsleepいりのbusyloop で待って_beginthreadしつづけています。 スレッド数をタスクマネージャでながめると400になり、だんだんへって10桁程度になってから また400に跳ね上がるのくりかえしをして、正常に終了します。が遅いです。 だんだん減っているときにはすぐに次の_beginthreadが成功してくれて、 なぜ、400のままずっといき、最後がだんだん減っておわらないのかわからないです。 あと、なぜ400で限界になるのでしょうか? ちなみにスタックサイズをでかくするとスレッド数の限界はもっと減ります。 メモリがどんどんくわれていってスレッドももっとたくさんできて欲しいのですが・・・ スレッドの内容はメモリを動的確保しhtmlをネットから拾ってきて読むものです。 これだけでわかる人 ヒントください。
>>52 え それはないと思う。
プロセスの使用メモリ35MBぐらいなんです。
全部で1Gつんでるのに。
スタックメモリサイズの制限でしょ
> スレッドの内容はメモリを動的確保しhtmlをネットから拾ってきて読むものです。 ジョブキューイングとかワーカスレッドとか知らんかね?
1プロセスにスレッド400個ってのは設計上どうなんだろ…。 タスクマネージャ見ても最高でSystemの78個程度だ。
>>56 同意。
スレッドの生成と、管理にはそれなりのコストがかかるから、
むやみに増やしてもかえって遅くなる。
せいぜい数個から10数個くらいにとどめておくべきと思う。
数千スレッド使いたいってあほか。
PCの玄海に挑戦したかっただけだろうよきっと
どうもスレッドからみでは、本当に同時平行に処理したいことと、 そうでないことの区別ができてないことが多いようだ。
この場合は ・ネットへのリクエスト ・得られた情報の分析 が並行処理対象になると思うんだが、 前者と後者ではやりかたがぜんぜん違うよなあ
あまりのスケールのでかさに、別件でスレッドを使おうか迷っているのが バカらしくなってきた
うちだと_beginthread()しまくるだけの奴で スレッド2000個ちょっとまで作れるな
ふと>51の質問みて思ったんですが、スレッドを分ける(並列にする) と処理速度って上がるんでしょうか。 処理の内容によるでしょうけど、単純にCPU性能に依存するような 処理で、並列に処理可能な場合とか。 まあ普通そういう目的でマルチスレッドを利用したりするわけじゃないですが。
ふと>51の質問みて思ったんですが、スレッドを分ける(並列にする) と処理速度って上がるんでしょうか。 処理の内容によるでしょうけど、単純にCPU性能に依存するような 処理で、直列に処理してたけど並列に処理可能な場合とか。 まあ普通そういう目的でマルチスレッドを利用したりするわけじゃないですが。
連書きスマソ;
>>64 動作中スレッド数よりもCPUコア数が多いなら、スレッドを並列化することで高速化する。
仮に1Core1CPUで単純に並列化した場合、全く高速化しないかオーバーヘッドの分遅くなる。
まぁ、CPUコア数の数倍以上のスレッドを起こすと資源の競合が発生するから速くなる筈がない罠。
>>67 CPUに限らず、資源が競合する処理なら、確かにそうなるな。
逆に言えば資源を競合しないI/Oウェイトなどが多い処理なら、
CPU数より極端に多いスレッド数でも処理は早くなるといえる。
たとえば今回のようなhtmlファイルのダウンロードの場合、
相手方のサーバーのレスポンス待ちが発生するので、複数のスレッドで別々の
htmlファイルを同時に取得しにいったほうがいい。
ただ、やりすぎると今度はスレッド切り替えとか、メモリスワップとか、回線速度の限界とかで
オーバーヘッドが大きくなるので遅くなる。
tcpip.sysの同時接続制限とか関係ないのかな?
>67 68 サンクス! 実はウチの作ってるアプリで性能を指摘されてるトコがあって、 並列化ってどうなんだろうと思ったんで、参考になりました。 とりあえずCPU依存の処理は効果薄って事ですね。
>>70 並列化を考える前に、やることは色々あると思うよ。
CPUに、P4以上の制限つけていいならiccでコンパイルしてみるとか。
iccがあれば、並列化も簡単に試せるしね。
まぁ、詳細はスレ違いになるんで省略するけど。
CPU依存の処理で高速化を考えるなら、並列化ではなくアルゴリズムの最適化を考えたほうがいい。 スパコンでもない限り、今のパソコンはせいぜい4コア。 並列処理させても、4倍未満にしかならない。 だけどうまくアルゴリズムを工夫すれば、数倍から数百倍の速度が稼げる可能性がある。
DELLの6万円パソコン買ったほうがよくね? 10台でも60万。さてアナタの2人月より安い?高い?
無限に並列化可能な処理と仮定するなら、クラスタリングもありかと。 所謂グリッドコンピューティング。
あと2倍になればいいだけなのにチューニングだとかほざいて 無駄にコードを複雑にしようとしていたボケがいたので サーバを3倍に増やして終わりにしました。
ま、そこら辺は完全にケースバイケースだよね。お仕事でやってるならコスト次第。 このスレ的には並列度を上げる方向に収束すると美しいんだけど。
そんな勝手に方向を決められても。
>>71 >iccがあれば、並列化も簡単に試せるしね。
体感で速くなったためしがない。
いったいどういう場合に効果があるのか…。
人間が見ればすぐ分かるが、コンパイラの並列可能判定って
どの程度のものなんだろう。
↑もちろん手動で並列化したら高速化できる状況での話ね。
>>78 勿論、最低限-parallelは指定しているとして、単純なループなら並列化してくれる可能性はあるよ。
尤も、OpenMPを手軽に試せるという積もりで書いたんだけど。
Sunコンパイラ最強伝説
最近、コンパイラの最適化性能比較ってあんま情報ないな。
83 :
デフォルトの名無しさん :2006/12/03(日) 21:51:02
すいません、マルチスレッドですか?
はい、マルチスレッドです。
あなたを、マルチスレッドです。
86 :
デフォルトの名無しさん :2006/12/06(水) 23:09:42
今日は徹夜でpthreadを勉強します。
こんやは徹夜で、マルチスレッドです。
それはいいマルチスレッドですね。
俺はみんながマルチスレッドしたあとでいいよ
みんないっしょでこそマルチスレッドです
俺ちょっと疲れたからみんな先にいってくれ
92 :
デフォルトの名無しさん :2006/12/08(金) 03:40:09
急激にスレの質が落ちて参りました
みんなでマルチコスレッドしねぇ?
JavaScriptの分際でマルチスレッドしてやがる事に最近気付いた。 仕組みどうなってんのよ?
Javascriptなら中身見れるでしょーが
ソースの問題じゃなくてCPUがどう処理をこなしているか知りたいんだよな
並行動作はせんと思うが
CPU?
onBlurとonClickで並列処理するよ。
だめだこりゃ
<script> function Test(){ while(1){} } </script> ... <span onclick="Test()">Hello World!</span> でブラウザ死ぬけど?
?
どのブラウザで? つかブラウザネタをここでやるのか・・・ヤだなあ
ここはやっぱり伝家の宝刀 volatileネタを持ち出して本来のスレの荒れ方に戻そうよ。
Intel C++ Compiler for LinuxでOpenMPを使った並列化をやっているのですが、Intel Thread ProfilerにはLinux版が存在しないので、
暗黙的/明示的なバリア, ループの分割, critical構文等のオーバーヘッドや負荷の不均衡が検出出来ず、いまいちパフォーマンスが伸び悩んでおります。
このような問題を解決できるLinux用のツールは存在するのでしょうか?
それともWindowsに移行するという選択肢しかないのでしょうか?
なんだかレベルの低い質問で慙愧に堪えないのですが、もし誘導や解答をいただければ嬉しいです。
Intel Thread Profiler
http://www.intel.com/cd/software/products/ijkk/jpn/threading/310854.htm
一昔前だったらまともなスレッドプログラミングしたけりゃSolaris使え、で 片付けられてたような気がするけど私も興味あるので識者の降臨を待つ。 Valgrind(Helgrinid)の他にLinuxで実用に耐えるツールはあるのかな、と。
108 :
105 :2006/12/11(月) 22:40:37
>>106-107 御解答有難う御座います。
わざわざ検索していただいたのに申し訳ないのですが、ちょっとその中には無いようですorz
凹んでいるだけでは何にもならないので、とりあえず"OpenMP"でググって片っ端から有望そうな所を覗いてみました。
結果、Omni OpenMP Compilerにtlogviewなるツールがあることがわかりました。
http://phase.hpcc.jp/Omni/openmp-tutorial/sld049.htm これを使えば、「iccでOpenMPを使った限界までのパフォーマンスチューニング」は難しそうですが、
「自分のコードの駄目なところ(計算粒度、ロードバランス等)を効率的に見つける」ことはできそうな感じです。
これを使って駄目だったらWinへの移行も検討してみようと思います。
SolarisがN:Mスレッドモデルをやめたのは効率が悪かったから?
アプリが1:1モデルを前提に作られる(チューンされる)ようになったから。 アプリといってもぶっちゃけoracleだが。 SolarisのためだけにN:M用チューンするのは時間の無駄だからね。 これを効率というならば効率だね。
I/.O主体の仕事は前提とかチューンってこととは関係なく、 1:1の方が効率がいい場合が多いでしょ。 CPUを明け渡すのがカーネル内であることが多いから。 だからエンタープライズが主戦場のSolarisでは当然のことかと。
OSが1:1ばかりになったというのもあるよ
そういうことは関係ない。 ちゃんと選んでやっている。
M:Nはシグナルの動きが1:1のときと全く同じにはならない。
両モードでのデバッグや検証コストを掛けられない。
もう一つは
>>112 のとおり。
OS屋のオナニーで仕様が決まる時代は終わった。
マルチスレッドのデバッグではまっています (私が作ったんじゃないのですが) beginthreadが50個、EnterCriticaSectionが40個くらい、 スレッド最大200個くらいが動くとんでもないシステムです。 (もちろん満足に動いてないです) とりあえず、下記の方針でソースをチェックしようと思いますが、 他にもありますでしょうか? 1 InitializeCriticalSection()以前の行に、_beginthreadを呼び出す関数に入ってないか 2 スタティック変数、グローバル変数にEnterCriticalSecitonなしで書き込みを 行ってないか 3 newで作ったオブジェクトのポインタを複数のスレッドで参照してないか
>>116 とにかくアクセス違反で落ちたり、
const変数が書き換わったりするみたいです
もちろんマルチスレッドが原因かは特定できないのですが、
(ただ、ソースを見ると明らかにマルチスレッドを扱いきれてないです)
今、メモリ周りとかいろんな方面から数人で見ています。
もちろんデバッガ使ったりログ吐いたりはしています。
>>115 あと、EnterCriticalSectionへの再帰がないか。
同一スレッドだと、EnterCriticalSectionの挙動が変わるから注意。
どれくらいのスパゲッティ度かにもよるけども 仮想的なdbを用意して、データへのアクセスは必ずdb経由にするのも手だぞ。 (ポインタは渡さない、必ず生データのやり取りにする) 少なくとも知らない間に書き換わることはなくなる。 パフォーマンスは落ちるけどな。
>>118 なるほど、それは知りませんでした。ありがトン!!!!!
>>119 うーん、なるほど。それも覚えておきます。ありがトン!!!
とりあえず、ある程度安定してきたら、
再設計など検討するらしいです。
winapiでいうところのCrateEvent(), WatiForSingleObject(), SetEvent(), ResetEvent() に該当する関数ってPOSIXでいうとどんなものになるんでしょうか? mutexは双方にあって別にいいんですが、待機オブジェクトがなくて困っています。
新年明けましておめでとうございます。 本年も、マルチスレッドプログラミング相談室 その5にご健勝あれ。
本年の相談は終了いたしました。
126 :
デフォルトの名無しさん :2007/01/08(月) 22:40:26
実験用にものすごく単純なマルチスレッドの http サーバを組んでみたのだけど、 コードだけ見るとロックするようなコードじゃないのに、長時間ストップしたまま になることがある。(いちおう、しばらく待つと再開する) listen() 状態のソケット作って、accept() したら pthread_create() してループ。 子スレッドのほうでは GET (path) HTTP/1.1 を待って、そのファイルを読んで返すだけ。 という単純なやつなのだけど、毎秒100リクエスト以上くらい httperf で送ってやると、 必要以上に処理がストップする。 (netstat -a すると一つも ESTABLISHED になっていない状態で数秒間とまっている) カーネルは NUMA を無効にした以外は特にいじっていない Linux 2.6.15.7/x86_64 スレッドとネットワークをがんがんいじっている人には自明な問題っぽいけど、 どの辺に原因があって、どういじれば、せめて無駄なストップをしなくなるのでしょうか。
>>126 親スレッドでpthread_joinなり、pthread_detachしてる?
してないと、終了コード保持のため、子スレッドが終了せず、プロセスのスレッド数限界に
引っかかるかもしれん。
いちいちaccept毎にthreadを作成・破棄というのが良くない予感
>>126 子スレッドはちゃんjとソケットから全部読んでから closeするか、shutdown するかしてますか?
FreeBSDでコンパイル&実行するとそういう問題は起きない
131 :
デフォルトの名無しさん :2007/01/16(火) 22:08:14
_endthreadでスレッド終了すると、デストラクタが走りません。 無理やり{}で囲んでデストラクタを走らせてますが、 標準的な方法ってありますか?
_beginthreadは使わない _endthreadexは呼ばない
133 :
デフォルトの名無しさん :2007/01/16(火) 22:29:22
>>132 _beginthreadexを使い、スレッド終了時に_endthreadexを呼ばないで単にreturnするだけということでしょうか??
134 :
126 :2007/01/16(火) 23:37:42
ISP が割り当てるアドレスの周辺が 2ch にブロックされて書き込めなかった…。
スレッドとは関係なく、プロセス (もしくはある listen 状態のソケット)
あたりの同時接続数が一定値を超えると何かあるのかも、とか推測中。
>>127 pthread_detach() してますね。
>>128 待機スレッドを用意しておくとかすると改善するのかな。
>>129 あ、読み残しがある可能性はあるかも。
けど、そういう原因ならリクエスト頻度を下げても同様の問題が起こり
そうなものだが、 50リクエスト/秒くらいにすると起こらなくなる。
>>130 ソケット一般の問題じゃなくて Linux 特有の問題か…。
135 :
126 :2007/01/16(火) 23:39:44
あ、とりあえず接続数を減らして、一接続あたりの転送量を増やすことで 目的には事足りるので、とりあえずそのようにしてやっている。 なぜストップするのか、に対する興味はあるのでまだ調べているけど。
tcp_fin_timeout の話かなぁ 再利用できるポートが足りなくなって、待ちになってるとか
137 :
126 :2007/01/17(水) 22:48:11
>>136 あ、それビンゴかも。
Apache に細工して、一度ソケットを (勝手な手順で) 作り直してアクセスすると、
同様の停止現象が起こった調査結果が手元にある。
ソケットに何かの値を設定すると停止現象を回避できるのかなあ
(Apache は標準でそれをやっているけど、自分の勝手な手順ではやっていないのが原因かなあ)
と想像していた。 setsockopt() で *ソケットごとに* この tcp_fin_timeout を
設定できるらしいので、この値がそれかもしれない。
これから Apache のソースを読んでみるつもり。 thanks.
スレッドがシグナル状態になったあとに新たにスレッドを生成したいのですが、 そのスレッドのハンドルはクローズした方が良いのでしょうか? シグナル状態になったらスレッドのスタックは解除されるようですが。 上書きしてCreateThreadをしたらメモリリークしたりしますか? Win32APIです。
クローズした方が良い
ハンドルってただのポインタだから、 上書きしてもポインタ先が変わるだけ リソースは残ったままだとおもう
スレッドが終了してシグナル状態になったんであれば、 スタックとかコンテキストは解放されると思うけど ハンドルは残ったままじゃないか?戻り値を受け取るためにハンドルが必要だし。 といっても、ハンドルごとき残ったままでもたいしたことは無い。 (少々のリソース漏れはたいしたことないなんて言ってる奴のコードは信用ならんけど)
試してみた。 #include <stdio.h> #include <windows.h> static DWORD WINAPI func(LPVOID p) { printf("thread %d\n", (int)p); return 0; } int main() { int i; for(i = 0; ; i++) { if (::CreateThread(0, 0, func, (LPVOID)i, 0, 0) == 0) break; } ::getchar(); printf("i = %d error code %u\n", i, ::GetLastError()); ::getchar(); } VS2005のデバッガ上だと2000超えたあたりでERROR_NOT_ENOUGH_MEMORYで止まる。 デバッガ外でやってみたら10万超えても終わらず、 なぜかipoint32.exeにアプリケーションエラーが出たりして怖くなったのでやめた。
メモリリークか 何もかも(ry
func のスレッド優先度、上げといた方がいいのでは?
146 :
143 :2007/01/22(月) 08:17:30
あーそっか。あくまでハンドルのみのテストだったらちゃんとWaitForSingleObjectで待たなきゃいかんわな。 しかしWaitForSingleObjectしたのにわざわざCloseHandleしないでおく理由って考えにくいが。
CreateThreadで走らせたthreadでは、CRTのfunctionを呼ぶべきではない。
メモリーリーク?
再入?
とりあえずCRTは動的リンクしておけと
2つプロセスで共有メモリのデータを共有する サンプルってどこにあるのですか?pthread Linuxのやつを探しています。
スレッド関係ないから。APUE買え。
VS2005って標準でOpenMP使えたんだな
155 :
デフォルトの名無しさん :2007/02/18(日) 16:38:41
ここで俺がひとまずここまでのレスをまとめる。 マルチスレッドは ム ズ カ ス ィ
>>152 だまってmmapすればいいんでないの?
>>155 お前にこの言葉を授けよう
「糞スレ立てるな」
158 :
デフォルトの名無しさん :2007/02/20(火) 23:27:34
ファイアーモックス!
159 :
デフォルトの名無しさん :2007/02/24(土) 10:27:57
質問なんですがマルチスレッドでは同じ変数のアドレスの場所を if文等で見に行くだけならぶつかることはないですか?
読むだけなら問題ないと思。 最適化には気をつける必要があるが。
FAQだな。 読むだけなら排他不要。 ただしvolatileを忘れずに。 つーかvolatile最強。
>>159-161 別スレッドからの書き込みも考慮するならロックなどによる同期が必要。
volatile はネタだよね?
他スレッドが変更するメモリを読むなら必要でしょ。
おっ久々にvolatileが来たか。わくわく。
>>162 writerが一人、readerが複数ならロックする必要ないよ。
166 :
デフォルトの名無しさん :2007/02/24(土) 13:28:17
意地悪しないで教えてやれよって。
JavaやC#でのvolatileはその解釈であってる。
C/C++のvolatileは割り込みしか想定していないので、マルチスレッドでの動作は不定。
ただしシングルCPUでのマルチスレッドは割り込み(タイマー割り込み)で実現されているのでたまたま動作する。
>>165 変数がアトミックじゃない場合、例えば32bitCPUで64Bitの変数にアクセスする場合などは、
書いてる最中に読み込みされると半分しか書き換わってない状態を読み込む可能性がある。
シングルCPUのマルチスレッドだと動いてしまうことが多いからね。それで合ってると思い込んでしまうのだよ。 CPUキャッシュの問題は難解だね。 さらにウィークメモリモデルともなるとさすがについて行けんorz
書き込み側が明示的に、アトミック書き込み命令を出せばいいんでね?
読み込みもアトミックじゃねーと意味ね-よ
要は、アトミックに読み込めることが期待できるint程度のデータ以外はなんらかの排他が必要ということでよろしいか。 #いや、intでも排他するべきなのかもし煉瓦。
>>171 > #いや、intでも排他するべきなのかもし煉瓦。
というのが
>>168 だね
マルチCPU環境の排他はバス設計の影響もうけるから
環境を明記しないと言及不能やね
>170 書き込みがアトミックに出来るのに、読み込みがアトミックに出来ない、なんて 変態CPUが現存するのか?そういうCPUではロックをどう実装するんだろ?
キャッシュラインをまたぐと面白いよねー
>書き込みがアトミックに出来るのに、読み込みがアトミックに出来ない、なんて >変態CPUが現存するのか? >書き込み側が明示的に、アトミック書き込み命令を出せばいいんでね? ↓ >読み込みもアトミックじゃねーと意味ね-よ だれも読み込みがアトミックにできないなんて言っとらんわ。
どっちかというと >ねーと → ー >ね-よ → - この不整合の方が気になるな どちらかがアトミックじゃないのかもしれない
こういう意味不明な誤変換はUNIX発のFEPwに多いな
178 :
デフォルトの名無しさん :2007/02/25(日) 15:04:49
volatile方式を知られては困る奴が必死だなw
そのリンク先にしても、なぜvolatileでは駄目なのかが書いてなくて
「お母さんが駄目って言ってたから」レベルの話しか書いてないな。
そして、そのURLを貼る
>>179 も同様。
なぜ volatile で済むと言えるのか、書くかリンク貼るかしてみやがれ。
そんなわけないだろ。逆だ。 "Paradoxically, it's worse to use volatile directly with built-ins, in spite of the fact that initially this was the usage intent of volatile!"
>>182 これって
>スレッドセーフなメソッドにはvolatileをつける。
という提案だよな?まだ実装はないと思ったのだが。
volatileを実装してるJVMってほとんど無いんじゃなかったっけ
>>185 実装ってどういうこと?標準 C++ コンパイラがあれば使える手法に見えるんだけど。
C とか C++ の volatile って I/O レジスタとか, 割り込み同期変数とかを, オ プティマイザがレジスタキャッシュしないように指示するために導入された物で, バリア同期命令とか生成する処理系は皆無のような気がするが... 俺の認識が古くって, バリア同期とか生成してくれる処理系が既にあるんだった ら先にあやまっとく
何故「volatileで済む用途」のケースにメモリバリアがどうのという話になるのかわからんね。 簡単な例で言えば (タイマ割り込み等で更新される)カウンタを読む場合とか 複数スレッドで値を読み取るとしても、ロックする必要なんか無い。 たとえ1ns更新が遅れたって、問題が出ることは無い(問題が出るようなら、設計がおかしい)。 え、更新時の再入を考慮しろって? そういうのを「設計」と言うんだろうに。
>>182 int func() const { } はよく使うが、int func() volatile { } を実際に使ってる例ははじめてみる。
ただその記事のLockingPtrは func() volatile の仕組みだけ拝借して実際の排他はmutexでやってるようだ。
よく理解できない部分もあるがvolatileしておいてconst_castで限定的に穴あけてるのだろうか。
このスレで問題になるのはそこではなくて、
記事の最初と2番目のコードで while (!flag_) のflagがvolatileだけでいいのか、
同期機構を使わなくてはいけないかのポイントだと思う。
>>188 volatileで済むってのは、コヒーレントキャッシュを持っている環境で
アトミックに読み書きできるサイズ限定だから、メモリバリアは関係ないよ。
2つ以上の変数に依存関係があったら、volatileだけでは無理。
一般論の話をすれば、キャッシュの一貫性を保障しない環境もあるから
int程度でもvolatileでは駄目という話になるが。
ちゃんと読めてないが、
>>182 って、コンパイラの実装とか関係なくて
constみたいな印としてvolatileを使ってみようっていう提案だよね?
volatileの仕様は処理系定義だとあれほど言ってるのに… 処理系を指定しないでvolatileについて語れることはない
処理系どころか言語すら指定されてない気がするのは 漏れだけではないはずだ
とりあえず、volatileをCの最適化阻害だけと仮定して、
>>191 一貫性を保証しなかったとしても、それはあくまで保証の話。
いつまで経っても同期されないような腐ったCPUってあるの?
あったとしたら処理系としてBrokenだよなぁ・・・。
>>193 ここに書いてる人のほとんどは処理系依存だなんて承知の上でしょ?
とりあえず、intだとしても同期やメモリーバリアは必要か?
って問いはもう少しレベル分けした方がいいと思う。
1. 読み込みに依存した書き込み(read-modify-write)
⇒ 同期もしくはメモリーバリアを含んだCASが必要。
2. 読み込みに依存しないが、確実に更新を見る必要がある
⇒ OoOを回避するために、少なくともメモリーバリアは必要。
3. 読み込みに依存しないし、更新は近いうちに反映されればよい
⇒ volatileでレジスタへの張り付きを阻害するだけで問題なし?
>>189 の「更新が遅れても構わない」は3になると思うんだが。
つまり、例えば時間掛かる処理をするスレッドがあってその進捗をプログレスバーに出すような用途なら、 進捗を書き込むのを処理スレッドに限定してGUIスレッドでそこをvolatileで参照するのもありってことでOK?
マルチスレッドの話は環境によって差異がありすぎるから 環境を限定しない討論に何の意味もないって感じだな。
198 :
デフォルトの名無しさん :2007/02/27(火) 03:01:55
volatile最強伝説が吹き荒れるwww
> 195 > とりあえず、volatileをCの最適化阻害だけと仮定して、 曖昧な仮定だな。 まずはお前の想定している処理系と、そのマニュアルにある volatile参照の仕様を書くんだ。
もう
>>182 みたいにvolatileキーワード使って組込型でも何でもロック必須にしちゃいなyo!
template <typename T>
struct NativeWrapper
{
operator T&() { return obj; }
private:
T obj;
};
volatile NativeWrapper<int> syncint;
mutex mtx;
LockingPtr<NativeWrapper<int> > pInt(syncint, mtx);
*pInt = 10;
201 :
195 :2007/02/27(火) 12:18:08
>>196 そんなとこ。他ではTwo-Phase Terminationの終了フラグとか。
こちらの場合はメモリーバリアを含んだ同期をループの内部で
実行する事が殆どだから、次のループで確実に気付くだろうけど。
>>197 ,199
おまえら処理系依存って書きたいだけだろ?
実際のとこはどうなのか、って話がしたいんだよ。
少なくともOoOやコヒーレンシが問題になるんだから、
最低限SMP/Multi Core/HT等のアーキテクチャとなる。
例えばIA-32,Power PC,Sparc等のSMPの類をサポートした
アーキテクチャのうち、
>>195 よりも厳しい制約が必要と
なるものは存在するの?
>>201 個々の CPU について考えるなんて面倒だから、
保証されてるかどうかで話したほうが楽なのに。
今は無くても将来にわたって無いとも言えないしね。
>>193 データ構造上の都合か何かでキャッシュラインをまたぐような位置から
int を読み込む場合には 3 もだめじゃないかな。
>>201 Intel Itanium では、非共有キャッシュが大きい上にキャッシュフラッシュの順序が
書き込みの順序と異なる。ので、
・volatile int a を監視
・aが変更されたら「何か」を行う
という処理の場合、大抵は「何か」の準備が出来たから a を1にしてるんだと思うけど、
メモリバリアが無いとその準備の処理結果を読み出せない可能性がある。
例) volatile size_t buflen; volatile char buf[max_buf]; で、
スレッド1: buflen = read(hoge); ...
スレッド2: if (buflen>0) { bufを利用; }
で、(スレッド2側のCPUから見て)buflen には read の結果のバイト数が書かれているが、
buf の内容はデタラメ、という状況がごく当たり前にあり得る。
205 :
195 :2007/02/27(火) 14:54:42
>>203 キャッシュラインをまたぐ場合って、普通のコードじゃ起きないし、
char buf[sizeof(int)+1]; *(int *)(buf+1) = 0;した場合とかでしょ?
今では例外飛ばさずにアクセスできるアーキテクチャの方が少数派なのでは?
>>204 他の変数を確定的に見る必要がある場合はOoOの関係で無理。
>>195 はひとつのintを扱う場合なつもりで書いてます。
>>196 を例にすると、タイマでプログレスバーを更新する時はvolatileのみ、
最後に終了したかを確定的に判断したい時だけpthread_join()するケースとか。
>>205 PCで使われているCPUの98%は、それをごく普通に実行します。
任意位置からの32bitの整数読み出しはMPEG系のビデオコーデックの
処理では多利用されるし。
207 :
195 :2007/02/27(火) 16:11:02
CPUの数が多いのは当たり前だからアーキテクチャって書いたのに。 そんな下らないツッコミは要らないって。。 Codecの処理だろうが、境界整列に反したメモリアクセスなんて 行儀の悪いコードなんじゃないの?少なくともポータブルじゃない。 処理系依存のレベルで言ったらvolatileの比じゃないと思うんだけど。
アーキテクチャの数で言って多いか少ないかについては、 漏れは何も言っていません。 実存するシステムの大半では割合で例外は飛ばないという (関連する)別の事実を提示しただけですよ。
209 :
195 :2007/02/27(火) 18:33:40
>>208 おまえ例外が飛ばないって書きたいだけだろ?
実際のとこはどうなのか、って話がしたいんだよ。
理屈で勝てそうにないと急におまえ呼ばわりですか。 実際の例で言うなら、MPEGのシステムストリームから4バイト長さの整数を取り出すとき、 ポータビリティを重視している ffmpeg ではバイト単位で取り出して整列してますし、 IA32/64が前提のIPPではポインタをそのままデリファレンスしてアライメントを気にせずに整数を取り出してます。 「普通のコードじゃ起きないし、例外飛ばさずにアクセスできるアーキテクチャの方が少数派」だから、 キャッシュラインまたぎの問題は無視してよいとでも言いたげな感じですが、 実際のとこどんなプログラムをどれだけ調べた上で書いてるんですか?
IA86において、そもそも、アラインメントが狂った位置への アトミック書き込みはできない。
傍から見てるモノとしては 実装の詳細じゃなくてアーキテクチャの視点で語ってほしいです><
「相談室」なんだから、なにか適当なターゲットを想定するのが普通だろ メタ論がやりたいならどっか適当にスレ立てろよ これがほんとにマルチスレッド
そういうアクセスははなからそういうあくせすという前提で特別に処理を書くんじゃないの? intでもアトミックに読めないとか、そういう問題とは別次元だろ。
わざとあえて意識してそういうことをしないとそういうことは起こらない。
216 :
195 :2007/02/28(水) 01:26:31
>>210 >>209 は自分じゃないんで・・・。
他の方も書いているように、CodecみたいにCPUベタベタな
最適化を行う場合を考えてもしょうがないかと。
今のところは
>>189 や
>>196 みたいなケースの場合にvolatileで
不十分な証拠は(処理系依存を除いて)出ていないんじゃないですか?
そんなわけで、今のところ
>>180 から進展はなさそうに思います。
>>213 自分はPCサーバクラスで使われるCPU辺りをメインに書いてます。
今はノートですらDual Coreだったりするので、その辺りも含めて
昔で言うワークステーションクラスまででしょうか。
言語組み込みの volatile で全部済ませられると主張するなら、 「あぁそうだといいね」とも思えるが、場合によってはロックが必要なことは 理解しているようだし。そうなると細かいこと考えずに全部ロックしとけば いいと考えそうなもんだ。 なんでそんなに必死になってまでロック使いたくないの? わざわざ保証されてないコード書くメリットが何かあるの?
このスレは頭ごなしにmutex使えやゴラーというやからが多いから意固地になってるのだろう。 結論はそうなんだけど、そこに至る過程を検証したいというのも分からないではない。 mutexの中の人が何をやっているかとか、実際身近にあるPCで賢い小人さんがどう働いているかとか、 そういう話題なら問題は無いだろう?
>>217 >なんでそんなに必死になってまでロック使いたくないの?
実行コストに決まってるだろ。
実行コスト無視できるなら、スピンロック、read-writeロック、プロセス内Mutex、プロセス間Mutex、
の使い分けなんて必要ない。
ただ、volatileで生成されるコードと、他のロックでどちらがコストが高いかは知らん。実行系によるし。
スレッド間で変数を共有する場合問題になるのは次の4つくらいか。 1)変数のレジスターへのキャッシュ。 2)コンパイル時の命令の並び替え。 3)CPUによる命令の並び替え(out of order) 4)CPUキャッシュ間の非同期。 1,2はコンパイラの仕事。 3は単一CPUでは発生しない。マルチCPUでは両方のケースがある。 4は単一CPUでは発生しない。マルチでもコヒーレント(一貫性)が保障されている処理系が多い。 3,4が発生しないでメモリー更新の順番が正しく見える構成をstrong memory orderと呼ぶ。 volatileだと1,2でかつアトミックな操作ができる単独の変数のみ。 メモリバリアは1,2,3,4すべてを満たしていて、 同期系のファンクションを使えばメモリバリアは適切に適用される。 書き込みが1スレッドで多数の読み込みスレッドがある場合に通常のLockが負荷が高いようなら、 ReadWriteLockとかInterLockとかそういったものを検討すべきだろう。
>>195 >いつまで経っても同期されないような腐ったCPUってあるの?
>あったとしたら処理系としてBrokenだよなぁ・・・。
ないとは言い切れない。互換性、安全性をとるなら同期ファンクションを使っておこう。
windowsXPまではstrong memory orderを前提にしているらしい。
MSDNのvolatileの説明が変なのはこのためだろうか。
移植性を無視してターゲットを絞るなら独自にいろいろやるのもありかもしれないが、
windows2003(今のところItanium用だけらしいけど)からは上記の3,4があるweak memory orderも
視野にいれているらしいから、こういうヴァージョンアップ時に困るな。
組み込み用だとキャッシュの同期なんて全くしない環境もあるようだが、 (そもそもCPUがマルチプロセッサ用に作られていない) そういう環境にマルチスレッド対応のOSが移植されてるかは、 ググってみたが見つからなかったな。 一昨年あたりから、組み込み用CPUでもキャッシュ同期メカニズムを 持った物が出てきたようで、SMP対応のlinuxが移植されてたりするけど。
223 :
195 :2007/02/28(水) 17:27:11
>>218 ほぼそんなとこです。
あとは、なんでPOSIX ThreadsにCASがないのか、とかね。
プリミティブ志向な設計なんだから追加されてもいいのに。
有名どころのアプリのいくつかは自前で実装してたりするし。
>>221 そりゃないとは言い切れないでしょ。
でもそういうのって、二の補数表現や1byte=8bitを仮定して
プログラムを書くのは良くないってのと同じなんじゃないの?
1word=36bitみたいな変態アーキテクチャを相手するのと一緒。
_beginthreadの使い方について質問です。 子スレッドの処理が止まっているとき、終了する方法が知りたいです。 ----------------------------------------------------------------- //子スレッドの関数 void thread_func(){ //Sleep();やソケットのaccept関数など永久に待つ関数などで、 //処理が止まっているので終了状態になりません } //子スレッド呼び出し thread_id = _beginthread(thread_func,0,(void *)param) //終了処理 GetExitCodeThread( thread_id,lpExitCode );//終了コード取得 ExitThread(lpExitCode );//終了コード指定して終了 CloseHandle(thread_id);//ハンドル閉じる ----------------------------------------------------------------- 1、子スレッドのsleep、accept関数など待ち状態を、解除する方法あるでしょうか? 処理が進めば、_endthreadで終了することが出来きるのですが。 2、強制的に親スレッドから、安全に子スレッドを強制終了する方法あるでしょうか? _beginthreadは、CreateThreadを呼んでるみたいなのですが、上記のように "//終了処理"しても大丈夫でしょうか?安全な方法教えていただけないでしょうか。 よろしくお願いします。
>>223 なんで良くないと言われていることをわざわざやりたがるの?
>>225 良くないって、仕様で未定義だからってだけでしょ?
検証もせずに「お母さんが駄目って言ってたから」な方が嫌。
>>226 最近のレスでロック API の仕様の根拠となるものはあらかた提示されたんじゃないの?
>>224 とりあえず、
・必要なら、子スレッドでは極力タイムアウトするAPIを使う
・_beginthread()の場合、スレッド関数の戻りで子スレッドのハンドルは自動開放されるので
明示的に開放する必要はない
・少なくとも_beginthread()のハンドルにCloseHandle()を使うのは間違い
きちんと対応する関数をセットで使わなければいけない
・ただ、親スレッドでExitThread()したら、その後のCloseHandle()は実行されないよ
・子スレッドの安全な中断方法はない。
突っ込み所満載すぎるので、MSDNなりナニなりよく読むべし。
>>228 タイムアウト処理を考えるという方針でいきたいと思います。
sleepは時間を短くすればいいですし、
acceptは、selectを使ってrecvのタイムアウト関数(timeoutRevcとします)
と同じにすれば、timeoutAccept関数作れるかもしれないです。
・timeoutAccept抜けたら、はじめの一回目は、ソケットが読み込めるのわかってるので普通のrecv関数を呼ぶ。
・次の受信から、timeoutRevc呼ぶ感じでしょうか。
いくつも箇条書きでアドバイス、ありがとうございました。
229です。 acceptする前に、select関数使えないんでしょうか。 FD_ZERO(&readfds); FD_SET(soc,&readfds); select(width,&readfds,NULL,NULL,&timeout) socは、きちんと渡せていたんですが、接続試しても select抜けられずに、全部タイムアウトになります。 accept呼んでからじゃないと、ソケットの読み取り可能か わからないかもです。 スレ違いになりますので、ネットワークのスレに行きたいと思います。 ありがとうございました。
231 :
デフォルトの名無しさん :2007/03/01(木) 11:14:25
やべーvolatile最強すぎる
「volatileが最強でない環境って存在するの?」
「現存しないからvolatile最強wwwwwwwwwwwwwwwwwwww」
>>161 でFA出てるしwww
2000年問題に通じるものがあるな
233 :
デフォルトの名無しさん :2007/03/01(木) 12:28:10
[すれ立てるまでもない質問はここで] で聞いてたんだが、此処で聞いた方が良いかと思ったので、 再質問させてもらいます。 Windows MFCでマルチスレッドは止めておいた方が良い と、良く聞くんだけど、具体的にどんな問題が発生するのか 掲示しているところが無いんだけど、どうしてMFCでの スレッドは嫌われるのか教えてもらえないでしょうか。 単なる好奇心なので、仮説でもうれし。
誰が言ってんだ、そんなこと。
235 :
デフォルトの名無しさん :2007/03/01(木) 12:48:10
>>233 それま色々なスレで同じ質問をしないほうが良いと言われただけでは?
>>233 とりあえず移動元に誘導書いておけよ、マルチ扱いされるぞよ。
俺も聞いたことない。
MFCに限らず、マルチ(複数の)スレッドで質問するのは良くない。
ワロタ
240 :
233 :2007/03/01(木) 16:17:27
>>240 WaitForSingleObjectで待つんじゃなくて自イベントで通知
MFC関係なくないか?
読みづらいし会話式がアレだな
UIスレッドは確かに使わないかもしれない。向いてないとか難しいとかいうより必要性が薄い。 ワーカースレッドについては特にMFC特有の問題じゃないな。
>>240 じゃあ、そのサイトが間違い。
いや間違いというか、MFCがマルチスレッドに対して便利な機構を用意しているかというとNoだけど、
マルチスレッドを意識してないわけじゃない。つまり、ユーザーからロックできないグローバル変数、
クラス変数はロックしてる。
なんで、ユーザーからロックできる部分については、勝手にロックして、スレッドセーフにしろよ、
ってスタンス。それを「向いてない」と表現するかどうかは人による。
・MFCとマルチスレッドの関係 (Afx...でのMFCグローバル情報へのアクセス等)、
・Win32とマルチスレッドの関係 (SendMessageがらみのウィンドウループの把握、WinSockでのWM_を使った非同期処理等)、
・一般的なGUIシステムにおけるマルチスレッドの作法 (GUIスレッドを止めない、長時間処理は別スレッド、非同期化等)
を分けて考えるべき。
まぁMFCはガベコレがないという致命的欠点を持っているなんて Wikipediaに書かれるほど挫折した連中に嫌われているってことだな。
245 :
デフォルトの名無しさん :2007/03/01(木) 18:47:00
> それを「向いてない」と表現するかどうかは人による。 「俺はマルチスレッドなプログラムなんかできないから、ライブラリか何かでどうにかしてくれよ」という人? 「これさえ使えばあら不思議。マルチスレッドなプログラムが簡単に!」とか。 >まぁMFCはガベコレがないという致命的欠点を持っているなんて これは笑いどころですか?
246 :
243 :2007/03/01(木) 19:03:59
>> それを「向いてない」と表現するかどうかは人による。 >「俺はマルチスレッドなプログラムなんかできないから、ライブラリか何かでどうにかしてくれよ」という人? >「これさえ使えばあら不思議。マルチスレッドなプログラムが簡単に!」とか。 いや、俺に言われても。
247 :
244 :2007/03/01(木) 19:38:14
>>245 > これは笑いどころですか?
いや、俺に言われても。
248 :
244 :2007/03/01(木) 19:57:04
MFCにガベコレを求めるとかバカとしか思えない
244はそんなことを言ってるわけじゃないんだが。 改行位置のせいで勘違いするのも分からんでもないが。
このスレのガベージをコレクトしたい
/ ____ヽ /  ̄  ̄ \ | | /, −、, -、l /、 ヽ | _| -| ・|< || |・ |―-、 | , ―-、 (6 _ー っ-´、} q -´ 二 ヽ | | -⊂) \ ヽ_  ̄ ̄ノノ ノ_ ー | | | ̄ ̄|/ (_ ∧ ̄ / 、 \ \. ̄` | / ヽ ` ,.|  ̄ | | O===== | `− ´ | | _| / | | (t ) / / | 「>1からマークスイープでGCするよ!」 「コンパクションも忘れずにね」 1時間後… ,-――-、 ___ { , -_−_− / _ _ ヽ .(6( /),(ヽ| / ,-(〃)bヾ)、l /人 ー- ソヽ _ | /三 U |~ 三|_ / / |  ̄_∧/ ヽ |(__.)―-、_|_つ_) | | \/_/-、 / / /`ー--―-´ / |-\ _|_ )_| / | // ̄( t ) ̄/ ヽ-| ̄| |_|_ / ,− | | ヽ二二/⌒l / l―┴、|__) | (__> -―(_ノ / `-―┘ / `- ´ / 「>1しか残らなかった…」 「テンプレへのリンクもなかったのか!」
>>251 [゚д゚] ・・・?
/[_]ヽ
| |
pthreadのPTHREAD_MUTEX_INITIALIZERのように、 win32のCRITICAL_SECTIONを静的に初期化する方法はありますか。 現在は仕方が無いので static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; で済むところを static pthread_mutex_t mutex; static int initialized; static int lock; if (!initialized && InterlockedIncrement(&lock) == 1) { pthread_mutex_init(&mutex, 0); initialized = 1; } などと書きました。 なお、↑のコードでは、とりあえず #define pthread_mutex_t CRITICAL_SECTION #define pthread_mutex_init(A,B) InitializeCriticalSection(A) #define pthread_mutex_lock(A) (EnterCriticalSection(A), 0) #define pthread_mutex_unlock(A) (LeaveCriticalSection(A), 0) #define pthread_mutex_destroy(A) DeleteCriticalSection(A) などと定義しています(極めてうさんくさいですが)。
>>255 class CriticalSection
{
CRITICAL_SECTION csect;
public:
CriticalSection() { InitializeCriticalSection(&csect); }
~CriticalSection() { DeleteCriticalSection(&csect); }
void Lock() { EnterCriticalSection(&csect); }
void Unlock() { LeaveCriticalSection(&csect); }
operator LPCRITICAL_SECTION() { return &csect; }
};
class Lock
{
CriticalSection& save_cs;
public:
Lock(CriticalSection& cs) : save_cs(cs) { save_cs.Lock(); };
~Lock() { save_cs.Unlock(); }
};
static CriticalSection cs1; // で初期化しておいて下のように使える。 void func(){ Lock lock(cs1); // } void func(){ cs1.Lock(); // cs1.Unlock(); }
というやり方だと、 コンパイラの吐く「ローカルな静的変数の初期化コード」に排他処理が行われないため グローバル変数(staticメンバでも良いが)にしか使えない。 で、過去スレに書いたが CriticalSectionへのポインタとInterLockedExchangePointerを使えば ローカルな変数でも、排他しながらの初期化及び実行が行える。
なるほど。C++のstatic objectの初期化機能を利用する訳ですね。
Cでは使えないテクニックですね……。
>>255 のコードには不備がありました。
2コ目以降のスレッドがInitializedCriticalSection()実行前に
下に流れてしまう可能性があるので、
上のコードの後で
while (!initialized) Sleep(1);
としなければなりませんね。
>>258 >で、過去スレに書いたが
目を通しておきたいのですが過去スレというのはこのスレですか?その4以前?
最初のロックまでCRITICAL_SECTIONの初期化を遅延したいとか
考えない限り大丈夫のように思えるけど。
んー、だから static CRITICAL_SECTION *p = NULL; if (!p) { CRITICAL_SECTION *q = new ...; Interlocked...(&p, NULL, q); //引数の順番忘れた if (p != q) { delete q; } } EnterCriticalSection(p); ... Leave...(); なら、Cでも使えるよ。
で、C++なら、これをclassにまとめて #ifdef _WIN32 で切り分けてPTHREAD_MUTEX_INITIALIZERと使い分けると楽だよ。 ただ、必ずstaticなオブジェクトとして使わないといけない、ということを 分かった上で使わないといけないけど。
あ、Initializeとか忘れてたけど まあ分かるでしょ
>>261 new, deleteがCでも使えるというのは冗談でしょう。
if (!p) {
CRITICAL_SECTION *q = new ...;
これは、この部分に2コ以上のスレッドが同時に突入した場合、
2度以上InitializeCriticalSection()を実行させたいという意味ですか?
265 :
259 :2007/03/04(日) 06:15:36
> while (!initialized) Sleep(1); このように書きましたが、これはWin32環境で合法なのでしょうか。 マルチコアのシステムではまずかったりしますか。 MSVC++で-Ox最適化をかけたアセンブリコードを眺める限り、 一見動きそうに思えますが、いまいち自信がありません。
266 :
260 :2007/03/04(日) 06:16:08
>>261 初期化を遅延する場合ですね。それなら了解。
>>264 newが使えない事くらい、わかった上で書いたんだけど(面倒だから)
そんな本質的じゃない部分を指摘してうれしい?
件の部分は、(ほぼ)同時に突入したら、当然複数初期化される。
けど、続く部分で、実際に代入されるのは一つであることが保証される。
(最初に実行されたスレッド以外からのCASは失敗する)
だから、それを実行した後、自スレッドで初期化した値とpが違っていたら
それを破棄して、全スレッド共有の値でロックを実行すればよいだけ。
まあ、俺が偉そうな事言いたくて書き込んだだけだから、あまり気にするな。
普通に非ローカルな静的変数とC++のインスタンス初期化を使うのが
いちばん簡単だし、わかりやすいし、無駄も無い。
初期化順が問題になることも無いでしょ。
268 :
259 :2007/03/04(日) 07:17:53
>>267 > そんな本質的じゃない部分を指摘してうれしい?
気を悪くされたならすみません。
Cで書いた場合のコードに、
>>255 と本質的な違いがあるのか?と
問いたかっただけです。
newが使えないだけではなく、クラスも使えませんよね。
>>261 は全くCのコードではありません。
> 件の部分は、(ほぼ)同時に突入したら、当然複数初期化される。
単に複数回初期化されるだけでなく、メモリリークが発生しますね。
> メモリリークが発生しますね。 だからわざわざ(本来なら省略しても良い)deleteまで書いたんだけど?
まさかとは思うけど 「実行中に確保(初期化)されて、終了時でも解放されないままのもの」 という意味で「メモリリーク」という言葉を使っている、 More Effective C++すら読んでないような初心者だったら、ごめんよ。
>>268 >>261 はいろいろ省略してるのだけど、InterlockedCompareExchangePointerを使えといってるのだと思うよ。
>Cで書いた場合のコードに、
>>255 と本質的な違いがあるのか?と
>問いたかっただけです。
どちらも遅延初期化で本質的な違いはなさそうだけど、
>>261 はダブルチェックロッキングが正しく出来ているが
>>255 には穴がある。
272 :
259 :2007/03/04(日) 08:27:12
>>269 理解しましたm(_ _)m
他スレッドのInterlockedExchangePointer()によって値が変えられていたら
deleteするという意味なのですね。
Cで書くと
static CRITICAL_SECTION *p = 0;
if (!p) {
CRITICAL_SECTION *q = malloc(CRITICAL_SECTION);
InitializeCriticalSection(q);
InterlockedExchangePointer(&p, q);
if (p != q)
free(q);
}
でしょうか。
273 :
259 :2007/03/04(日) 08:30:03
んが。 malloc(sizeof(CRITICAL_SECTION)); ですね。 それと。InterlockedExchangePointer()ではなく、 InterlockedCompareExchangePointer()を使わなければならないのですか。 むずかしい...。
274 :
259 :2007/03/04(日) 08:32:30
あーそうか、ほんとごめん。
確かに
>>271 の通り、CompareExchangeの方のこと(つまり
>>258 が俺の凡ミス)。
俺が重要な部分を間違えていたのに、意図を理解してくれる人がいてくれて助かった。
他の人も含め、ごめんね。
>>259 では、本質的な解決にならないと思うよ。
つまり、比較(テスト)と初期化(&代入)の間に他のスレッドに割り込まれる可能性を消すには
atomicなCASを実行するしかないって事。
あ、そうか、
>>255 を見るとInterlockedを使っているのか。
でも、InterlockedIncrementは正負と0しか判定できないんじゃなかったかな。
で、仮に
初期値を-1として
2^32個以上のスレッドが同時に初期化部に入ることは有りえないとして
>>259 の修正(Inc失敗なら他のスレッドを待つ)を加えて
当然volatileにして
とすれば、正常に動くのかな。
でもそこまでするなら、やっぱりCASを使う方がまともかと。
277 :
259 :2007/03/04(日) 09:40:12
>>276 はい。CAS方式がエレガントでまともなコードであると納得できました。
Sleep()ループで待つなんてカッコ悪いことは出来ればしたくありません...。
有難うございます。
ここまでやれば大丈夫だと思うけど。 if (!initialized) if(InterlockedIncrement(&lock) == 1) { pthread_mutex_init(&mutex, 0); initialized = 1; メモリバリア〜〜 } else { while (!initialized) { Sleep(1); メモリバリア〜〜 またはinitializedが揮発性であることが必要 } } } 老婆心から言えばスレッド生成前までに作っておいたほうがよいと思う。 スレッド生成後の初期化なんてバグの元。 PTHREAD_MUTEX_INITIALIZERマクロが何をやってるか調べてみたら何かヒントがあるかもしれないね。 javaで有名になったダブルチェックロッキングの話はまだ半分くらいしか理解できてないしなorz
InterlockedIncrementはWin95以前だと正負と0の判定しかできないので
>>255 のようには使えないよね。
あと厳密に言えばの話だけど
このスレの上のvolatile関連の議論からするとinitialized=1;の変更がキャッシュのせいで
他のスレッドに伝わらないかもしれない(規格的には)ので
>>255 のinitializedにはlock命令が必要だけど
lock命令を追加しようとすると結局
>>261 みたいになってしまうんじゃないかな。
別に言わなくてもわかるだろうけど
>>255 は volatile static int lock = 0;
>>272 は
volatile static CRITICAL_SECTION *p = NULL;
if (p != q) { DeleteCriticalSection(q); free(q); }
> PTHREAD_MUTEX_INITIALIZERマクロが何をやってるか これはさすがに定数値を{}なりで囲んでるだけだと思うけど。 Cでも使えるんだし。
281 :
259 :2007/03/04(日) 09:52:14
PTHREAD_MUTEX_INITIALIZERは単に{ 0 }
とかだと思います。
>>279 うわ。赤面しまくりです...。
ぶっちゃけUnixベースのライブラリをちょろっといじくってWin32に
移植しようと思っただけなのですが、こんなワナが待っていたとは
思ってもいませんでした。
282 :
デフォルトの名無しさん :2007/03/04(日) 10:24:41
下の例の場合変数iにvolatileは必要かどうか質問です。
lock, unlockがメモリバリアだから必要ないという認識なのですがつけている例も見ます。
>>261 だとlockせずに読んでる箇所もあるので必要なのかもしれませんが、
この辺の基準ってどうされていますか?
int i;
thread_function() {
mutex.lock()
i = i + 1;
mutex.unlock()
}
だれか .NET Frameworkのメモリモデルとかに詳しい人おらんかね?
>>282 付けといた方がいいんじゃない?mutexのメモリバリアでcpuキャッシュの同期は取れても
スタックやレジスタに積まれたままだったら意味ないしね。
>>283 設計上はウィークメモリオーダリングということなので、OoOあり〜の、コヒーレンシキャッシュは信用できね〜のです。
今のところ実装上はx86系のWindows上ではストロングメモリオーダリングのみ。
Itaniumは構成によってウィークメモリオーダリングもある得るそうです。
ところが、CLR2.0では書き込みオーダは保証されてて、 今後もそうだと約束されてるらしい。 それはおいといて、よく理解できてないのが、 書き込みスレッドでメモリバリアを実行した場合、 読み込み前のメモリバリアは必要なのかどうか。 あるメモリ領域に書き込みしてメモリバリア実行、その後完了フラグセット。 別スレッドで完了フラグを確認してからメモリ領域を読み込みってときに、 完了フラグ確認後にメモリバリアは必要なのかどうか。 なんとなく読み込み順が保証されないから必要な気もするんだが、 .NETのメモリバリア命令はフルメモリバリアだから不要?ってのも見た。 .NETのメモリバリアは別プロセッサの読み込みキャッシュもクリアして かつJITの最適化とかで先読みとかがおこらないなら大丈夫なんだと思うんだけど この方面素人なのでいまいちよく分からない。
メモリバリアの説明には、このプロセッサ上でキャッシュをフラッシュするとかって説明になってんだよね…
Itaniumだと、そもそもout of orderしないですな。 命令の並べ替えや並列化はすべてコンパイラの仕事だ。
だからこそ その辺の事情は本来プログラムで意識したくないよな・・・ DCLの欠点なんて最たるものだし
>>282 メモリバリアだから必要ないという認識では、ちょっと違うね。
関数呼び出しをまたいでグローバル変数をキャッシュできないから
volatileが必要ないというのが本質。
変数をレジスタ等にキャッシュしていないからこそ、メモリバリアが有効になる。
仮にlockやunlockをインライン展開できるようなコードで実装できたとすると
while() { lock(); i = i + 1; unlock(); } はvolatileが無いと危険かもしれない。
>>290 それは本質じゃなく単なる実装の話だと思います。
たとえばmsvc++などは次の理由からそういう実装になっています。
現在のx86系WindowsはOoOはやっててもアプリからは見えないハード的な仕掛けになっていますし、
コヒーレントキャッシュもある前提なのでキャッシュによる不整合もありません。
x86はレジスタの数が少ないので関数呼び出しのタイミングで変数をメモリ上に書き出します。
たとえばpthreadのmutexではvolatileは不要とドキュメントにあります。
すべてのコンパイラがそうなってるかどうかは分かりませんが、少なくともスレッド系のライブラリと一体で
提供されている環境ではサポートされているはずです。
>>291 インライン展開できない関数を呼ぶ前は、x86であろうと無かろうと
非ローカル変数をキャッシュできないよ。
レジスタの数が問題なのではなく、非ローカルな変数は呼び出した先で
更新される可能性があるから。
あと、ローカル変数でも、アドレスを取って他の関数に渡している場合に
その前と後で変数の中身が変更される可能性は、コンパイラも考慮しているはず。
だから例えば
>>255 のlockや
>>272 のpにはvolatile不要なはず。
もちろん、
>>255 のinitializedには必要だけどね。
で、pthread_mutex_tも、アドレスを取って渡すのだからvolatile不要、
という考え方でも充分かもしれない。
ただし、アドレスを取って呼び出した関数から戻った後に
変数の中身が他のスレッドによって変更される可能性は考慮されないので
レジスタにキャッシュされるかもしれない。
それが問題になる可能性がある(コードで中身を参照している)ならば
volatileが必要になるね。
>>292 確かにそこは例えが悪かったので取り消します。
(PGOのような広域のインライン展開のことを考えていたのですが論旨に合わないようです)
言いたかったのは同期関数の呼び出しのタイミングで
偶然レジスタとメモリの同期が取られているという話ではなく、
メモリバリア実現の属性のひとつとして関数の呼び出し時にレジスタとメモリの同期が
とられるという仕組みが利用されてるということです。
だから、レジスタとメモリの同期以外にCPUキャッシュ間の同期やOoOの調整が必要ならば
その処理が同期関数に含まれていなければならないと考えているわけです。
295 :
デフォルトの名無しさん :2007/03/05(月) 18:53:41
____ / \ / ─ ─\ / (●) (●) \馬鹿ばっか | (__人__) | \ ` ⌒´ / ノ \ /´ ヽ | l \ ヽ -一''''''"~~``'ー--、 -一'''''''ー-、. ヽ ____(⌒)(⌒)⌒) ) (⌒_(⌒)⌒)⌒))
296 :
デフォルトの名無しさん :2007/03/05(月) 22:57:17
volatile旋風スゴス
質問です。 while ( count > 1 ){ pthread_cond_wait( &cond_t, &mutex ); } この場合、条件変数と呼ばれるものはcountですか? それともcond_tになるのでしょうか? また、countのチェックにifは使ってはならない。と言われたのですが、 なぜだか解りません。 上記の部分と、 while (1){ if( count > 1 ) pthread_cond_wait(ry); } は同じだと思うのですが・・・ よろしくお願いします
>>297 while (1)
{
if( ! (count > 1) ) break;
pthread_cond_wait(ry);
}
と同じだと思う。
> 条件変数と呼ばれるものはcountですか?それともcond_tになるのでしょうか? 条件変数はcond_t。!(count>1)は述語。 > countのチェックにifは使ってはならない。と言われたのですが、 言った本人に聞けばいいと思う。いけないってことは無いと思う。 pthread_mutex_lock(&mutex); while (!pred(ry)) pthread_cond_wait(&cond, &mutex); pthread_mutex_unlock(&mutex); というのが定型パターンの予感はするんで、 その人にとって奇怪なコーディングするなという意味かもしれん。
ありがとうございます。 countは述語っていうのですか。知りませんでした。 >ifでんでん 後でもう一度聞いてみます。
でんでんってなんだ。云々(うんぬん)と言いたいのか、わざとボケてるのかどっちだ。
>>302 単なる2chのジャーゴンだから気にするな
countが述語なんじゃなくて "count>1"が述語 countは単なる変数
305 :
301 :2007/03/11(日) 15:38:51
>>304 "count>1"で、述語。ですか。解りました。
ありがとうございます。
>>でんでん
"うんぬん"で"云々"ですか。初めて知りました
ゆとり年代より一つ上なはずなんだけどゆとりでごめんなさい
306 :
300 :2007/03/11(日) 15:43:08
ごめん。!(count>1)でなく、count>1だった。 301に幸あらんことを。
俺がかつて1日だけ流行らそうとしてばら撒いてたでんでんが意外な影響を。
「云々」を「でんでん」ってことは 「云」を「でん」と読んでるって事だよな。 俺、そもそも「云」という漢字、単独でどう読むか知らないのだが。
伝が“でん”だからなあ
雲が「うん」と読まれることには頓着しないらしい。
ワンタン 雲呑
うーんぬんむーしむし、かーたつむりー
314 :
デフォルトの名無しさん :2007/03/16(金) 09:25:59
____ / \ / ─ ─\ / (●) (●) \ 「テラワロスwwwwwwwうぇうぇwwww」・・・・と | (__人__) | ________ \ ` ⌒´ ,/ .| | | ノ \ | | | /´ カタ. | | | | l カタ | | | ヽ -一ー_~、⌒)^),-、 | |_________| ヽ ____,ノγ⌒ヽ)ニニ- ̄ | | | ____
315 :
デフォルトの名無しさん :2007/03/20(火) 00:12:35
ごめん書籍いいでしょっていわれてるけれど マルチスレッドの勉強する本をおしえてほしいの
マルチスレッドについて本で得られるものは1%もない。 といっては見もふたもないので、もう少し具体的にマルチスレッドで何をしたいの? OSは?マルチスレッドアプリ?APIがしりたい?それともカーネルの実装(はないよな)?
317 :
デフォルトの名無しさん :2007/03/20(火) 15:54:59
Unix 方面の人は「実践マルチスレッドプログラミング」 Win32の人は「Win32マルチスレッドプログラミング」 当り前のことが当たり前に書かれてるだけで、 別にいいも悪いもないけど。 このあたりに出てくるような概念、問題、手法については常識として理解した上で、 新しい手法やOS/CPU/言語毎のメモリモデルなどについての知識を深めると、 volatile 論議とかで無駄に遊べる。
319 :
デフォルトの名無しさん :2007/03/21(水) 00:27:18
>>317 素朴な疑問
> Unix 方面の人は「実践マルチスレッドプログラミング」
> Win32の人は「Win32マルチスレッドプログラミング」
この辺を読めば volatile 最強って言い切れるようになるんですか?
317をもう一度よく読んだほうがいいんじゃない?
自作自演の可能性
volatile厨を論破するのはそんなに簡単じゃないよ。
NG登録するだけだし
324 :
デフォルトの名無しさん :2007/03/24(土) 10:03:31
Win32の本ってオライリーのやつのことでいいの?
>>315 並行プログラミングの原理―プロセス間通信と同期への概念的アプローチ (単行本)
326 :
デフォルトの名無しさん :2007/03/27(火) 14:50:58
____ / \ /\ キリッ . / (ー) (ー)\ / ⌒(__人__)⌒ \ volatile厨を論破するのはそんなに簡単じゃないよ。 | |r┬-| | \ `ー'´ / ___ / \ クスクスッ /ノ \ u. \ !? / (●) (●) \ | (__人__) u. | \ u.` ⌒´ / ____ / \!?? / u ノ \ クスクスッ / u (●) \ | (__人__)| \ u .` ⌒/
327 :
デフォルトの名無しさん :2007/03/27(火) 22:33:12
Javaのsynchronizedとwaitとnotifyに関する質問なんだが
http://www.javaworld.jp/technology_and_programming/-/10941-5.html ここの
class Buffer {
private int value;
private boolean isEmpty = true;
public synchronized void putValue(int v) {
while (!isEmpty) {
try {
wait();
} catch (InterruptedException e) { }
}
notifyAll();
isEmpty = false;
value = v;
}
public synchronized int getValue() {
while (isEmpty) {
try {
wait();
} catch (InterruptedException e) { }
}
notifyAll();
isEmpty = true;
return value;
}
}
これがどうして動くのか分からん。
あるスレッドがgetValueに入ってる間は、ほかのスレッドは
getValueにもputValueにも入れないんじゃないのか
すまんソースコードが見づらくなってしまった。 リンク先を見てくれ。
すまんかった。 とんくす
332 :
デフォルトの名無しさん :2007/03/28(水) 08:53:09
____ / \ /\ キリッ . / (ー) (ー)\ / ⌒(__人__)⌒ \ の二段落目を理解できない無能? | |r┬-| | \ `ー'´ / ___ / \ クスクスッ /ノ \ u. \ !? / (●) (●) \ | (__人__) u. | \ u.` ⌒´ / ____ / \!?? / u ノ \ クスクスッ / u (●) \ | (__人__)| \ u .` ⌒/
333 :
デフォルトの名無しさん :2007/04/01(日) 13:51:44
LAN 内の複数のファイルサーバーから (巨大な) ファイルを一括してダウンロードするプログラムを作成していますが、 おそらくネットワーク通信がボトルネックになるので、 サーバーごとにスレッドを作成してマルチスレッド化しても 高速化にならないですよね?
小さいファイルを大量に、だったら考えられなくもないけどね・・・
>>333 それぞれのサーバーのレスポンスが回線速度より相当遅ければ
早くなる可能性はあるんじゃね?
LAN内だとレアケースかもしれんけどWANならそれなりに効果はある。
効果があるかどうかは1サーバーからのダウンロードだけで帯域を
使い切っているか計測してみればいい。
>>333 LANだったら、下手に同時に別のサーバにアクセスすると却って遅くなるかもしれないね。
337 :
デフォルトの名無しさん :2007/04/02(月) 16:52:23
____ / \ / ─ ─\ / (●) (●) \ <春だなぁ・・・と | (__人__) | ________ \ ` ⌒´ ,/ .| | | ノ \ | | | /´ | | | | l カタカタ | | | ヽ -一ー_~、⌒)^),-、 | |_________| ヽ ____,ノγ⌒ヽ)ニニ- ̄ | | | ____
自分で考えないから
>>295 とか書かれちゃうんだよ
340 :
デフォルトの名無しさん :2007/04/10(火) 09:03:48
____ / \ / ─ ─\ / (●) (●) \ <俺も何も考えずにそれ貼ったんだけどね・・・ | (__人__) | ________ \ ` ⌒´ ,/ .| | | ノ \ | | | /´ | | | | l カタカタ | | | ヽ -一ー_~、⌒)^),-、 | |_________| ヽ ____,ノγ⌒ヽ)ニニ- ̄ | | | ____
内容が稚拙なのは確かだな
やっぱ玄人は 「マルチスレッドロジックにマルチスレッドロジックが重なるアミダのトグロwで超絶難しい」 だよなw
一度ハマるとそれを避けるようになるよ 気がついたらシングルスレッドに
と似非コンサルがさも大発見をしたかのようにおっしゃりましたとさ
確かに一番の解決策は 「マルチスレッドを使わない事」かも コンパイラなりインタプリタなりが、自動的にマルチスレッド化してくれるのが理想だけど まぁ無理だろうね
346 :
デフォルトの名無しさん :2007/04/11(水) 00:26:05
____ / \ /\ キリッ . / (ー) (ー)\ / ⌒(__人__)⌒ \ と似非コンサルがさも大発見をしたかのようにおっしゃりましたとさ | |r┬-| | \ `ー'´ / ___ / \ クスクスッ /ノ \ u. \ !? / (●) (●) \ | (__人__) u. | \ u.` ⌒´ / ____ / \!?? / u ノ \ クスクスッ / u (●) \ | (__人__)| \ u .` ⌒/
必死だなぁ
348 :
デフォルトの名無しさん :2007/04/11(水) 09:11:05
>>345 最近は自動的にマルチスレッド化してくれるコンパイラもあるじゃん。Intelとか。
CoreMicroFusionが利かなくなるとか、ほとんど効果が無いという問題はあるけど。
あれは複数パイプラインのスケジューリングの延長線上に過ぎないだろう
「アミダのトグロ」で釣れまくってるな。 釣れたのは全部、似非技術コンサルみたいだけどw
openmpのような自動的なのって流行るのかねぇ? それほどのヘビーロードな用途があんまり見えん 今の用途がつまんないWebアプリに偏ってるというのもあるけど
流行とか関係なく必要な場面で必要な人が使うだけ。 科学技術計算や並列処理とは無縁な 似非業務コンサルには一生関係。
流行とか関係なく必要な場面で必要な人が使うだけ。 科学技術計算や並列処理とは無縁な 似非業務コンサルには一生関係なっしんぐ。 似非コンサルが気付かないうちに 一般向けにマルチコア対応コンパイラーが普及するだろ
354 :
デフォルトの名無しさん :2007/04/11(水) 13:01:42
技術計算で本格的に使うならOpenMPよりMPI
いつも思うんだけどさぁ、 そこで一行tipsみたいなハッタリしか書かない奴って 議論上どう扱ったらいいのさ? ググルくん?
357 :
デフォルトの名無しさん :2007/04/12(木) 08:22:59
____ / \ /\ キリッ . / (ー) (ー)\ / ⌒(__人__)⌒ \ 一行tipsみたいなハッタリしか書かない奴って議論上どう扱ったらいいのさ? | |r┬-| | \ `ー'´ / ___ / \ クスクスッ /ノ \ u. \ !? / (●) (●) \ | (__人__) u. | \ u.` ⌒´ / ____ / \!?? / u ノ \ クスクスッ / u (●) \ | (__人__)| \ u .` ⌒/
358 :
デフォルトの名無しさん :2007/04/12(木) 08:57:53
議論とか一行tipsってなんだ? 質問したのに回答をもらえなかったやつが粘着してんのかw
変なAA書きと変な文句言いが 24時間体制で常駐している事は理解できた ____ / \ /\ キリッ . / (ー) (ー)\ / ⌒(__人__)⌒ \ 議論とか一行tipsってなんだ?質問したのに回答をもらえなかったやつが粘着してんのかw | |r┬-| | \ `ー'´ / ___ / \ チネクズッ /ノ \ u. \ !? / (●) (●) \ | (__人__) u. | \ u.` ⌒´ / ____ / \!?? / u ノ \ ヒッコメバーカ / u (●) \ | (__人__)| \ u .` ⌒/
360 :
デフォルトの名無しさん :2007/04/12(木) 10:45:01
オブジェクト指向って使わんの?
ライブラリとかで配布する以外なら使う必要ないとかあった。ものは作れればい院です
362 :
デフォルトの名無しさん :2007/04/12(木) 12:11:36
俺もそう思う ものが出来ればやり方なんてなんでもいいと思う 業務で使うなら色々制限はあるだろうけども
OpenMPはそもそもたいしてスケールしない上に、 ターゲットであるところの多重度が低い用途でさえも現状 MPI に性能で負けてるってのが定説なんじゃないの? コード書くのは楽だけど。 インテルあたりの実装が変わったかなにかして進展でもあったのか?
技術計算で本格的に使うならOpenMPよりMPI
365 :
デフォルトの名無しさん :2007/04/12(木) 21:11:26
Visual C で信号処理シミュレーションのプログラムを書いています。 一部、処理の高速化のためインラインアセンブラでSSE2の命令を 使おうとしています。 ここで疑問が生じて悩んでいます。それは次のとおりです。 WINDOWS XPのマルチスレッドでスレッドが切り替わった瞬間は、 CPUのXMMレジスタの値はスタックにOSのカーネルが退避して くれるのか?ということです。 それとも、スレッド切り替えを検知して、XMMレジスタの値を 退避させるコードを自分で書く必要があるのでしょうか。 環境は次のとおりです。 OS:WINDOWS XP 開発環境:Visual C++ .net 2003
OSがそのCPUに対応してればユーザプロセス側で考慮する必要はないやろ。 XP無印は2002年だっけ、その頃もうXMMレジスタがあったと思うけど。
>それとも、スレッド切り替えを検知して、XMMレジスタの値を >退避させるコードを自分で書く必要があるのでしょうか。 こういうコードは書こうとしても書けないと思います。
368 :
365 :2007/04/12(木) 22:31:48
ありがとうございます
>>366 >>367 スレッド切り替え時のXMMレジスタ管理は、
OS側でやってもらえるつもりで作ってみます。
>>365 やっとメモが出てきた。
SSEのSIMD命令を使うためにはCR4のOSFXSRビットが立っている必要があってこのビットはOSが立てる。
OSがSIMDをサポートしてない場合はこのビットが立っていないので、そもそもSIMD命令が使えない。
CR4の読み書きは保護レベル0でないと出来ないので、アプリから実際に命令が使えるどうかの
判定は実行してみてGP(CPU例外)を捕まえるしかない。
ただしCPUにSIMDの能力が潜在的にあるかどうかはCPUID命令でわかる。
>>365 趣味でやるなら止めないが、業務でやるならiccを使う方が(早|速)いかもよ。
>>365 Windows だったら、IsProcessorFeaturePresent() で調べてOKならOSが
サポートしているということ。
372 :
デフォルトの名無しさん :2007/04/13(金) 22:07:03
あるオブジェクトに対し、読み込みスレッドが多数、書き込みスレッドがひとつだけあります。 読み込みスレッド同士は排他したくないんですが、書き込みスレッドがアクセス中は 読み込みスレッドと排他したいのです。 こういう場合どういう排他制御が定石でしょうか? Win32APIで クリティカルセクションでオブジェクトを囲ってしまうと、読み込み書き込み の同時アクセスは防げますが、読み込み同士でも排他しあって具合が よくありません。
スレッドで制御するよりSQL標準で SELECTは共有ロック、UPDATE、INSERT、DELETEは排他じゃなかたかな
>>372 Advanced Windowsにシングルライタ/マルチリーダガードの例があるよ。
下手に作ると単純にクリティカルセクションで囲むよりも遅くなると思う。
>>372 読み込みスレッドは TryEnterCriticalSection で
ブロックさせずにクリティカルセクションの所有権を取得。
書き込みスレッドは EnterCriticalSection で
普通に排他させればいけると思う。
(ただしTryEnterCriticalSection はNT系OSのみのサポート)
377 :
372 :2007/04/13(金) 23:02:12
名前のヒントをいただいたので、 Readers writer lock でググってみました。 Win32APIだと既成の同期オブジェクト一個をそのまま使う というのでは済みそうに無いですね…。 ありがとうございました。
378 :
372 :2007/04/13(金) 23:10:23
>>376 読み込みスレッドにて、TryEnterCriticalSectionで所有権の
取得に失敗して戻ってきた時、所有してるのが他の読み込みスレッド
か書き込みスレッドなのかはどう判断するんでしょうか?
>>375 その本持ってないもので…
379 :
372 :2007/04/13(金) 23:21:23
>>378 たしかに376のやりかただと
読み込みスレッドが所有権を取得しているときは
書き込みスレッドはブロックできるが、
書き込みスレッドが所有権を取得しているときに
読み込みスレッドがブロックできないので、
以下のように書き込みスレッドの所有権を示すフラグを用いる。
1.書き込みスレッドが EnterCriticalSectionを呼ぶ直前にフラグ立てる。
2.読み込みスレッドがそのフラグを見て、フラグがたっていれば
EnterCriticalSection、たってなければTryEnterCriticalSectionを呼ぶ。
3.書き込みスレッドで LeaveCriticalSection を呼んだ直後にフラグをおとす。
だめだめだろ
読み取りスレッド1がロック開始 読み取りスレッド2がTry〜で失敗、でも読み取りなので続行 読み取りスレッド1が処理完了、ロック開放 書き込みスレッドがロック開始 読み取り操作とバッティング
ReadWriteLockっていうやつのことか
ReadWriteLockはいったんMonitorもどきを作れば、 ネット上に転がっているJava用のソースが流用できるようになる。 lock/unlock/nitifyAllが実装できれば十分。
下手に使うと余計遅くなるから注意。
vistaからReadWriteLockのAPIが新設されたような…
>>372 >具合がよくありません。
具合は良い。
Compare and swapとかwait-free関連の参考書教えてください。 古くさいAPIの使いかた載った本は一応全部あります。
まずは、その古臭いAPIの載った本の一覧を書いてもらおうか。
>>387-388 Vistaってpthred風のCondition Variablesなんかも追加されてるのか。
なにげにスレッド関連のAPI拡張多いな。
「一回だけ初期化」用の仕組みも追加されてる なにげにうれしい つかXPまでとvista以降では作り方が変わってしまわないかな・・ 最近気づいたんだが、mutexの獲得が要求順じゃなくなってるのな server 2003から変わったらしい
「一回だけ初期化」ってどういうの?
シングルトンのインスタンス生成を確実に一度だけ行うとかじゃない? pthread_onceみたいな。
なるほど、あったら便利かも。
どうせマイクロソフトの実装なんぞあてになんねーんじゃねぇの?
どっちかっていうと、POSIX準拠のために追加したんじゃないかね。 VistaのUnix互換機能はかなり強化されてるみたいだし。
Windows捨てろよ
API だけ UNIX 並みになっても…
Windowsには全く必要ない機能でも、移植性のためにわざわざ 用意してるものもあるよ。ファイバーとか。
ファイバー全く必要ない機能なのかよ。
マイクロスレッディングのようなことでもやらんかぎり・・・
Linuxカーネル2.4系でスレッドを特定のCPU上で実行させる(CPUを選択できる) 手段はありますか?
sched_[gs]etaffinity()でできない?
横レスだけど、外から affinity を変更するコマンドって無いの?
>>407 pidさえ判ればいいんだから、外部プロセスから幾らでもできるっしょ。
#勿論、権限があるとして。
まぁ、そうなんだけどね。サンクス。
それカーネルが動いてるCPU id(普通は#0?)に対して負荷掛けることでDoS成立するね。
>勿論、権限があるとして。
>>410 1. プログラムを実行出来ている時点で…
2. カーネルってシングルスレッドで動いてるの…
どっちで突っ込んで欲しい?
ところで、Linux の CPU 割り付けって排他的には出来ないんだね。
show_friend.pl?id=755479('・ω・`)
尻穴開けて待ってるから、早く突っ込んでくれないか。 アッー!
>>406 それカーネル2.5..以降じゃないか?
416 :
デフォルトの名無しさん :2007/05/04(金) 02:41:51
緊急浮上
417 :
デフォルトの名無しさん :2007/05/04(金) 11:58:15
これから仕事の関係でプログラムを学ぶんですが最初はどういう事から始めたらいいですか?
指示出した奴に聞け
次の職種のピックアップ。
マルチスレッド1度も使ったことがないんだが、どういう場合に使うものなの?
>>420 sleep等使う処理の場合主スレッドでやるとビジー状態になる為
そういう場合サブスレッドに任せて使えば主スレッドは生きる
マルチプロセスだとメモリリークがたまにあっても プロセスごと解放されてシステムピンチにならないけど マルチスレッドでメモリリークあるといつまでも解消されず 致命的になるケースがあるということが分かりました 回避する方法ってリークしないように作るしかないですか?
>>422 そのスレッドが終了すれば解放されますが。
>>422 そもそもリークさせてるプログラムを作ってる事自体間違ってる
Apacheが同じ道をたどっているので、 apr_pool系関数 (Apache Portable Runtime)を調べてみるよろし
>>420 本当にマルチスレッド化をするメリットを見出せないで使っている奴は、
色々と複雑で難度が高いものが好きで、あのアミダの様な処理シーケンスの
ギミックで遊びたいか、興行的wなプログラマーの誇示と道楽で使うもの。
サーカスのハイレベル空中ブランコや4個以上のお手玉などと一緒。
似非コンサル乙
>>420 おれは画像処理の高速化に使ってる(要HT、マルチコア)。
シングルプロセッサ環境より確実に速くなる。
負荷が高く並行処理可能で、マルチコア、マルチCPUなら、確かに効果はあるな。
また似非コンサルが片言知識で騒いでるなw
他のプログラムでパイプラインが埋まってたら、ミスキャッシュで遅くなりまくりだろう。
>他のプログラムでパイプラインが埋まってたら ほうほう?
相変わらず、ワナビーに厳しいスレだなw
彦○呂「見て〜! 思考のスパゲッティー状態や〜〜(間)ナマ茹でだし↓」
>>420 元々独立した処理が並列に複数同時に動くような状況では、
無理にシングルスレッドで組むよりもマルチスレッドの方が簡単になる。
例えばWebサーバのようなサーバアプリケーションでは、主スレッドで
クライアントからの接続を管理して、クライアントから要求が来たら
スレッドを作って処理させるのが基本。(1クライアント=1スレッド)
これで簡単にマルチクライアントのサーバが作れる。
これをシングルスレッドで同じことをやろうとすると、物凄く面倒。
>420 あと、どうしてもコード領域サイズが大きくとれない時、かな。 マルチスレッドにすることによって、コードサイズを節約できたりするンだよね。 組み込みとか、携帯でのテクニックだけど。
なんてーか、rubyでプログラミングしてるところに 「メモリブロックはこの形式で保存されるはずだから、もうちょっとヒット率を上げれば速くなる」とか 「Javaのバイトコードは〜に変換されるから、XXXとYYYは同じ」とか ユーザが立ち入っちゃいけない部分のお話をしてる風に見えるんだが
>>435 いまその程度でスレッド立てるなんて馬鹿のやることだよ
練習用にはいいかもしれんが
質問単発スレの話かと思った
Javaでもバイトコードとか、HotSpot/JITコンパイラのこと知らないと、 マルチスレッドプログラムではまることあるよ。
大抵、最初にスレッドを増やすことを覚えて、次に減らす努力を始めるね。 シングルスレッドのプログラムが書けるようになる。 ↓ 並行処理のためにスレッドを作ることを覚える。 ↓ 楽しくなってやたらとスレッドを作る。 ↓ スレッド切り替えがオーバヘッドになることを覚える。 ↓ 非同期処理を組み合わせてスレッド数を節約する努力を始める。 ↓ 最終的にスレッドプールに落ち着く。 で、現代的なOSはスレッドプールのディスパッチをカーネルランドでできるAPIを持つようになる、と。 epollとかIOCPとか。 コンピューティング能力を使い切るための並列処理はまた別。
>>436 >マルチスレッドにすることによって、コードサイズを節約できたりするンだよね。
理屈がよく分からないので詳しく説明してみてくれると大変ありがたい・・・
コードがシンプルになるという
>>435 の類の話かな。
>442 違う。コードはもの凄く複雑になる。その代わり、コードのサイズは節約できる。 ループで 0〜10, 0〜5 までの処理をマルチスレッドで行う場合、二つの関数を作り for文を置くとする。 { for( ; i < 10 ; ) { i++; } return; } { for( ; i < 5 ; ) { i++; } return; } これを、 { for( ; i < j ; ) { i++ } return; } として、j=5, と j= 10 で同じ関数をマルチスレッドで実行する。→ コードは約半分。 これを基幹ロジックに導入する。ある意味、職人技のひとつで、メンテナンス性はかなり悪い。 って話。お勧めじゃないけど、これもひとつの組み方という感じで。
>>443 それシングルスレッドで十分だしw
何か激しく勘違いしてると思う
>>438 マルチスレッドを使ったことが無い人に、どういうときにシングルスレッドよりも
便利なのか、一番分かりやすそうな例で簡単に説明しただけなのに、
そんなこと言われても困るんだが。
>>444 俺も443が何言ってるのか分からないな。
関数にして引数変えて呼び出すだけで済む話だよね。
>444 >445 いや、勘違いはしてない。 この考え方を基幹ロジックに入れるんだよ。例はわかりやすいように書いただけさ。 ま、こんな方法、知らない方が幸せだけどね。
>>447 その例がまったく分かりやすくない、というか誰も理解できないわけだが。
どう分かりやすいのか説明してほしい。
どんなに難しい話でもちゃんとついて行けるから、安心してください。
>>443 >として、j=5, と j= 10 で同じ関数をマルチスレッドで実行する。→ コードは約半分。
同じ関数をシングルスレッドで実行する。→やはりコードは約半分、となるでしょう?
マルチスレッド、シングルスレッドにかかわらず汎用関数化でコードを削減しているだけのように見える。
例えば漏れは昔 16bitのゲーム機用にMUAを書いたときに、一つのループに
・メールの表示
・メールの編集
・コード変換とSMTPサーバへの送信
・メールのサイズの計算
を多重化して動作モードで機能を切り替えたりしたことがあるけど、
単にそういう話ではないのですか?
>448 >この考え方を基幹ロジックに入れるんだよ。 と言うところかな。やはり、ポイントは。 そこが理解できてないから、汎用関数化してる、という言葉が出ちゃうんだろうな。 その文に言及しないで、例の話ばかりなのは、ついてこれてない事を自覚してみてください。 で、多重化して動作モード切替という話でも、だいたい近いので、そう考えて良いんじゃないかと思うよ。 ただ、コードサイズを小さくする事が目的、といううお話ですから。 エスパーで一文を追加すると、 それでコードサイズが小さくならんよ。って話にはならないわけ、なぜなら基幹ロジックに入れるわけだから。
難しいがマルチスレッドに興味ある初心者な俺にとっては有意義な話題だ
451 :
450 :2007/05/08(火) 23:01:48
人がいるうちに聞いとこう。 マルチスレッドでの排他制御はクリティカルセクション使うことが多いと思うんだけど。 セマフォでの排他制御ってのもできるんですか?
452 :
デフォルトの名無しさん :2007/05/08(火) 23:18:42
synchronized unko setunko(unko){s=unko}; synchronized unko getsemlock() {if s>0 s-=1 return おk else nullpo or wait}; synchronized unko releasesemlock() {s+=1 notifyforme}; とほぼ一緒じゃないの?
できるにきまってるだろ。
>>449 基幹ロジックってなによ?
マルチスレッドにすることによってコードサイズを小さくできるってのを
具体的に示してくれればいいだけだろ。
どういう原理化だけでもいい。
>454 >具体的に示してくれればいい 断る。暇じゃないんだ。
俺も基幹ロジックが何を指してるのか知りたい。ググっても
>>443 が言ってるのが何のことかさっぱりわかんね。
何かの分野での常識用語ですか?
なんだよただのあほか
自分で職人技とか言っちゃうのも痛い
分からないならこなくていいよ
マルチスレッドってI/Oレイテンシとかシーケンシャルで重い処理の 処理時間を隠蔽するために使うもので、乱用するもんじゃないとか 思ってたんだけど。俺の感覚が間違ってるのか。
マルチは使いこなせば最強馬だが 下手に使うと振り落とされる感じが強い 暴れ馬だな
コードサイズを小さくって、マルチスレッドとダイナミックリンクの話を混同してない? オブジェクト指向の再利用とも違うよね? マルチプロセッサとかで十分マルチスレッドを処理するハードが有れば有効だけど、2コア程度ならどうせ他のプログラムの処理も行ってるしシングルスレッドのほうが早くないか? HTが疑似2コアに見せてて、2コア用にマルチスレッドするとパイプラインが詰まって遅くなったりするし。 ゲームなんてシングルスレッドで十分だろ。 昔から描画間隔内にプログラム詰め込んで同期取って来たじゃん。 メールがマルチスレッドって嬉しいのか? どうせ表では送信中ですの砂時計出してるだろ? 職人技ワロタ。どこの自称職人?
全力で食いつきすぎ。もうちょっと要点を絞ろうぜ。最後の一行だけでいい。
>>462 2chブラウザがハングして長文消えた・・・orz
すんごいはしょって書くけど極論だね。スレッド化は用途次第。
スレッドにする対象が見極められるならシングルコアだろうと
ハイパースレッディングだろうとそれなりに役に立つ。
メールクライアントの話はスレッド化に適さない例をわざわざ
選んでいる。適切だとは言えないな。
>2コア程度ならどうせ他のプログラムの処理も行ってるしシングルスレッドのほうが早くないか? 甘いな。やってみれば判ることではあるが。
>>455 > 暇じゃない
自分の書いたマルチスレッドのコードで多数発生した不具合を始末している最中ですか?
>462 ダイナミックリンク笑った。 おまえ、組み込みってゲームしかやった事無いだろ。世間知らずだな。 >466 おまえは、仕事で使っているソースを、こんなところに張れるとでも思ってるのか? 秘守義務もしらない、アマチュアか。 メンテナンスしにくい -> わかりにくい -> わかりやすく書いて出せ。 おまえ、手間を考えてクレよ。ゆとり世代は想像力が無くて困る。
どういう原理かだけ書けよw 今度はゆとりかよ
どう見ても、一人だけ違う世界に居るようですが。
また空気の読めないキチガイか。
意味不明の例だけだすやつがあほ あれで意味を理解できるやつはいないだろ あれで説明になってると思ってるお前はゆとり以下だ
お花畑モード全開ですね。
おもしろい主張をする ↓ 説明を要求される ↓ 守秘義務を盾に拒否 いいね、この流れ
基幹ロジックって何か教えてくり
秘守義務(←何故か変換できない)ってどこの言葉なんだろうな。
秘守義務w
うお、普通に読み流してたが秘守かよ。
秘守義務はいいから基幹ロジックって何か教えてくり
だめだ。どうやっても
>>443 が理解できない。
1. 一つの関数をパラメータ変えて2回実行する。
2. 一つの関数をパラメータ変えて2つ並列に実行する。
という2者を比べて、2の方がコードが減るという謎の実行環境があるってことなのか。
普通に考えるとスレッド作成と、待ち合わせの分2の方がコードが増えると思うが、
秘守義務で守られた基幹ロジックでは違うんだろう。
> 暇じゃない 典型的な負け犬の捨て台詞ワロス まぁ簡単に逃げられるのは2chのいいところだな。
だから基幹ロジックって何か教えてくりよ。別に本人じゃなくても 知ってる人なら誰でもいいから
応答速度か計算処理量を重視するかで変わってくるんでないの? 互いに干渉のほとんどないようなのだと楽にスケールできるタイプのもあれば、 同期によって落ちやすくなるのもあるしさ。 非メモリ空間への読み書きみたいなのが発生すればちっとは変わるの? そもそもその辺はosがカバーしてるのでしょうか。
>>460 ちゃんとやると結構多くの種類の応用で性能面から多用することになるよ。
例えば沢山のイメージファイルのサムネイル作成やりサイズ処理等は
マルチスレッド化しないと遅くて話にならない。
シングルコアの場合でもIO待ちの間にかなりの計算ができるし、
マルチコアならさらに差が出てくる。
んでスループットを上げるという観点からみると、SMTやコアの数とI/O待ち時間を
考慮した適当な数のスレッドプーリングで実装する。
( IOCP が使えれば IOCP でも良いけど)
スループットより個々の処理のレスポンスを上げたい場合は、
非効率になることを承知の上でそれを超える数のスレッドを容赦なく使う。
(この場合メモリもいっぱい載せてもらう)
UI 側処理を継続させるために UI スレッドとワーカスレッドを分離するってのは
クライアントアプリではほぼ必須の処理だけど、これはなんというか奥深さがなくて、
ここで語るほどの技法や信仰もないように思う。
>>482 >同期によって落ちやすくなるのもあるしさ。
レースコンディションや計算時の依存関係が沢山あって上手に多重度を上げるのが
難しい処理ってのはあると思うけど、落ちやすくなるってのはPGの質が悪いだけのような気がする。
たぶん自称「職人」を使わなければOK
基幹ロジックワラタ
> これはなんというか奥深さがなくて、 で、で、で、でた〜〜〜〜〜〜〜〜〜〜〜〜!! 「奥が深い」 でた〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜!!!
We are the 基幹ロジック. You will be assimilated. Resistance is futile
modern multithreadingって洋書の邦訳ってありましたっけ? これ教科書的に使えて初心者にお薦めのような気がするのですが
つか今どきこんなしょうもねーデラワロス基幹ロジックって使ってる奴いるの? ライブラリ買ってくるかICCで済ませる方がプギャーとか言われなくて済みそう
マルチスレッド 基幹ロジック でぐぐってもこのスレが最初にヒットするんだが…
基幹ロジックとはなんなのだろう??
>>490 基幹ロジックの意味を知ってるならぜひとも教えて
×基幹(きかん)ロジック ○基幹(もとのり)ロジック
今時基幹ロジック使ってないやついるんか? MoFのサイトに載ってるよ
- ついて行けてますから、説明してください。 - ついて来れてないじゃん。んなヤツに説明すんのは時間の無駄。 - 「うきききーーーーっ」 と、ファビョーン - つまんね <- いま、ここ。
そもそも最初の「わかりやすい例」とかいうもの自体、誰一人わからないわけだが。 おそらく本人も理解していないだろう。 最初からおかしな奴だとは思っていたが、こういう話でハッタリやデタラメが通じると 思ってるんならそうとうお目出たいぞ・・・
>>493 基幹ロジック MoF でググッても分かりませんでした。
何のことか教えて欲しいです。
>>466 晒せないない公開していいソースを別に作って出せばいい
最後まで付き合えないなら最初から黙ってろ
気違いと厨がマルチスレッドしてるスレはここですか?
- ついて行けてますから、説明してください。 - ついて来れてないじゃん。んなヤツに説明すんのは時間の無駄。 - 「うきききーーーーっ」 と、ファビョーン - つまんね - 「うきききーーーーっ」 と、またまた、ファビョーン - つまんね <- また、ここ。
以降、気違いはスルーで
DualCoreが増えて、マルチスレッドがブームになり、デッドロックが流行語大賞になる予感。
以降、デッドロックはスルーで
デッドロク
秘守義務はさすがに要求されたことは無いな。契約時の語句の間違いは致命的だ(w 沢山のイメージファイルのサムネイル作成やりサイズ処理等でMS化してしまうとCPUを占有してしまうので、マルチユーザを前提とした環境では向いてないな。 レン鯖とか多人数で共用してる鯖だと迷惑。
>>505 すまん、一つだけ突っ込ませてくれ。
>MS化
マイクロソフト化だろ? エクスプローラのサムネイル表示の遅さを指摘しているものと思われ。
きっとモビルスーツ化のことだろう。
maruti sureddo
510 :
デフォルトの名無しさん :2007/05/13(日) 19:54:08
スレッドセーフかつ高速なスレッディングプログラミングをライティングするには どういうブックをリーディングすればいいのでしょうか。
マルチスレッドに関しては、入門書以上のものは見たことないな。
理論ばっかだね。 実際の実装に対するプログラミング手法の解説って見た事無い。
”マルチスレッドプログラミング 入門”も ”オブジェクト指向プログラミング 入門”って感じする
>>510 スレッドセーフって、共有エリアへのアクセスの排他制御とか、
スタティック変数で値を保持する非リエントラントな関数コールの
ラップ(かぶり)抑止などか?
無闇にやると、関数にしろメモリにしろ整合取れない -> スレッディング以前の問題 整合を気にしつつ穏当に実装 -> 遅くて洒落にならん どうすりゃいいのよ このままだと、パーティクル処理とかメインに絡まないサブスレッドしか走らせられない。 何が何でも意地でもメインスレッドをマルチ処理しなけりゃメンツに関わる
コード領域をどうしても小さくしたい場合に使うって書いただろ。 何が何でも、っておまえはやりたい事はなんなんだ?
ちょw 多重起動防止外しただけじゃねーか。
どこが画期的なのか全然分からない。
多重起動防止を外したからデュアルコアを両方とも使えるようになっただけにしか見えないのに、 さも凄いことのように記事を書いていることに衝撃を受けた。
>>519 自分のプロダクトをデュアルコア対応にする最速の方法だぞ。
画期的すぎる。しかもこの方法は4コアでも8コアでも通用する。
ただし、ユーザーに見捨てられる。
洒落や冗談でなく、1ジョブ1プロセス型のアプリケーションなら一番手っ取り早いね。 2coreXeon*2の環境でテストしたら、4プロセスまでは処理速度がリニアに向上したケースもある。
>>521 その目的に対しては有効な手法だとは認めるが、
期待してリンク見たのに、感想としては、正直がっかりだ。
そのうちRPGかなんかで、別プロセスでアイテム一覧プログラムを動かして「DualCore最適化」と言い張ったりして。
そんなことよりマルチスレッド化してコード領域が小さくなる件についてkwsk
>>525 自分で複数タスクを同時処理するためのフレームワークのコード書くより、
OSが提供するのを利用したら自分の書くコードが減るからじゃないの?
>>526 え、そういうことだったの?
つまり自分で(シングルスレッドの)イベント駆動型マルチ
タスク処理書くより、OSのマルチスレッドAPI使ったほうが
コードが簡潔になって小さくなるってことだったのか。
まあそりゃ、確かにそういう状況もあるな。
>>527 ごめん、過去レス見ずに書いた。
言い出した人は、マルチスレッドとは関係のないコードサイズ縮小の一手法しか挙げてないね。
その上、基幹ロジックって言ってるから、それを外部設計にも応用しましたってことだと思う。PG泣かせのバカSEの典型かも。
どういう意図で言ったかは本人に聞くしかないと思う。
>マルチスレッドとは関係のないコードサイズ縮小の一手法 これがわからん…。上のほうでサブルーチン化することとの 比較みたいなのあるけど、サブルーチン化する以上にマルチ スレッド化で小さくなるケースなんてあるの?
上のサブルーチンの例はどうでもいいなら、
>>526 とか、
煩雑な処理をマルチスレッド化したらコードがシンプルになる例ならよくあるでしょ。
>サブルーチン化する以上に
条件によって千差万別なのに、比較しても意味ないよ。
上のサブルーチンの例はただの勘違いだと思うのでスルーしていいと思う。
まあそんなのは当たり前の話で、 ことさら携帯などの環境ではとか 特殊な話はよくわからんな。 メンテナンス性を非常におとすから、 あまりお勧めできない話らしいし。 ってわけで昔の話は無視しとけ。
こいつは笑うしかない
まあそれは、あれだけど リアルタイムのゲームでマルチスレッド化して恩恵得られるのってどこらへん?
マルチスレッド自体が重要ってんじゃなくて、 単にマシン資源をできるだけ活用するってとこだわな。 ※もちろんそれをするためにはマルチスレッドが必要だけど そういう意味でスペックを想定できないPCでは難しいよね。
ロックフリー
〜の処理を「2コア目に回す」なんてPCでできるのかね? スレッドにはできるだろうが、そのスレッドがCore1で走るか Core2で走るかはOSのみぞ知るってところじゃないの?
Win32ならSetThreadAffinityMask()で指定できる
Solaris ならどのスレッドをどのコアで動かすか細かく指定出来るよ。 グルーピングで指定も出来るし、スレッド毎に指定する事も出来る。 プロセスの外からスレッドの割り付けを変更する事ももちろん可能。
rdtsc rdtscp
M:Nが絶滅するらしいね
MN(LW)P
プログラマやってると、ちょい前のレスの人の様にコンパイラみたくピーピー鳴く生き物になんの?
よそで聞け
547 :
デフォルトの名無しさん :2007/05/19(土) 18:16:59
ここでjavaのthreadの話していい?
いいよ
549 :
デフォルトの名無しさん :2007/05/19(土) 19:32:56
javaのthreadはsunが作ったから世界一なのに、 なんで他の言語で無様な模倣品を作り続けるの? ぜんぶjavaになってしまえばいいのに。 以上です。
ビル・ゲイツ 「 SUNの Javaランタイムは 二度と見たくない」
Bill が作った言語のランタイムは見てみたいw
N-BASICとかがそうだろ。当時としてはよくできてるんじゃないかな。
アァスマン、ソースが見たいって事ね。
大丈夫、当時のBASICは皆アセンブラで書かれていたから 逆アセンブルすればソースになる。
そうなのけ? メモリが 256KB で十分な時代ならそんなもんか。
256KBなんて贅沢な。 16KBを必死にやりくりしてた頃が懐かしい。
GVRAM領域にコード置いたり。
当時、メモリ空間は、64KBだ。 RAMが64KBなんて超高級機だ。
ROM8K RAM8K
>>553 当時の人はOPコード暗記してるので、読むだけならバイナリのまま読んでた。
だから、そのままで読んで問題なし。
最初に触ったのは富士通のFM-7だったかな N88BASICだった あれってメモリいくつだったんだ?
FM-7がN88BASICのわけねぇっしょw
こらこら Nxx-BASICはNECだ。
MS-DOS版N88日本語BASIC(86)コンパイラー 長い名前だったw
32KB
FM-8は64kBフル実装(4kBはアクセスできない)だったけど FM-7は32kBだったの?
8ビットCPUでマルチスレッドなんかできるの?
FM-7の方が後発なのに削るなんてことあるかいな。 尤も、6809*2の変態構成だった記憶はあるが。
6809 と OS-9 はすばらしかった。 マルチスレッドではないが、メモリ保護つきマルチプロセスは実現してた。
7は8のほぼアッパーコンパチ。バブルメモリとか普及しなかったものは削られたけど。
>>569 当時はUnix(SystemVと4.2BSDの頃?)にもマルチスレッドってなかったような。
8ビットマシンでメモリ保護ついてる機種なんかあったんだ。
68000なんて公証16ビット中身32ビットなんて変態CPUもあったなぁ 商売損してるよなぁ
日本ではz80系がメジャーだと思っていたのに、こんなに6809系マンセーな奴がいたのか。
2MHz とか 3MHz とかって今考えると泣けて来るな。 クロックが 100MHz を超えた時は感動したもんだったが。
おまえらマルチスレッドなんてほぼない時代の話すんなよ
マルチスレッドは甘え。
>>567 16bitだが98DOSでは常駐という手法で
マルチスレッドもどきが出来た記憶。
>>580 DOSの常駐(TSR)は、コオペラティブマルチタスク。マルチスレッドではない。
>>581 インターバルタイマ割り込みでステートマシンうごかせば…
でもじゃねーか
マルチタスクとマルチプロセスとマルチスレッドの違いが分かりません。
マルチタスクは別々のプロセスが同時に、、、 ここで言うマルチプロセスはプロセス(メモリ)空間が別々な複数の同じプロセス、という意味かな マルチスレッドはそれぞれのスレッドのプロセス(メモリ)空間は同じ
割り込みで別処理するだけなら、8bitCPUでもできる罠。
仮想メモリ空間が作れない処理系では、 マルチスレッドはおろかマルチプロセスもできないってことですか。
リソースの共有の程度の話だから そこまで厳密に考えなくていいんじゃないの
>>586 つ[Concurrent CP/M-86]
マルチタスク 複数のアプリケーション(タスク)が平行して動く。 1タスクは1プロセスとは限らない。 マルチプロセス 複数のプロセスが平行して動く。1プロセスが1タスク とは限らない。 マルチスレッド 複数のスレッドが平行して動く。1プロセス=最低でも 1スレッド。
× 平行 ○ 並行
閉口
592 :
デフォルトの名無しさん :2007/05/24(木) 20:57:58
_beginthreadexでワーカスレッドを起動させたあと ワーカスレッドがreturnする前に親スレッドでCloseHandleしても 問題ないでしょうか? 実際のところ_beginthreadexの直後でCloseHandleしても ワーカスレッドは動き続けているようなのですが、 リソースリークが気がかりなのです。
ハンドルが必要がなければ、_beginthreadexした直後に CloseHandleするもんだよ。リークなんかしない。
ハンドルの意味わかってねーなー
>>594 Windowsのスレッドオブジェクトは、
・そのスレッドを示すハンドルがすべてクローズされ、かつ
・スレッドの実行が終了している
ときに消滅する。CloseHandle()をいつ呼んでも実行中のスレッドが死
んだりすることはない。
597 :
594 :2007/05/25(金) 01:41:44
>>595 分かっていないからお聞きしている訳で…
598 :
594 :2007/05/25(金) 01:54:52
>>596 ありがとうございます。そのような情報はどこ(MSDとか書籍)に記述してあるのでしょうか??
たとえば私が
>>594 であげたリンクによると
>「最初にスレッドを終了」し、次にそのスレッドのすべてのハンドルを閉じなければなりません。
括弧は引用者(筆者)による強調。
最初にスレッドを終了するという点をわざわざドキュメントとして記述してあるということは、
スレッドの終了を先にしなければならないといけないと思ったのですが?
差し支えなければもう一度教えていただけないでしょうか?
>>598 ハンドルを閉じてからスレッドを終了してはならない、とは書いてない
だろう?
600 :
594 :2007/05/25(金) 02:18:35
>>599 はい、確かにその点については記述されておりません。
私の勘違いで時間を無駄にさせてしまい。すみませんでした。
教えてくださり、ありがとうございました。
変数を減らすなんていう下らない事の為に、
論理的に誤った記述を行うのは如何なものか、と。
>>592 >>594 問題は無いらしい。
MSは明言していない。
603 :
デフォルトの名無しさん :2007/05/25(金) 10:24:12
592です。
みなさまご回答ありがとうございます。
おかげさまでたいへんすっきりしました。
>>594 さん
私が寝てる間に疑問に思っていたことを
投げかけてくれてありがとうございます。
>>602 勝手な解釈の部位は、誰にも宛てていない:b
>実行中にハンドルをCloseしていいことはMSDNライブラリにも書いてある。
明言している箇所を抜き出しなさい。
探すのが面倒だからね。
この糞鳥餅は目が見えないらしい
日本語で噛みくだいて訳して欲しいんだろ 厨にはよくある事
gcc4.2のOpenMPコードヘボヘボでだめじゃんw
マルチスレッドが無ければ世の中のデスマの35%は無くなる。
無くならない。 なぜなら、別の原因でデスマるから。
コードの書けないSEがいなければ、デスマの80%は無くなる。
>>610 我が国の中傷システム開発会社の特徴が、どこでも入社半年でSE教育を強制され
プログラマを見下ろす事を刷り込まれる。
やがて殿様状態になった自分に気が付き、右往左往して何人も辞めてゆく・・・
そういうのはマ板でやってくれないか
この To remove 以下は前の文章の補足として読まなければならない ような希ガス
614 :
デフォルトの名無しさん :2007/06/01(金) 21:45:24
あるタスクをスレッドに分解する手法って何がある?
どんなタスク?
____ / \ / ─ ─\ / (●) (●) \ 「テラワロスwwwwwwwうぇうぇwwww」・・・・と | (_。人。_) | ________ \ ` ⌒´ ,/ .| | | ノ \ | | | /´ カタ. | | | | l カタ | | | ヽ -一ー_~、⌒)^),-、 | |_________| ヽ ____,ノγ⌒ヽ)ニニ- ̄ | | | ____
機能分割とか領域分割とかってthreadに関係あるの?
gccもopenmpに対応したっていうのに、いまさらpthreadを学ぶやつってなんなの?
posixの意味はわかってるか?
RHEL 5.0 と RHEL 4.5でシステムの管理できるプロセス・スレッド数ってどうなった? あと、1プロセスが管理できるプロセス数とか。 こういう情報ってなかなかまとめて公開されてないんだよね。
>>622 そういうのってディストリの話じゃなくてカーネルの制限だろ
てことでカーネルのソース読めばよろし
どこを読めば良いのかヒントぴりーざ
Linux板で聞けば誰か知ってるんじゃね?
ゲ製でみたのは内緒なw
Linuxでマルチプロセスを実現したい場合、 メインプロセスでfork()を行う。子プロセス側でexec()系の関数使う。 が一般的なんでしょうか?windows見たいにCreateProcess()があって、 成功失敗を戻り値で判断できるような関数ってLinuxだと用意されていない?
Linuxそのものが失敗だから用意するもない
>>627 system()でバックグラウンド起動すればほぼ同じことができる。
popen()とシェルの機能を使えば更に起動したプロセスのIDも取得できなくはない。
はい fork と同時に pipe で繋いでプロセス間通信します
しかし、どうも forkって嫌なんだが、そういうこたぁないのか?
ないよ
嫌というのは? 重いから?
fork()は言語の仕様として受け入れられないレベルの機能だから。
Cの言語仕様にはマルチプロセスなんて概念ないからねぇ。
>>634 fork() と C の言語仕様には何の相関もありませんが。
K&RがUnix作ったすぐ後にcを作った。 受け入れられないのはたぶん>634だけ。
プロセスを複製するのはちょっとキモいな if(fork()==0){ //子 }else{ //親 } 最初見たときは「何じゃこりゃ」と思った記憶がある CreateProcessとかで明示的に作成する方が わかりやすいといえばわかりやすい
フォークで複製するのとプロセスを生成するのではまったく意味が違う。
フォークって書くとなんか別のモンみたいだな ナイフと一緒に使うアレとか
>>627 単にマルチプロセスしたいならexec()系は不要。
exec()系の目的は他の実行イメージへの置き換え、
もしくは自身と同じ実行イメージに置き換えての再起動。
Windowsではプロセスの分岐と実行イメージの
置き換えを分割できないので、不便な事も多い。
fork()とexec()系を組み合わせた挙動が欲しいのならば、
msvcrtのspawn()系のような関数を実装すればいい。
fork() = フォーク spawn() = スプーン
hash() = 箸
処理を二股に分岐するからfork()なんだが。
へえ。forkって分岐するっていう自動詞でもあるんだ。 The road forks near the river. 道は川のそばで分かれている. また一歩世界征服の野望に近づいたよ。
どうすれば、中学英語で野望に近づくのかと
世界征服セーラー服
>>648 大丈夫、エラーの時には分岐してないから。
あ、もしかして、if分岐と勘違いしている?
深夜に骨肉の争いがあったらしいな
深夜って何時から何時までよ
骨肉の争いって何よ?
>>649 あー「処理」ってのが flow じゃなくて process なのね。勘違いしてた。
getpid getppid は出来るのに 子プロセスIDの取得だけなんで面倒なのか
forkの返り血
産んだ子供の面倒ぐらい自分で見ろよ ってことでね?
リアルでこえーよ
子は1人とは限らないからなー
「ゾンビプロセス」よりは 「水子プロセス」の方がしっくりくる。
そういや、プロセスの水子供養とか、冗談でやってた奴いたな。
今まであの手この手で何人殺したかわからんなマジで
通報しますた
便器に捨てた精子は数知れず
通報…されそうです><
マニュアルページにもwait(2)で子供の骨を拾えと書いてあるから、 骨を拾ってもらえないうちはゾンビでいいんでない?
1982年にわたし待つわとあみんは歌ったが あれは子供の骨を拾うためだったのか こわいこわい
>>666 たとえあなたがふりむいてくれなくても……
子プロセスの肥大化に気づかないほど親プロセスがリソース食ってたんだろうな
もともと肥大化してたピザ子プロセスだったんじゃね?
いや、そう言ってるんじゃないか?
いくらピザデブでも妊娠の初期症状一切見逃したのか? つか生理止まっても気づかねぇとかどうよ
いや気がつかなかったのが両親と教師なのは書いてるけど 本人は知ってたのでは
うちの姉と母はいつだよねーとか言ってるぞ目の前で
だからうちの姉とと母は「いつだよねー」とか言ってるんだよ俺のも目の前でな
十月十日?
50レスもスレ違いが続いたのか
あーマルチスレッドとマルチプロセスだからスレ違いなのか
NPTスレッドって何よ?Linuxの普通のposix threadととは違うもの?
ググレカス
ククレカレー
ククレカレーって、もうなくね? みかけないよ?
>>685 Amazon で売ってるよ。ククレはクックレスってホントかな…
アマゾンって・・・ 日本ではもう売ってないの?
グローバル変数ってもう安心して使えないのですか? たとえばスレッドの終了フラグみたいな場合にグローバル 変数を使うのは危険なんでしょうか? win32とlinuxを想定。
↑C言語を想定
pthreadのmutexやOSの排他機構を正しく使えばOK。 して久々にvolatile再来!?
つまり排他してないフラグで以下のようなスレッド while(!sinu) { ... } を実行していて、他のスレッドで sinu=true をしても、回りつづけてしまうことがあるんでしょうか? 最適化関連は捨象するとして。
>マルチプロセッサ環境下で、あるプロセッサ上のスレッドが更新した変数の値が、別のスレッドで読めるかわからない とのことなので、693は回りつづけることがあるということですね。 ところでpthread_mutex_lockやEnterCriticalSectionて その内部コードのメモリアクセスに対して、実メモリにアクセスすることを 保証してくれるんですか?
>とのことなので、693は回りつづけることがあるということですね。 それとも、値をセットした直後は回るかもしれないが、無限に 回ることはありえないってことなのでしょうか?
日本語でOK
698 :
デフォルトの名無しさん :2007/06/12(火) 22:58:29
これがわからないとこまるのでage
(゚д゚)ハァ? 君の質問の答えはさっきのHPに全て書いてあるよ。 読んで解らないのなら基礎ができてないわけだから、pthreadの参考書買って一から勉強した方がいい。 少なくともスレッドプログラミングにおいては、基礎がしっかり理解できていないとまともなものは作れない。
>最適化関連は捨象するとして ってなんで捨象しちゃうんだよプンプン
701 :
デフォルトの名無しさん :2007/06/12(火) 23:12:53
>>699 書いてあるならここに書いて。
できないなら言い訳書いて。
大物のヨカン
確かに大物っぽいなw
無能に限って態度がでかいなぁ
彼は切羽詰ってキレる寸前なんだよ
708 :
デフォルトの名無しさん :2007/06/12(火) 23:59:44
反応早すぎワロタ
>>693 排他していない限り環境依存であり断定できない
>>696 排他していない限り環境依存であり断定できない
とりあえず何か問題出るようならタマに聞いてくれ
>>708 お前の上げた例が単純だから
この例に限っては無問題でいいけどな。
ということを忘れるな。
C言語 スレッドあたりで検索すれば レースコンディションの話なんて腐るほど出てくるだろうに・・
まあなんだ、普通はこれをレースコンディションの問題とは言わない
>>693 >を実行していて、他のスレッドで
>sinu=true
>をしても、回りつづけてしまうことがあるんでしょうか?
大丈夫、電源落とせば確実に止まる。
>最適化関連は捨象するとして。
「捨象」って意味わかっている? つーか、sinuの型も書かないで何を論じろと?
>sinuの型も書かないで何を論じろと? またか。 書いてること以外情報を補えないコンピュータ脳の持ち主。 trueって近くに書いてるのにbool型だと推測できないの?
そんな型はありません
>>716 最適化を捨象しちゃう香具師が、何を想定しているかなんて推測不可能だ。
それに、Cならtrueがbool型である保証がないのでなんでもありだしね。
#C++なら演算子オーバロードでやっぱりなんでもありだけど。
こんなところに書く例でオーバーロードとか別に深読みする必要もないし。 C言語だからboolが無いってのに突っ込むのも今更。
本人必死過ぎ
704のレスをみて180あたりから目を通してみたのですが、volatile論争はともかく mutexロック自身のコストはそんなに高いものなんでしょうか? 多数のスレッドがmutexロックを掛けたリソースにアクセスする場合のロック取得の為の待ち時間が発生するのは理解 できるのですが、仮定として1スレッドしか無い場合(つまり他のスレッドとのロック取り合戦が発生しない場合)の コストがどんなものなのか知りたいです。
裏でビデオのエンコードをやってる環境なので 相当イイカゲンなテストになっちゃったんだけど…。 Win32のCriticalSectionとMutexについて、 取得と開放のループをシングルスレッドで100万回ずつ回してみた。 CriticalSectionの 32ms に対して、Mutexは 960ms。 思ってたより差があるなぁ。
mutexは普通カーネルモードへの遷移が要るからなのかな?
およそ1マイクロ秒か、確かにかなり重いな…
linuxはCriticalSection相当は無いの? もしくはlinuxのmutex はすごく軽いとか。
いまLinuxで100満開mutexロック〜解放やってみたけど0.178秒だった(boost::thread使った) ちなみにAthron2400なマシンでKernel2.6(NPTL)
721で言っているmutexってのは Win32ではCriticalSectionにあたる機構だし、 721の疑問に対するWin32環境での答えは、 CriticalSectionの100万回32msのほうだね。 (報告上げといて今更だけど…すまん)
Win32のCRITICAL_SECTIONは(内部でどう工夫してるかは知らないが) (PC-Unix系の)pthread_mutexよりかなり速いという話は聞いたことがある。 スピンロックをできるだけ高速で取得する工夫をしていて、 もしかしたら関数呼び出しを抑えてるのかも。 当然、どちらもロックをダイレクトに獲得できるときはカーネルに移行しないはずだけど。
で、ロックのコストだが、処理によっては確かに気になる場合もある。 例えば、少し前に別スレで「VC++のfputcが遅い」という話があった。 これは、一文字出力する度にロックしているため。 (最近のVC++はMTライブラリしか提供していない) もちろん、こんなのは工夫次第でなんとでもなるのだが 知らないと悩むことにもなりかねない。
Win32のクリティカルセクションは競合が発生してない限り カーネルに遷移しないから高速なんじゃなかったっけ スピンロックか何かしてたような
僕にはついていけない・・
速さなんて相対的なもんだ 何かとの比較なしに語ったところで意味が無い 関数呼び出しは、速いか? みたいなもんだな 関数呼び出しのオーバーヘッドが気になるようなケースもあるからinline関数の ようなものが存在する ロックもしかりだよ
Win32のクリティカルセクションが速いのは、InterlockedExchangePointerを 使っているからだよ。 これは、アトミックな処理で値を交換するAPI。もちろんユーザモードのまま。
>>728 mutex objectはhandleを用いる。
コレに触れる事は、kernel objectを操作する事を意味する。
>>732 だからCRITICAL_SECTIONとMutexやpthread_mutex_tとの比較の話だろ?
もしかして、あなたには見えないの?
>>734 え、毎回カーネルに行っちゃうの?
「スピンロックが取れないときだけ」カーネルに移行すると思ってたけど。
(当然、スピンロックはlock+cmpxchg+pauseを使って)
だったら、差がついても仕方ないとは思うけど。
カーネルで作成するものだとしても、ユーザー空間に必要な部分だけをマップして
読み取り(必要なら読み書き)可能にしてるものって、結構あるでしょ?時刻とか。
いや、ソース見ないで想像で書いてるだけだから、違ったらごめんね。
100万回で1秒が遅いって、オマエら普段どーいうプログラム作ってる んだよ。1秒間に何回同期してるのか気になる。1万回超えたら特殊領域じゃね? それともI/Oが0.001秒かかるところが同期によって0.001001秒に なったから遅いとか言ってるんじゃねーだろーな。
わずか1000回で1msもかかる処理は、出来れば呼び出しを減らしたいと俺は思うね。
で、発端の
>>693 みたいな、
メモリの参照するだけなのに1ms/1000回もの時間をとられちゃかなわないから
なんとかvolatileだけで済ませないかという話も出てくるわけだな。
まあ実際には(スレッド間のロックは)もっとずっと短時間だからいいけど。
>>737 getc()/putc()の類は、古典的なマクロ版ではほぼ単純なポインタ操作だけ・
マルチスレッド対応版は、これに関数呼び出しやロック等、もろもろの
オーバーヘッドが加わる。
この場合、ロックだけがオーバーヘッドじゃないわけだが、
0.001秒が0.001001秒なんてモンじゃない、確実に数倍以上は違うよ。
VS2003以前の環境を持っているなら、計測してみればよい。
>>736 > え、毎回カーネルに行っちゃうの?
mutex は他プロセス(not スレッド)との同期も取るからな。
確かにCygwinのfputcは無駄に遅い。
>>741 おいおい、pthreadのmutexだよ?
どう考えても話の流れからしてWindowsのMutexの事じゃないか
745 :
デフォルトの名無しさん :2007/06/13(水) 23:55:17
初心者ですみませんが教えてください。 gethostbyname( ) のようなスレッドセーフでないライブラリ関数にはなにがあるのか、 リストみたいなものはあるんでしょうか? また自身で作成する関数は別として、上の様な関数をマルチスレッドで使っても 気にしなくてすむ良い方法はないでしょうか? セマフォを掛けるにしても、その関数が内部でstatic変数を使用しているか分からないとダメですよね。 よろしくお願いします。 m(_ _)m
747 :
746 :2007/06/14(木) 00:00:19
mutexと書かれるとLinux Mutexと書かれるとWin32を前提として 話を読み進めてしまう自分がいることに気が付いた。 チラ裏
俺も基本的には同じよん
>>748 今後はそれで行こう
次スレのテンプレに入れといて。
「別途断りの無い場合は mutex は pthread、Mutex は Windows と見なします」
>>734 の内容は、728ではなく、
>>723 への書込みだと訂正しておく。
#3と8は見た目が似ているから、打ち間違えやすい(ぉ
スレ違いかもしれんけど デュアルコアのCPUの場合 子プロセスや孫プロセスをたくさん 起動した場合、ちゃんとコアは 振り分けられるの? それとも片方のコアだけ使うの?
>>752 まともなスケジューラを持った OS ならきちんと振り分けられる。
大抵の OS なら自分で振り分ける事も可能な筈だ。
もちろん片方のコアだけを使うようにも設定出来る。
それはよかった
このスレは今後重要になる。 今のプログラムをマルチスレッドにコンパイルするだけでなく、 プログラムをマルチスレッドに書き換えるソフトってないんかな・・・ ええ、マルチスレッドのことはあまり知りませんとも。
>>756 既存プログラムの実行形態を変更するって事?
(基本的に)無理。
>>756 ベクトルプロセッサとかで
for (int i = 0; i < N; ++i) {
array[i] = func(i);
}
みたいな時に i 毎に振り分ける処理系はあったと記憶してる。
だけど func() が array[] その他の i について
依存してないことを検出するか手動で指定する必要がある。
…二十年位前の知識だから今はもっと進んでるかもだけど。
効率を求めればそういうアルゴリズムを駆使することになるし
設計から考えないといけないので自動化のうま味はあまり無いと思う。
最近その辺の動的自動化の研究を理研とかNECとか日立辺りが組んでやろうぜっていう話が
あるらしいけどな。
>>758-759 >756はそういう話なの?
>今のプログラムをマルチスレッドにコンパイルするだけでなく、
>プログラムをマルチスレッドに書き換えるソフトってないんかな・・・
「コンパイル」じゃなく「書き換える」そうなのだけど。
JIT っぽいのが研究されてる希ガス
Javaにつかりすぎてガベコレのない言語では書きたくなくなった俺が 通りますよ。 Javaはスレッド使いやすくていいな。C#はまだ勉強中。
GC のある言語はスケールし辛いのが難点だね。 Java はかなり頑張ってると思うけど。
涼宮ハルヒも分裂ぎみだな ああいうの書いてて恥ずかしくないんかな
javaや.netの中間言語形式から 並列成分を抜き出して以下略とかいうのはないかな やっぱ開発者がアノテーションしないと無理か
.netってやったこと無いが、なぜバイトコード形式のアーキテクチャーにしたんだ。 Windows以外のプラットフォームにも移植する計画があったのだろうか? 公式ではWindows以外のかんきょ 書いててふとスレ違いだと気づいた。
>>767 当時は、次の 10 年も x86 が支配するとは確定してなかったからね。
実際はサーバからデスクトップ、モバイルまで x86 で大体いいやという
世界になりつつあるけど。バイトコードならどの CPU が支配的になっても
良いし、セグメント毎に違う CPU が勝ち残っても問題が少ない。
それと、同じ x86 でも CPU 毎にキャッシュのサイズやら何やらが変わる
から、それぞれに JIT で後付けの最適化が出来るのは嬉しいでしょう。
あと、Windows 以外は考えてないと思うな。昔で言う NT 系みたいな、
別の Windows の登場は考えていたかもしれないけど。
X64やらIA64やらX86やらにネイティブに対応するにはどうする? ってだけで現実に意味あるだろう。
あーネイティブってのは、えーと、んんんややこしいな、なんか誤解を生みそうだ…
このスレって相変わらずスレ違い発言多いなぁ
pthreadでマルチスレってる人たちに伺いたいのだが、 デバッグのツールとかでオススメはない?
ここらへんでダンゴさんのシメのレスが欲しいところだ
団子チューさーん
777 :
デフォルトの名無しさん :2007/06/28(木) 21:42:28
LOOP処理を自動で分解してくれるjavaのライブラリないかね?
>>734 遅レスだが、とりあえず、バル、バル、バルル ...と効果音を入れておこう。
SoftwareTransactionMemoryについて詳しいサイトないかのう・・・
なぜハンドルがあるのにサドルやペダルはないんでんしか?
昔はあったんだけど技術の進歩とともに廃れたいいった 例えると、人間が漕がなくても進む自転車ができたようなもの。
たとえ漕がずに済んでもサドルはいるべ すわれねーじゃんw
サドルがなくても坐れる自転車もできたようなもの。
そのうちハンドルもいらなくなるんじゃね?
> 香代 どこで売ってますか?
787 :
香代 :2007/06/28(木) 22:48:01
持ってますよ お譲りします?
香代より田代の方が良いです...
OpenMPはJavaでは使えないのでしょうか??
790 :
779 :2007/06/29(金) 20:22:32
フォォォォォォー
791 :
香代 :2007/06/29(金) 20:50:52
そんなん知らないもん
792 :
779 :2007/06/29(金) 22:37:28
どこぞのスレで
>サーバ落ちた。 SQL流すなよ
みたいなのを見たが、複雑なシステムだったりWEBがらみだったりして、
でかいSQLが来ることがありうるなら、オープンコボルなんかありじゃないかな。
SQLは前処理・後処理(トリガ。選択の余地無しで必ず掛かる)、カスタマイズが苦手。
その点コボルなら
クライアント⇔COBOL⇔DB
(CALLインターフェース)(CALLインターフェース)
で通常SQLの部分が柔軟性のあるプログラムになる。
更に、SQLでいうストアド呼び出し、逆ストアドみたいなこともできる
COBOL→C言語(CALL)、C言語→COBOL(関数)
オープンコボルだとJAVAも使えるらしい。
トランザクションは
http://jp.bea.com/e-docs/tuxedo/docs71j/html/rf3cbl2.htm みたいなのが検索したらヒットした。要はTPモニタの型を使ってカスタマイズするようなものか(TPモニタインターフェース)
SQLの手狭感がぬぐえない場合、そろそろCOBOLも見直されてもいいんじゃないかな。
どこの誤爆ですか
質問です。マルチスッドレの説明がしてある場面では必ずスレッドセーフうんぬんと いきなり話が始まりますが、その前提が説明されていることが少ないですよね。 スレッドセーフを意識しなければいけないのはオブジェクトのインスタンスがシングルトン な場合やインスタンスがスレッド間で共有されている場合だけですよね? 逆に言えばそうでない場合、シングルトンなオブジェクトもなく、スレッド毎にインスタンス を作成して並行に処理するだけなら不要ってことでいいでしょうか。 前提がきちんと書かれていないことが多いもので質問しました。
共有部分がまったくないならマルチプロセスと見分けが付かない
797 :
デフォルトの名無しさん :2007/06/30(土) 18:33:03
シングルトンなオブジェクトにハードウェアリソースを含めるならそうかもしれないね
↑意味不明w
800 :
795 :2007/06/30(土) 19:18:13
>>797 確かに。例えば一括印刷などの処理で対象処理が処理1〜5とか複数あった場合に
上から順番に流していくより、それぞれ単独スレッドで実行した方が昨今のマルチコア
環境を有効に使えるんではといった感じです。この場合処理間に横の関係はありません。
(間に別の帳票が挟まってしまうじゃないか!というのは本題ではないのでとりあえず
おいて置いてください)
もちろんファイルIOやDB書き込みなどのバッティングが無い処理でオブジェクト内で利用する
サードパーティ製等のオブジェクトがスレッドセーフかどうかは調べがついている、という前提です。
こうした場合、自作クラスではロックなどのスレッドセーフは考慮する必要はないのではないか?
というのが言いたいことでした。
複数ロックがあると獲得順番によってデッドロックが起こりうるが そのレベルの考慮は自前でやるとして?
それはスレッドセーフにするための考慮をしたうえで、 ロックなどを用いなくても大丈夫と判断したんじゃないのか? ロックなどを用いなくてもスレッドセーフである、というだけだろ。
「スレッドセーフを考慮」がいい味出してるな
>>795 人に質問をするときは、ちゃんと質問内容を整理してから書けよ・・・
Q1.
>>795 の云う「考慮」って一体どういう事?
自分の書くソースの中で排他処理を書くか・書かないか?ってこと?
それとももっと一般的な話?
Q2.
>>795 は一体何のためにスレッドを使いたいの?
>それぞれ単独スレッドで実行した方が昨今のマルチコア
>環境を有効に使えるんではといった感じです。
って事は、もしかしてただ単純に、
複数プロセッサを同時に動かして速くしたいだけなの?
スレッドを複数用意してアプリケーションの中で発生するタスクに対して リソースのようにして割り当てて使う方法ってなんか呼び方ありますか?
806 :
795 :2007/06/30(土) 22:19:41
>>804 すいませんです。。
> Q1.
>>795 の云う「考慮」って一体どういう事?
> 自分の書くソースの中で排他処理を書くか・書かないか?ってこと?
> それとももっと一般的な話?
両方になるかもです。自分の書くソースもそうですが、一般的にあるオブジェクトの
インスタンスを共有しない場合はロック処理は必要ないのでは?という疑問です。
なぜ疑問なのかというとロック処理が必要な条件が明記していない記述が多く、
ひょっとしたら言語によっては異なるインスタンスでもクラスが同一ならマルチスレッド下
ではインスタンスメンバ等が共有される(メモリ節約の都合上とか)仕様とかがあって
マルチスレッドではロックが前提とかあるのかな?と思いました。
> Q2.
>>795 は一体何のためにスレッドを使いたいの?
(中略)
> 複数プロセッサを同時に動かして速くしたいだけなの?
そうなります。バックグラウンドで処理とか処理中UIを操作させるためとか今の所
考えていません。直列で動かす必要のない処理を処理時間が短くなれば自分
的には充分です。
質問しといてあれなのですが、ちょっと今からパソコンが使えなくなるのでまた明日
見に来ます。すいません。
>ロック処理が必要な条件が明記していない記述が多く、 ほとんどは、共有リソースにアクセスする場合、とか少なくともそういう書き方してるように思うが。
「スレッド間で共有されないインスタンスは ロックせずに読み書きしても問題ないと思うのですが、 それでもロックが必要になるケースというのはあるのでしょうか?」 ずいぶん長ったらしく書いてくれたけど、つまりこういうことだろ?
本当に共有している部分がないならいらないだろ。
排他処理が不要というとこんなケースかな。 スレッドを生成する前に必要なデータを共有する変数にセット。 スレッド生成、処理開始。この間共有する変数は生成したスレッドからだけアクセス。 処理終了とJoin。その後共有する変数から結果を取得。 実際はスレッドの生成時と終了/Join時にメモリバリアが存在しているのだろうけど。
>>810 紛らわしいのでちょっと訂正
×生成したスレッド
○生成されたスレッド
スレッド生成(or Join時)に、親スレッドが書いたデータを、明示的な メモリバリアなしにサブスレッドが読み出せることって保証されてるんかね? pthreadは保証されてるみたいだけど、Win32 APIとかどこかに書いてある?
pthreadが保証しているというソースキボン
814 :
795 :2007/07/01(日) 19:50:29
>>807-811 どうもです。説明が下手ですいません。
共有がないならロック処理はいらなさげということで安心しました。
ただ、自作クラスから使用する各言語の標準クラス等について共有メンバがないか継承元の
基本クラスレベルまで調べるのが手間ではありますが・・
大抵はインスタンスメンバはスレッドセーフではありませんとかそっけなく書いてあるだけなので・・
こいいう場合はロック処理を書いたラップクラスで包んであげてスレッドセーフにするのが定石
なんでしょうかね。
んなのインスタンス自身を共有してなければ安全とみなすしかないだろう。 そうでなければそれはライブラリの実装の問題だ。
817 :
デフォルトの名無しさん :2007/07/02(月) 22:48:54
そういえば、Windowsのメモリモデルのドキュメントというのは見たことないのですが どこかにありますか? Windows2003のPlatform SDKからMemoryBarrierマクロというのが増えていますし、 その辺で何か変わっているはずなのですが。
818 :
デフォルトの名無しさん :2007/07/02(月) 23:21:05
>>805 スレッドプーリング (Thread Pooling)
.NETですが質問させてください。 次のようなクラスがあります。 public class BackgroundWorker: Componet { private bool cancellationPending; public bool CancellationPending {get {return cancellationPending;}} public void CancelAsync { cancellationPending = true; } ... } ワーカースレッドでCancellationPendingを調べて止めるという使い方なのですが、 排他は必要ないんでしょうか?
volatile 指定して、ついでにThread.MemoryBarrier() も呼んでやらないと IA64 の SMP とかで困ることになることがあるかもしれない。
>>820 やはりそうですか。
Reflectorで
System.ComponentModel.BackgroundWorkerの実装を見て、悩んでいました。
Microsoftが実装しているのに、残念です。
cancel してから calcel されるまでの時間が不定で構わない、 という仕様なら、実運用で問題は起きなそうな感じ・・・
BackgroundWorkerはComponent派生 ComponentはMarshalByRef派生 MarshalByRefのメソッド呼び出しはインライン展開されない 分かったか?
>volatile 指定して、ついでにThread.MemoryBarrier() も呼んでやらないと どんな意味ないvolatileだよw
いろいろ理屈があってこうなってるのだろうけど、 自分でやるときはlockかvolatileを使ったほうが無難だろうな。
>>824 volatile は VM やコンパイラに対する指示で、メモリバリアとは別のもの。
はいはいCLIの仕様を理解してから言おうね。
>>825 それは同意。
自信がないならlockしとけってな。
>826 C#のvolatileはメモリバリアも行う。
lockを使うけどおかしな使い方するやつはどうしてくれたらいいですか?
Lock! Lock! the L.M.C!
struct pointer_t { <ptr, tag>: <node_t *, unsigned integer> }; struct node_t { data_type value; pointer_t next; pointer_t prev; } struct queue_t { pointer_t tail; pointer_t head; } void enqueue(queue_t* q, data_type val) { pointer_t tail node_t* nd = new_node() nd->value = val while(TRUE){ tail = q->tail # Read the tail nd->next = <tail.ptr, tail.tag+1> if CAS(&(q->tail), tail, <nd, tail.tag+1>){ (tail.ptr)->prev = <nd, tail.tag> break } } } これって本当にLock-Free FIFOなの? というかLock-Free系のアルゴリズムの解説されている書籍ない? いちいち論文探して読むのすっごい面倒なの
>>833 ふむふむ、できればJAVAとかエセ言語じゃなくて
CとかC++の解説が乗ってるの知りませんか?
言語に依存した話題でも無いのにw
毎回コンパイルする際に、-lpthreadをつけているのですが、環境変数か何かを使って これを省略する方法はないでしょうか?
あります
>>836 alias tcc='cc -lpthread'
だれか助けてくれYO
何がわからんのよ CAS?
>>843 CASは解かるけど、後のアルゴリズムがなんで
ここでCAS使うとlock-freeになるのか解からん。
というかlock-freeってパフォーマンス本当にいいの?
volatileには勝てないと思う
おまいら教えてくれ。スレッド(pthread)の死活管理ってどうやるのがよい? 突然スレッドの一つが死んでいてアプリの動きに異常をきたしていた スレッドの死んだ原因はわかったけど原因究明に多大な時間を浪費したし 今後も似たような問題が起こらないとも限らないので解決策を求めています 現在動いているスレッド一覧をアプリから取得するコマンドとかないっすかねぇ スレッドには初めて挑戦するが思った以上に難しいな・・・
WDT
カーネルスレッド単位なら、psとかにそういうオプションありそうだけど。 ユーザスレッドだと外部からは見えないんだからいかんともならん。
>>846 糞コード投下します。Linux限定でpthread_getattr_np()が
0以外ならスレッドしんでます。だから、デバッグ用アプリなんか作成して
共有メモリかなんかにpthread_tとpthead_attrを公開してやってpthread_getattr_np()すれば解かるよ
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
void * TestThread1(void *arg){
sleep(3);return NULL;
}
void * TestThread2(void *arg){
sleep(5);return NULL;
}
int main(){
int ret1 = 0, ret2 = 0;
pthread_t pt1, pt2;
pthread_attr_t attr1, attr2;
pthread_create(&pt1, NULL, TestThread1, (void *)NULL);
pthread_create(&pt2, NULL, TestThread2, (void *)NULL);
while(1){
ret1 = pthread_getattr_np(pt1, &attr1);
ret2 = pthread_getattr_np(pt2, &attr2);
if( ret1 > 0 && ret2 > 0){
fprintf(stdout, "[RET1 %d] [RET2 %d] thread term\n",ret1, ret2);
return 0;
}
fprintf(stdout, "[RET1 %d] [RET2 %d]\n",ret1, ret2);
pthread_join(pt1, NULL);
pthread_join(pt2, NULL);
}
return 0;
}
850 :
846 :2007/07/10(火) 01:33:00
>>849 うぉおお! これだ!
情報ありがとうございます。明日にでもいろいろ試してみます
でもpthread_getattr_np()のmanがないのが気になる・・・
どこかに戻り値の説明がないでしょうか?
ソースがあるじゃないか
852 :
デフォルトの名無しさん :2007/07/14(土) 11:38:27
スタックの代わりになる マルチスレッド処理向けのデータ構造って有りますか?
意味がわかりません><
習志野う
スタックの代わりの意味がわからん TLSじゃだめなのか
lock-free または wait-free なデータ構造を考えてるんですが Exchangeがアトミックな関数だとして、関数Popは スレッドセーフでしょうか? first->nextを読み出してる間にfirstが書き換えられる恐れがありますか? typedef struct Node{ Node* next; int value; } Node* first; int Pop(){ Node* n = Exchange(first, first->next); return n->value; }
>>857 そんな微妙な話なら特に、ちゃんとコンパイルできるコード貼れ。
>>857 > first->nextを読み出してる間にfirstが書き換えられる恐れがありますか?
当然ある。
だから、こういう状況では compare-and-swap (CAS) を使うのが定石。
>>859 当然ってのはどういうこと?グローバル変数だから?
だったら CAS 使っても問題が解決しないよね?
CASで成功するまで繰り返し
というか、そのあたりが判らないなら、Lock-freeな アルゴリズムを実装するのは止めといた方が良い
>693のお馬鹿ちゃんと同じ匂いがするな
865 :
デフォルトの名無しさん :2007/07/26(木) 22:36:34
winsockでUDPのサーバ プログラムを作ってるんですが、どうすればスレッド化できるのかがわかりません。 ログインを済ませたら ユーザー毎にスレッドを立ち上げ、一度ログインした人からはそのスレッド内でコマンドを受けるようにしたいのです。
待ち受けポートが同じなら、デマルチプレキサを実装して、 スレッドに分配してあげたら。
867 :
デフォルトの名無しさん :2007/07/26(木) 22:47:51
multiplexerの反語じゃないのか?
マルチプレクサってよまね?
シナが
>>867 同じ撥音で言うから俺はすげー
そのいいかたするやつ心んでほしいと思う
セレクタのことだろ
特にユーザー・スレッド間に関係がなくて、(Inpersonationとか) 単にコマンドを並列実行したいだけなら、複数スレッドでrecvfrom でコマンドが来るまで待ってる、という選択肢もあるはず。
>>865 スレッド毎にキューを作る。
メインのスレッドは recvfrom で受信し、送り側IP:ポートの組で既存のスレッドを探し(なければ作る)、
そのスレッドのキューに受信したメッセージを追加し、スレッドを待機状態から実行状態へと遷移させる。
スレッド側はキューにメッセージがあれば処理し、なければ待機する。
872 :
デフォルトの名無しさん :2007/07/27(金) 14:40:59
すいません。C言語の初心者なんですが、作り方がわからないプログラムがあります。 初めに数字を入れて、次に+、-、*、/、=と聞かれ、=が押されるまで計算を繰り返 し、=が押されると合計=結果と出したいのですがどなたか教えていただけませんか ?
>872 すれ違い
複数のNICから時系列順に 非同期にパケットを受信する方法ってありますかね?
スレ違い?
なんで, このスレ繁盛してんの? 突き詰めれば排他と同期の問題だろ?
それがお前が考えてるほどそんな簡単なことじゃないからだよ
>>877 なんで人間がこんなに繁殖してるの?
突き詰めればチンコとマンコの問題だろ
それはちょっと突き詰め過ぎだ
突き詰めたいぜ
>>877 マルチスレッドが簡単だと思ったら初心者
難しいと思えるようになってようやく初級脱出
jump、longjump、gotoいっぱい使えば マルチスレッドなんて楽だ。
50%はスレキチガイなのだ
環状バッファで、書き手と読み手がそれぞれ1つしか存在しないときに #def MAX 5000 data{ int len char *data } c_buffer{ data d[MAX] int w_index int r_index } こんな感じでデータ構造作った場合、ロックが必要な場合って w_indexがMAXから0に戻る場合だけでOK? それ以外は、wとrが等しければemptyってことでいいと思うんだけど
886 :
デフォルトの名無しさん :2007/08/04(土) 17:36:16
volatileをつければOK
アトミックな書き込みを保障できるのならいいけど…… なにかそういうAPIかなんか使った方が無難でしょ。
まぁ、intに限って言えば、アライメントさえ合っていれば現実的には問題ないと思うが。 コメントは付けておいた方がいいかもね。 っていうか、w_indexがMAXから0に戻るときも、ロックいらないんじゃない?
>>885 書き込み時にdataの領域とw_indexの双方の更新が必要だから
メモリバリアがないとOoOの関係で不定になりそうな気がする。
メモリバリアとCASなら何とかなりそうな気もするけど、
循環バッファが埋まっている時の挙動を考えると危なそう。
素直にロックしとくのが一番安全だと思う。
>>890 やっぱりそれだと、毎秒270MBでデータ書き込むので
頻繁にlock呼ぶととんでもなくパフォーマンス悪いです。
うーむなんとかならんものか...
>とんでもなくパフォーマンス悪いです 環境と実測値プリーズ
数10〜数100回の書き込み単位でロックしたら?
894 :
890 :2007/08/05(日) 00:06:18
>>891 270MB/秒ってdata内の可変長データでしょ?
1ブロックのデータの平均サイズにもよるんだろうけど、
普通に考えればその内部のデータの処理時間に較べれば
FIFOをロックしてる時間なんて誤差って感じがするけどなぁ。
895 :
890 :2007/08/05(日) 00:13:09
補足しときます。 誤差ってのはロックの競合が少ない場合の話。 FIFO操作くらいの短時間ロックじゃ2スレッドなら そう滅多に競合しないだろうってこと。
>>894 1ブロック7600byte
データ長[300-7600]可変
これで、270MB/secだから仮りに
全ブロックを毎回ロックした場合
943718回ロックが発生するから
CPUすぐブン回って困るのですよ。
いまだに具体的にどういう処理をしようとしているのか理解できない俺がいる。
899 :
890 :2007/08/05(日) 00:49:55
毎回ロックした場合でも競合さえしなければ普通は速い。 本当にロックがネックになっているのか調べるべき。 lock freeが有意義になるのは複数CPUの場合が多いし、 なんか方向性が間違ってそうな気がする。
300〜7600バイトのパケットで270MB/sec おおよそ 50k packet/sec かな? これを2スレッド間(reader/writer)で受け渡したい、という話 packetのadd/remove時に一回ずつlockすると 100k locks/sec やることになる ということでvolatieの導入を考えているらしい 実測しないで語るのがこのスレの掟なのでそこは目をつぶること
ところでReadがWriteに追いついた場合もしくはWriteがReadに追いついた場合は、 それぞれブロックするという動作なの?
busy waitなループで待つに決まってるだろ
単にメモリバリアでいい気がするのは気のせい?
いまどきのCPUって、競合のないロックなら数十ナノ秒程度じゃなかったっけ?
バッファサイズを10001にするんだ
>>905 システムコール半端ないほど発生するから
CPUは無駄に食うよ。それがすげー悩みなの
必ずkernel modeに入ると勘違いしている馬鹿発見?
カーネルモードに入る同期機構、およそ1マイクロ秒(とある環境) カーネルもーぢにはいらないクリティカルセクション等、およそ30倍程度早い(とある環境) ってイメージがある。
カーネルもーぢw
マルチスレッドとクラスを使ったサンプルプログラムを作成しろって言われたのですが、 よくわかんないので面白そうなものが思い浮かびません。 言語はPythonのコマンドラインです。 自分の足りない脳みそでは引数にファイル名を与えて1ファイル1スレッドとかで編集出力とかしようと思うのですが、 何か他に初心者に出来て面白そうな課題ってないでしょうか?
Webサーバ
>>911 指定 URL を http-get & 解析して、img src を並行ダウンロードとかどう?
直列もできるようにして、動作の違いを見れるようにしておくとか。
914 :
911 :2007/08/08(水) 02:29:09
>>913 レスありがとうございます。
なるほど。ダウンロード系の方も面白そうですね。
そういえばregetとかirvineとかあったなぁ。とりあえず脳みそと相談してみます。
他にもありましたら教えてプリーズ
>>914 パケット偽装系のほうが楽しいよ。
実力ついてきたらネトゲの改造とかやると
1ヶ月で300万ぐらい儲かるよ。
信者かるのかよ
信者狩りだー!
もみじ狩りだー!
>911 食事する哲学者の問題とか。
デッドロックするサンプルか!
いやいや、たしか哲学者の食事問題はセマフォを使って回避できるはずだ だからセマフォのサンプルなんじゃない?
922 :
911 :2007/08/09(木) 01:58:38
>>915 >>919-921 レスありがとうございます。
とりあえず913さんのをベースに作ろうと思います。
食事する哲学者の問題は初めて聞きました。先はながいなぁ・・・
Windowsの_beginthreadexでスレッドを作成しているのですが 子スレッドが孫スレッドを生んだあと親である子スレッドは自らreturnで 死んでしまいました。 孫は自分の親が死んだことも知らず元気に活動しています。 という物語は成立しますか?
924がただの荒らしっぽいので追記: Unix のプロセスの様な親子関係は、Win32のプロセスやスレッドにはありません。
なんかさー 線形リスト1要素ごとに mutex用の変数あるってきもくね?
リスト全体をロックするとスケーラビリティが落ちると思ったのかもしれない。
>>928 そんなことねーだろwそんなケースあるのかよw
ロックの分散を意図してるケースならよくあるぞ?
>>931 要素の値のポインタの書き換えに使うケースもある。
リストのリンク関係を更新しないなら全体のロックは不要。
それはインタロックすらいらないケースではないのか?
インターロックというか、メモリバリアは要るんじゃない?
>>933 要る要らないは条件次第。
例えば、pthreadにはアトミック操作関数ないし、
コヒーレンシの保証には同期関数が必要だし。
そもそも「キモい」じゃなくて、要不要、効率面とかで語れと。
pthreadってメモリバリアもないんだっけ?
>>931 Win32 の CRITICAL_SECTION とか linux カーネルのスピンロックみたいな
軽い奴なら 1 : 1 で良いかもしれないと思う。管理も楽だし。
lockで競合するくらいならその方がいいってことはあるだろう。
書くだけスレッドと読むだけのスレッドが 1:1の場合って排他制御する必要あるにょ? 書きまくって読みまくればいいよね?
>>939 それも条件次第。
x86では整列境界に沿ったワード操作はアトミックだが、
全てのCPUがそうとは言い切れない。
複数CPUの場合にはメモリバリアが必要なケースもあるし、
更新された値の反映が遅れても構わないなら無くても問題にならない。
最近はマルチコア流行ってるからね。 ちゃんと排他制御するかメモリバリア張っといたほうがいいと思うよ。
メモリバリア命令ってどうやって使うの? よくわからない....
環境は?コンパイラは?
Linux gcc 3.4 64bit
だからメモリモデルやらが明確でない環境ではやりたくない。 .NETとかJavaとか比較的仕様が明確な環境でしかやる気がしない。
>>945 Java はいいよね、こういうところは。 .NET は知らないや。
memcpyとかもアトミック演算で囲まなくていいよね? あれは中でやってくれてるよね?
やってくれない。
まじかじゃあ自分でmfanceとか用意してやらなきゃ いかんというわけか
だから、そういう事を考えたくないならmutex等を使えと。
素直に mutex とか CRITICAL_SECTION とか使っとけばいいよ・・・ あれらはちゃんと入口と出口でメモリバリアかけてくれてるから。 自分でメモリバリアなんか扱うのは、mutex 実装してる人とか OS の中を作ってる人とか、 あとどうしてもパフォーマンスが気になる速度狂な人くらい。
pthreadやWin32 APIにも Java相当のvolatile read/writeやCASが追加されるんじゃね? その辺の仕様が固まった時期より有効性が認められているだろうし。
FPGA使ってるから、mutexじゃ間に合わねーの ほぼDDR2 533と同速度でデータ流れてくるから こえーのなんのって
そりゃ大変そうだ・・・がんばれ
そんな環境じゃPOSIX仕様での保証とかどうでもいいよね。 好きなだけインラインアセンブラ使ってくれw
ここはちょっと妥協して #define membar() asm volatile("mfence":::"memory") でいこうと思います。 これでもおせーんだよなぁって場合は工夫しないとなw きっとまだ足りないはずだ
条件が後から後からでてくる。いい流れだ。
書き込みだけの場合は sfence とか読み込みだけの場合は lfence とか・・・ どの程度違うかわからんけどね。
>x86では整列境界に沿ったワード操作はアトミックだが、 >全てのCPUがそうとは言い切れない。 >複数CPUの場合にはメモリバリアが必要なケースもあるし、 >更新された値の反映が遅れても構わないなら無くても問題にならない。 なんでやねん
どの点が疑問なのか具体的に指摘してくれないと答えらんない
962 :
デフォルトの名無しさん :2007/08/12(日) 16:49:28
おいおい、volatileでカンペキだろ?
volatileはコンパイラに対するヒントでしかないので、完璧かどうか知る由もありません。
C/C++ の volatile は全然カンペキじゃない。
volatile で完璧かどうかはともかく、 volatile が単なるヒントだなんてことはない。 そんな信用ない実装だったら メモリマップド I/O なんて危なっかしくて使えない。
んにゃ、対象が外因によって変更される可能性があるから最適化の対象にするなというヒントでしかない。 アクセスごとに、外部との同期を取るような保証は全くないよ。
同期を取る保証はないけど、最適化をしないという保証はある。
お前らFPGAなんて使ったことねーからわからねーんだろ(笑) 役立たずは黙っててくれー
>>969 専門知識があるやつ以外お断りなら専用スレ立ててそこでやれよ。
>>969 FPGAなんか使ったことないよ。つーか、あんたはFPGAなんか使っているのかね。
お前らシロウトなの? 毎秒270MBでデータが流れ込んでくるんだぞ FPGAとはそういう世界
もう触るなよ。
ワードの読み書きがアトミックではないかも知れないと言いながら 反映が遅れてもいいなら問題ないって、そんなわけあるかい。
そもそもアトミックに読み書き出来ないならメモリバリアでも足りない
あのなー こっちはFPGAで270MB毎秒のデータを処理せにゃならんの チマチマ排他なんかやってらんないの わかんないかなー
判らん。 なんで、高々270MiB/SecのデータごときでFPGA云々言わなきゃならんのか。 #FPGA使えることをよっぽど自慢したいのかな?
FPGAなんて小さい会社でしか使わないけどな。 でかいところはASIC使うし。
触るなってば。
>>978 それをIntelさん相手に言ってあげてください
きっと驚いてしまうでしょう
>>978 >こっちはFPGAで270MB毎秒のデータを処理せにゃならんの
>チマチマ排他なんかやってらんないの
>わかんないかなー
でも、本当に多量のデータを処理してるのは石の方であって、
>>978 自身ではないと思うんだがなぁ。。。
あのー978は俺じゃないよw ちなみに普通のワークステーションでも処理できるけど リアルタイムにデータ解析できるからFPGA使ってますよ
>>975 よく読め。条件次第の例を二つ出しただけだ。
上は特殊なCPUのケース、
下はメモリバリアの必要性も条件次第の意味。
ところで、lock freeな配列リングバッファって実現されてんの? 連結リストな待ち行列しか見たことないんだけど。
それってどういう動きするもんなの?
つまり要領固定のブロッキングキューみたいなのか、 それともブロックしないものなのか…
質問があります, read/writeシステムコールってスレッドセーフ? おんなじfdに複数スレッドでよってたかって書き込んでもOK? 順番は考慮しないものとして.
992 :
988 :2007/08/13(月) 15:26:25
Javaで言うBlockingQueueだとlock freeな意味ないから、
enqueue/dequeue出来ない場合はfalse/null返す感じの。
あんまり意味無さそうなんだけど、
>>885 のやりたい事ってこれでしょ?
内側にlock freeな配列リングバッファ、
外側に条件変数使ったBlockingQueueを被せる感じ。
どのみちenqueue時にはdequeue待ちしているスレッドに
通知しなきゃいけないからlock freeの意味ないんだけど。
>>991 一般的にはスレッドセーフ。
正確なところは使っているOSのマニュアル嫁。
思いつきで書いてみた。動作確認はしてない。 public class LockFreeRingBuffer<E> { int capacity; AtomicReferenceArray array; AtomicInteger head, tail, elements, spaces; public LockFreeRingBuffer(int capacity) { this.capacity = capacity; array = new AtomicReferenceArray(capacity); head = new AtomicInteger(0); tail = new AtomicInteger(0); elements = new AtomicInteger(0); spaces = new AtomicInteger(capacity); } public boolean enqueue(E element) { if (element == null) throw new NullPointerException(); for (;;) { int n = spaces.get(); if (n == 0) return false; if (spaces.compareAndSet(n, n - 1)) break; } int index = head.get(); while (!array.compareAndSet(index % capacity, null, element)) { index++; } head.getAndIncrement(); elements.getAndIncrement(); return true; }
public E dequeue() { for (;;) { int n = elements.get(); if (n == 0) return false; if (elements.compareAndSet(n, n - 1)) break; } int index = tail.get(); E element; for (;;) { element = array.getAndSet(index % capacity, null); if (element != null) break; index++; } tail.getAndIncrement(); spaces.getAndIncrement(); return element; } } もうちょっと減らせないもんかな・・・
そろそろ誰か次スレよろ
997 :
988 :2007/08/13(月) 16:49:43
spacesとelementsをそれぞれenqueue/dequeueの確定と扱ってるのか。 お互いに対になる要素数を最初と最後に更新して干渉を防いでるんだよね。 「空きがある or 要素がある」を先に確定した上で、 headとtailを対象要素の確定に先だったヒントして扱って 配列中の空要素への追加や有効要素の取得を行う、と。 配列要素の入れ替えあたりでモヤモヤが残る気がするんだけど、 これで良さそうな気もする。うまく説明出来ないんだけどさ。 この手のアルゴリズムの検証ってどうやってやってるんだろう?
おーい、それでFPGAからの270MB毎秒のデータさばけるのかー? そこんとこが大事なんだけど、分かってるかなー?
よゆーよゆー^^
1001 :
1001 :
Over 1000 Thread このスレッドは1000を超えました。 もう書けないので、新しいスレッドを立ててくださいです。。。