06/01/28 15:25:22
>>236
率直に言えば無意味な検証。
というのは、メモリリークだけが問題ではないから。
仮にメモリリークしていなかったとしても、
複数のスレッドで同時に1つのワークエリアを参照していれば、
各スレッドがお互いに1つのワークエリアをぶっ壊しあう。
喪前さんのやり方では、そのパターンが検出できない。
むしろ、メモリリークしている方が複数のスレッドで異なるワークエリアを作成している、
つまり不完全ながらもマルチスレッド対応しているという見方もできる。
(実際どうかは知らん。メモリだけ確保して1つのワークを壊しまくってる可能性もある)
つか、なんでCreateThread()で試してるんだ?
試すまでもなく駄目なの分かり切ってるだろ。
_beginthread*()ならまだわからんでもないが・・・。
238:225
06/01/28 18:02:37
> 複数のスレッドで同時に1つのワークエリアを参照していれば、
> 各スレッドがお互いに1つのワークエリアをぶっ壊しあう。
マルチスレッド対応のランタイムでは、そのような問題は起こらないことが
保証されているものだと思ってました。
_beginthread(ex) の説明を読む限り、メモリリーク問題以外については
何も記述されていません。
> つか、なんでCreateThread()で試してるんだ?
確認したかったのは、「A.EXE で作成したスレッド内で B.DLL 内の関数を
呼ぶことが出来るかどうか」だからです。
A.EXE は BCB5 で作成していて、B.DLL は VC6 で作成しています。
B.DLL 内の C ランタイムルーチンを使うのに、A.EXE の _beginthread(ex)
を使っても無意味なのは初めからわかりきっています。
また、>>235 では書きませんでしたが、3.の場合、C ランタイムルーチン
はスタティックリンクされてるので、やはり A.EXE の _beginthread(ex)
と B.DLL の _beginthread(ex) は全く別物です。
> 試すまでもなく駄目なの分かり切ってるだろ。
メモリリークという点だけ見れば、駄目とは言い切れないという結果に
なったと思うのですが。元々 DLL_THREAD_ATTACH/DETACH で解決し得る
問題だと思ってるので、この結果がおかしいとは思えません。
239:デフォルトの名無しさん
06/01/28 18:45:54
>>238
> マルチスレッド対応のランタイムでは、そのような問題は起こらないことが
> 保証されているものだと思ってました。
思うのは勝手だけど、正しい使い方をしないと正しい挙動はしてくれないよ。
この場合、_beginthread*()を呼ばないと、「正しい挙動」はしてくれない。
なぜなら、Cランタイムをスレッドセーフにする肝心の処理を_beginthread*()がやるから。
ついでに言えば、問題はB.DLLだけの話ではなくて、A.EXEのランタイムに
何を使ってるか? というのも重要。にも関わらず、>>235でその点に
一切触れていない点からも、喪前さんの理解が足りないことが伺える。
240:225
06/01/28 20:18:06
>>239
> なぜなら、Cランタイムをスレッドセーフにする肝心の処理を_beginthread*()がやるから。
_beginthread(ex) と _endthead がやるのは、スレッドごとに必要なメモリ
の割り当てと解放を行うことですよね?
_beginthread を使わなかったせいで、ランタイムルーチンを呼び出し時に
そのスレッドではまだメモリが割り当てられてなかったなら、その場で動的に
割り当てれば問題ないでしょう。実際、動的に割り当ててると思うんだけど。
問題なのは、スレッドの終了を知ることが出来なくなるせいで、割り当てた
メモリを解放する機会が得られなくなり、その結果としてメモリリークが発
生する、ということではないの?
_beginthread(ex) を使わないことによって、排他処理的な問題が起こるとは
どこにも書いてないですよね?起こらないとも書いてないけど。
排他処理的な問題が起こると明記されてるのは、シングルスレッド版の
ランタイムを使った場合の方だけです。
マルチスレッド版の方では、メモリリークのことしか書いてないと思う
んですけど。
> ついでに言えば、問題はB.DLLだけの話ではなくて、A.EXEのランタイムに
> 何を使ってるか? というのも重要。にも関わらず、>>235でその点に
> 一切触れていない点からも、喪前さんの理解が足りないことが伺える。
A.EXE は BCB5 で作成、B.DLL は VC6 で作成と書いてます。
理解が足りないのは認めますが。
長文ばかりで申し訳ない。
241:デフォルトの名無しさん
06/01/28 20:54:27
とりあえず消えろ
242:225
06/01/28 21:09:14
>>241
真面目に質問してるつもりなんですが、そういうのが伝わらない
あたりが 2ch のイヤなところですね。
どこかにこの件に関してきちんと解説したウェブサイトなり書籍
があればご紹介頂きたかったですがね。
243:デフォルトの名無しさん
06/01/28 21:19:39
>>242
そういうのにいちいち気にしていたら駄目だよw
2chの使い方からまず学んだほうが有効に使えるかも。
当然俺のレスにもレスは要らないぞw(あってもいいけど
244:225
06/01/28 21:40:13
>>243
やっぱりそうですか。(^^;
>>235 の結果から、(この検証が正しければ)メモリリークに関しては
処理系依存ということになったわけだし、ドキュメント化されてるわけ
でもないようだから、結局のところ結論なんて出ないんだろうな…。
「A.EXE で作成したスレッドから B.DLL の関数を呼び出すとメモリリークする」
のだとすると、Susie プラグインとか、自分ではメンテナンス出来ないプラグイン
方式の DLL を使うアプリをマルチスレッド化するのは非現実的ということになっ
てしまうのか…。ほとんどの DLL は C ランタイムを使用してるだろうから。
一度作成したスレッドはアプリが終了するまで使い回すようにするしかないの
だろうか…。なんか納得行かないな。
245:デフォルトの名無しさん
06/01/28 22:06:40
Susieプラグイン使う様なサイズのアプリなら、
スレッドプール使えば"about 70-80 bytes"のリークなんて気にする必要ないのでは?
>>242
MSDNだろ。
246:241
06/01/28 22:09:50
マルチスレッドプログラミングをしたことのない房でも225のような真面目なやつを馬鹿にできるんだから
2chって憂さ晴らしに最適だよな。
247:デフォルトの名無しさん
06/01/28 23:06:33
>>231
248:デフォルトの名無しさん
06/01/29 01:07:13
>>244
真面目におかしなことばっかり言ってるから相手したくなくなるんだよ。
依存するのは処理系自体ではなくライブラリだし、
アンドキュメントな実装に依存したコードを書くのは無謀。
漏れが言えることは、
「EXE・DLLの両方で同じライブラリ使ってれば、相互に呼び合いしても問題ない」
「泥沼に足突っ込みたくなければ推奨されてるやり方を使え」
それだけ。普通にMSVCRT使えばいい。
それ以上のこと知りたいなら、AdvancedWindowsなりMSDNなりCRTのソースなり
自分で読んで勉強してくれ。スレでいちいち書けるほど単純な話でもない。
249:225
06/01/29 04:20:43
>>248
> 「EXE・DLLの両方で同じライブラリ使ってれば、相互に呼び合いしても問題ない」
DLL は他人が作ってるので自分でいじれないし、EXE は GUI の
関係上 BCB しか使えないので。
> 「泥沼に足突っ込みたくなければ推奨されてるやり方を使え」
EXE で作成したスレッドから DLL の関数を呼ぶ場合の推奨されてる
やり方とは?EXE/DLL ともに MSVCRT を使うことですか?
> AdvancedWindowsなりMSDNなりCRTのソースなり自分で読んで勉強してくれ
MSDN と CRT のソースは自分なりに熟読してみたつもりです。
CRT のソースから、>>235 の結果は予想通りでした。
でも、3.の結果は予想通りだけど納得行かない。
BCB5 の C ランタイムライブラリのバグと言うべきなんじゃないだろうか。
仕様で片付けていい問題ではないような…。
AdvancedWindows を読んでもう少し勉強してみます。
250:デフォルトの名無しさん
06/01/29 09:28:51
最後のはBorlandのドキュメント読まないと仕方ないでしょ。
使ったことないから、どういう事になっているのか知らないし、
それで仕様通りの利用かどうかもわからない。
いずれにせよ、サードパーティのDLL内で、
CreateThread()を多発してない限り、別に大きな障壁になることじゃないよね。
スレッドを多発する場合、スレッドプール使うのは鉄則だから。
251:デフォルトの名無しさん
06/01/29 18:37:53
>>237>>239
やなやつだなあ。
まじめに答えてる振り装ってるが不快なことこの上ない。
252:デフォルトの名無しさん
06/01/29 19:09:23
まあスレッドプログラミングなんてやってる香具師はそんな香具師ばっかりだから
253:デフォルトの名無しさん
06/01/29 19:30:17
だから日本はだめなんだよな
254:デフォルトの名無しさん
06/01/29 19:57:56
>>252
いっしょにすな!
255:デフォルトの名無しさん
06/01/29 21:20:17
URLリンク(support.microsoft.com)
の"static"の使い方は違和感あるなあ。
"thread local"ってことだよな。実際は生存期間が"dynamic"だし。
256:デフォルトの名無しさん
06/01/30 17:17:51
マルチスレッドでプログラムを作っているのですが、VisualC++6.0(SP6)でデバッグすると
しばらくするとフリーズしてしまいます。
フリーズというのは、VC++と実行しているEXEがまったく応答しなくなり、
さらにOSの反応がほとんどなくなる感じです。
ほとんどというのは、Alt+Tabぐらいは効くのですが、タスクマネージャーも起動せず
他のアプリも、しばらく動くのですがじきに応答がなくなります。
デバッグではなく、ただEXEを実行した場合は普通です。
OSはWindowsXPHome SP2で、まあ標準的な環境だと思います。
1つ怪しいのといえば、NortonAntiVirusですが、これに関しては
ほぼインストールしたてのWin2000SP4のマシンでやっても同じような現象が
起こったので、他のアプリが邪魔している、というわけでもなさそうです。
それなりに長いソースなので、同様の問題が発生する簡単なソースをコピペします。
257:256
06/01/30 17:18:38
#include <windows.h>
#include <stdio.h>
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
char* szClassNme = "aaa";
DWORD WINAPI thread_proc(LPVOID param)
{
int i;
while(1)
{
i++;
Sleep(10);
}
}
258:256
06/01/30 17:19:29
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPreInst,
LPSTR lpszCmdLine, int nCmdShow)
{
MSG msg;
WNDCLASS WClass;
HWND hWnd;
DWORD tid;
if (!hPreInst) {
WClass.style= CS_HREDRAW | CS_VREDRAW;
WClass.lpfnWndProc= WndProc;
WClass.cbClsExtra= 0;
WClass.cbWndExtra= 0;
WClass.hInstance= hInstance;
WClass.hIcon= NULL;
WClass.hCursor= LoadCursor(NULL, IDC_ARROW);
WClass.hbrBackground= (HBRUSH)GetStockObject(WHITE_BRUSH);
WClass.lpszMenuName= NULL;
WClass.lpszClassName= szClassNme;
if(!RegisterClass(&WClass))
return 0;
}
hWnd = CreateWindow(szClassNme, "aaa", WS_POPUP | WS_SYSMENU | WS_MINIMIZEBOX,
100, 100, 200, 200, NULL, NULL, hInstance, NULL);
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
CreateThread(NULL, 0, thread_proc, NULL, 0, &tid);
259:256
06/01/30 17:24:07
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (msg.wParam);
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return(DefWindowProc(hWnd, msg, wParam, lParam));
}
return 0;
}
260:256
06/01/30 17:30:36
thread_procの、while(1)のところにブレークポイントを設定し
F5を連打し何回かループさせると、いずれ固まります。
ひょっとしてプログラムに何か原因があるのでしょうか?
デバッグがままならないとなると開発が非常に困難です。
261:256
06/01/30 20:19:40
WinXPで、ウィンドウズキー+Lで、ユーザーを切り替ることはできたので
別のユーザーからMSDEV.exeを強制終了すると、一応復帰できることが分かりました。
しかし、依然として非常に困っています。
もし以前こんな現象に見舞われたけど、こうして直したよ、とか
ここをこうしたらいいんじゃないの?っていうのがありましたらぜひ教えていただきたいです。
262:デフォルトの名無しさん
06/01/30 20:32:17
osの再インストールしても直らなかったという、ほろ苦い思い出があるよ。
263:256
06/01/30 21:32:25
>262
その後は結局どうなりました?
ひょっとしてマルチスレッドのデバッグは、VC++6.0でできないっていうのが
「仕様」なんでしょうか?
264:デフォルトの名無しさん
06/01/30 21:52:07
Windowsを2000にするか、VisualStudioをバージョンアップしませう
265:256
06/01/30 22:01:27
>264
Windows2000でもなりました。
VisualStudioをバージョンアップですか.... 高かったんですよね。
266:デフォルトの名無しさん
06/01/30 22:26:40
>>256
私も Windows2000 から XP にアップグレードしてから似たような
現象が発生するようになりました。
VC++6.0 と BCB5 でそうなっていて、どちらもマルチスレッド
アプリケーションでなくても発生します。
なんか Window メッセージの送受信の応答がシステム全体でとてつもなく
遅くなる感じですね。バックグラウンドで音楽とか流していても、音楽は
普通に流れますが、ウィンドウの切り替えとかがものすごく遅くなります。
完全なフリーズじゃないだけに、諦めて電源を落とそうにも、落とすタイ
ミングに困ってしまうというか。
URLリンク(www.wg7.com)
これと似たような症状なんですが、私は試していません。言語バーが
使えなくなるのも困るので。
結構頻繁に起こるので辛いのですが、起こらないときは起こらないので、
そういうものだと思って諦めています。
267:225
06/01/30 22:43:46
_beginthread(ex) の説明のところに、CreateThread だとメモリリークして
しまう C ランタイム関数の一覧でも書いてあれば良いんですけどね。
URLリンク(support.microsoft.com)
には malloc とか fopen でもメモリリークするようなことが書かれてるけど、
実際に試してみると、VC6/BCB5 どちらの場合もメモリリークしてるようには
思えないです。
ここに書かれてないものでは、rand() を使うとメモリリークしますね。
今回の呼び出しの結果が前回の呼び出しに依存するようなタイプの関数は
全滅なんでしょうね。
268:256
06/01/30 22:55:37
>266
確かに今まで他のプログラムを組んでいるときにそういうことはありました。
しかし、今回はそれとはちょっと違うように思えるのです。
一度固まると、少なくとも20分ぐらいは待ってみたのですが復帰しませんでした。
しかも、ほぼ毎回起こります。
上のソースに何か問題点があるのでしょうか?
ウィンドウメッセージに応じて処理をするスレッド(最初に起動されたときのもの)
別に他の計算をするスレッドを別に作っています。
競合が起こっているのかと思い、上のような簡単な簡単なソースを書いてみたのですが
あれでも必ずといっていいほど起こります。
ちなみにWindowsMeでも起こりました。家のPC全滅です..
269:266
06/01/31 00:34:55
最初は自分が書いたプログラムに原因があると思ってたのですが、
Web 上にある他人が書いたもののいくつかを自分の環境でコンパイル・実行
してもそうなるので、環境によるものだと思って諦めることにしました。
Windows2000 では問題なかったので、256 さんと私とでは状況が
少し異なりますね。マルチスレッドアプリケーションでなくても
発生しますし。お役に立てなくてすみません。
270:デフォルトの名無しさん
06/01/31 01:33:38
オレもよくなる。ステップ実行しているとなんでもないところで固まってCtrl+Alt+Delをやって再起動とかやるが
まったく動かず、次にAlt+Tabで悪あがき。選択した窓から順に固まる。
最後電源長押し、するとmsdev.exeを終了しています、かなんかがでて、msdev.exeが終了するとほかもサクサク終わる。
もちろんまったく終わらないでそのまま固まることもある。
DLLで提供される関数をステップオーバーしたときに出るとか、なんか最初はそんなことを思っていたけど
そうでもないらしい。
271:デフォルトの名無しさん
06/01/31 09:31:42
Windowsのスケジューラ糞馬鹿だから
タスクマネージャでMSDEV.EXEのプライオリティ上げろ。
272:256
06/01/31 21:11:22
VisualStudio .NET 2003を入れてデバッグしてみたところ、簡単なものは
ほとんど固まらなくなりましたが(とはいえ、ごくたまに固まります)
開発しているプログラムは依然として固まるようです。
いまいちすっきりしないのですが、あまりこの問題にかまっている時間的
余裕も無いのでデバッグ時のみシングルスレッドで動くようにして
場当たり的な解決をすることにしました。
幸運にもあまり修正せずにすむに済みました。
依然として自分のプログラムに問題があるのかという不安はのこりますが...
266さんをはじめ、皆様、様々な情報提供ありがとうございます。
よくあることのようなので、少し安心しました。(していいのか!?)
273:デフォルトの名無しさん
06/01/31 21:27:49
>263
imeだか関係の問題だったはず。
URLリンク(ww1.enjoy.ne.jp)
の、マルチスレッドの注意点の項を参考にしてみては?
私は効果なかったんですが・・・
274:デフォルトの名無しさん
06/02/01 01:56:10
257のコードで何にも問題は出なかったぞ。
F5押しっぱなしでも固まるどころか快調そのもの。
Dual Pentium III 1GHz, NT4.0 VC++ 6.0+Sp5
275:デフォルトの名無しさん
06/02/03 16:12:33
>>256
デバッグモードでなぜかおかしくなるというWin個体は確かにある。
どうしようもない。マシン変えろ
276:sage
06/02/04 00:23:14
VB6.0でActiveX DLLを使用し、マルチスレッドを実現できるという噂を聞いたのですが
本当ですか?
でもイメージが掴めない・・・
VBでActiveXコンポーネント「A」を呼び出し
↓
A作成→A何らかの処理
↓
VBの処理←A処理終了
↓
VB次の処理
って感じでマルチスレッドとは違う気がするんですが・・
もし本当であれば、どなたか参考になるサイトをご教授頂けませんでしょうか
277:デフォルトの名無しさん
06/02/04 01:43:21
URLリンク(search.yahoo.co.jp)
278:デフォルトの名無しさん
06/02/04 08:38:15
>>276
DLLの中はC++で書けばなんでもやり放題なんじゃね?
DLLの中でクリートスレッド
279:デフォルトの名無しさん
06/02/04 09:02:03
>>278
クリートスレッドってなに?
280:デフォルトの名無しさん
06/02/04 09:39:29
CreateとDeleteの合成語だろ
スレッドを作ったら自分で閉じろってことだ
281:デフォルトの名無しさん
06/02/04 12:14:10
>>276
ActiveX のコンポーネントとして作成した DLL/EXE が
スレッドセーフだ、ってだけじゃね?
282:デフォルトの名無しさん
06/02/04 12:20:51
何をしたいのかしらんが
COMのスレッドは楽しいぞ
283:デフォルトの名無しさん
06/02/06 19:46:27
CreateThreadをクリートスレッドって読んだんだろ。
馬鹿みたいだが。
284:デフォルトの名無しさん
06/02/11 07:40:21
もう二日も考え込んでるんですが解決しないんで質問です。(うう、マジで目と頭が痛い…。)
基本的に生産者消費者問題なんですが
Aが物を作るとBに渡し、Bが物を作るとCに渡し、Cが物を作るとDに渡す、というように
複数の生産者/消費者のベルトコンベヤーでの流れ作業を想定しています。
で以下のように組んでみたんですが、
今度はB自身が消費したことをB自身に知らせなくてはならなくてこんがらがってきました。
public class Main
{
public static void main(String args[]) {
ConveyerBelt stationAB = new ConveyerBelt();
ConveyerBelt stationBC = new ConveyerBelt();
ConveyerBelt stationCD = new ConveyerBelt();
Worker producerA = new Worker(stationAB);
Widget consumerB = new Widget(stationAB);
Worker producerB = new Worker(stationBC);
Widget consumerC = new Widget(stationBC);
Worker producerC = new Worker(stationCD);
Widget consumerD = new Widget(stationCD);
producerA.start();
consumerB.start();
producerB.start();
consumerC.start();
producerC.start();
consumerD.start();
}
}
ConveyerBelt()バッファーが三つというのは正しいと思うんですけど
スレッドはABCDの四つだけ作ればいいんでしょうか?どなたかご教授下さい。
285:284
06/02/11 07:43:18
ちなみにセマフォは「なし」の方向でお願いします。
286:デフォルトの名無しさん
06/02/11 07:47:19
日本語で質問してください
287:デフォルトの名無しさん
06/02/11 08:44:23
>>284
Chain Of Responsibility パターンはもう検討済みなの?
288:デフォルトの名無しさん
06/02/11 10:21:28
>>284
4つじゃないとダメなわけもないし、好きに作ればいい
289:デフォルトの名無しさん
06/02/11 12:09:10
各々理由を書いてね。
> 今度はB自身が消費したことをB自身に知らせなくては
> ならなくて
> ちなみにセマフォは「なし」の方向でお願いします。
290:デフォルトの名無しさん
06/02/11 18:57:50
>>289
正確厨、規格厨、口先厨の予感。現状提示されている情報から
回答が思いつかなければ、その問題に対する類似性や経験則
など思い当たるところが無いっつーことだろ。
全部の情報が分からないとコミュニケーションできないような
応用力無しやつは黙ってろ
291:デフォルトの名無しさん
06/02/11 19:56:02
>>9
Double Checked Lockingに追加
Scott Meyers & Andrei Alexandrescu
"C++ and The Perils of Double-Checked Locking (II)"
URLリンク(erdani.org)
付録に"volatile: Brief History"あり。
Douglas C. Schmidt & Tim Harrison
"Double-Checked Locking
An Optimization Pattern for Efficiently Initializing and Accessing Thread-safe Objects"
URLリンク(www.cs.wustl.edu)
292:デフォルトの名無しさん
06/02/11 21:48:09
>>290
エスパー以外は黙れと。
293:291
06/02/11 22:33:21
せっかく流れ切ったのに…
294:デフォルトの名無しさん
06/02/11 22:58:43
>>290
やんわりと、「設計がおかしいんじゃないか?」と言われてるんだよ。
まあ、もうまともな回答は期待できないだろうからどうでもいい話だが。
295:284
06/02/12 01:45:30
ご迷惑をお掛けしております。m(__)m
>>287
そんな概念があったんですね。というくらいなので検討済みではないです。
検索してみていくつかサイトを見つけたのでもう少し読んでみます。
分からなければまた質問します。それと
if (Thread.currentThread() == "Thread[Thread-0,5,main]")
System.out.println("I am the Worker A.");
のようなチェックを入れたいんですが、そんな比較はできないみたいです。
左辺値はどんな感じにすればいいんでしょうか?
これができれば、一つ一つ鎖をつなげていける気がするんですが。
>>288
逆を言うと「4つでもできる」ということですか?
>>289
現状を話しますと
Aから渡された物をB自身が処理(消費)してもないのに
(いや、時にはAから物を渡されてもないのに)
Bは勝手に生産を始めてしまいます。
ですから現在はA-B間、B-C間、C-D間のみで同期がされてます。
それと、やっぱりセマフォアは「あり」でもいいです。
296:デフォルトの名無しさん
06/02/12 05:05:21
ここでは綺麗でも汚くても叩かれますYOW
297:デフォルトの名無しさん
06/02/12 05:06:03
誤爆した スマン...
298:デフォルトの名無しさん
06/02/12 07:55:32
>>294
その「やんわりと」の部分が他人をイラつかせるんだよ。現実でも
相当にいやみな人間だろう
299:デフォルトの名無しさん
06/02/12 08:00:36
>>292
そこまで行間が読めないようだと生きるのに苦労してないか?
300:デフォルトの名無しさん
06/02/12 08:14:33
>>299
292は皮肉で言っただけだから、普段は別段苦労はしてないな。
301:デフォルトの名無しさん
06/02/12 11:03:26
この業界、日本語の喋れない奴ばかりだからエスパー能力は必須だよね
低級エスパーだから日々苦労してるよ
302:デフォルトの名無しさん
06/02/12 11:38:10
エスパーってほどか? そうじゃなくてだな、俺の言いたいことはだ、
類似の問題を経験していたら回答が思い浮かぶだろ。素直に
それ書いてやりゃいいんだ。お前らだって今まで誰かに教えて
もらったり助けてもらったことあるだろうに。
それを忘れてくだらねー皮肉や、重箱の隅をつつくようなまぜっかえしを
親切を装ってやるようないやらしいことすんなよ。ナサケナス
303:デフォルトの名無しさん
06/02/12 11:48:06
別に2chで教えようと混ぜっ返そうとどっちでも構わんと思うのだけど。
まぁ、ヒントだけ貰った方がいい場合と答丸ごと貰った方がいい場合があるのでどっちがいいとも言えないしね。
漏れはここのスレでは教えることも教わることも少ないけど、この板全体では教わることより教えることのほうが多くなるようにしている積もりだがね。
混ぜっ返したり揶揄したり誘導したりも多いけどw
304:284
06/02/12 12:23:35
で、あのー・・・
305:デフォルトの名無しさん
06/02/12 12:28:35
生産者消費者問題くらい、標準的なテキスト読んで自分でやれ
306:284
06/02/12 12:37:41
テキストには生産者消費者が一対一の例しか載ってないんですよ。
こんなに真剣に質問してるのになんでこんな目に遭うんだ…
世の中絶対におかしい。
307:284
06/02/12 12:38:49
丸投げでもなく真剣に書いてるのに…もう馬鹿馬鹿しくて泣けてきた…もういいです。
308:デフォルトの名無しさん
06/02/12 12:57:25
なんで、consumerBとproducerBが別オブジェクトなわけ?
ふつうは入口と出口のある1つのオブジェクトとして考えるでそ?
309:デフォルトの名無しさん
06/02/12 13:03:48
お前らかわいそうだから教えてやれ。おれは良く分からないのでパス。ごめん
310:デフォルトの名無しさん
06/02/12 13:05:39
レベル1エスパーだけど、
>>284
>> ConveyerBelt()バッファーが三つというのは正しいと思うんですけど
>> スレッドはABCDの四つだけ作ればいいんでしょうか?どなたかご教授下さい。
唯一の正解があると思ってるのか?好きにつくれよ
311:デフォルトの名無しさん
06/02/12 13:06:34
>>306
質問する相手を間違えているだけだろう?
世の中がおかしいのではないと思う。
312:デフォルトの名無しさん
06/02/12 13:11:45
普通はレスの付き方を見て、質問の仕方が悪いと思うんだけどね
313:デフォルトの名無しさん
06/02/12 13:17:51
>>284
漏れも>308の言うとおりだと思う。
つか、めっちゃ単純な問題だと思ってたから
まさかconsumerBとproducerBが別だと思ってなかったw
あらためてソース見直してみてビックリした。
> ですから現在はA-B間、B-C間、C-D間のみで同期がされてます。
それでいいんじゃないの?他に同期取らなきゃいけないの?セマフォもいらんと思うけど。
314:デフォルトの名無しさん
06/02/12 13:30:26
>>313
> 他に同期取らなきゃいけないの?
知りもしないのに、
> セマフォもいらんと思うけど。
云うな(w
315:デフォルトの名無しさん
06/02/12 13:43:39
うん、ごめん。よくわかってなかったわ。
最初ConveyerBeltの作り疑ってたもんな。
危うく恥かくとこだった。
316:289
06/02/12 13:51:11
俺も、>>308 に同意。
だから、
> 今度はB自身が消費したことをB自身に知らせなくては
> ならなくて
は、何か勘違いしてんじゃないかと思って、>>289 を書
いてる。はじめのうちは、(俺も含めて) 結構とんでもな
い勘違いをすることがあるから、別にそれがおかしいとは
思わないけど、何を考えてるかわからんと情報を提供して
あげることもできないから。
あと、>>306-307 が本人かどうか知らんけど、「真剣に
質問」したのにまともな答えが返ってこないと言うが、
匿名掲示板に質問すること自体が既に「真剣に質問」して
いるとは言えない。回答する方は、あくまでも知ったかし
たいか暇つぶしか昔の恩を返したいかなんだから、「真剣
に向き合え」とか言われたら、「なんちゃ、それ。」で無
視されるのがオチ。
この板の人は基本的に親切だから、嘘は余り書いてない。
>>290 みたいな雑音を飛ばしてよく読めば、きちんと
ヒントは書かれているから、自分でググルなりすればいい。
そのものズバリの答えが欲しいなら、本を買うなり学校に
通え。
317:デフォルトの名無しさん
06/02/12 14:14:03
実質何も答えていないのを繰り返してるだけじゃね?
318:デフォルトの名無しさん
06/02/12 14:19:02
答える側が堂々巡りするケースのほとんどは、
質問がいい加減なことに起因する。
319:デフォルトの名無しさん
06/02/12 15:40:49
320:289
06/02/12 15:47:02
>>317
まあ、確かにそのものズバリの回答は無いけど、>>287,
>>308 あたりは、充分ヒントになりうると思うが。
個人的見解として、このヒントを基に自分で勉強するぐら
いでないとマルチスレッドのプログラミングはできないと
思う。
321:デフォルトの名無しさん
06/02/12 19:56:19
変なところで改行するなよ
醜い
322:デフォルトの名無しさん
06/02/14 13:30:16
久し振りに来てみたが、相変わらず、このスレは知ったか馬鹿が多いな。
とりあえず>>288、>>310、>>311あたりの馬鹿どもはこのスレいても邪魔だから消えろ。
もう>>284はいないと思うが俺なら
public class Main
{
public static void main(String args[]) {
ConveyerBelt NULL = new ConveyerBelt();
ConveyerBelt stationAB = new ConveyerBelt();
ConveyerBelt stationBC = new ConveyerBelt();
ConveyerBelt stationCD = new ConveyerBelt();
Worker workerA = new Worker(NULL, stationAB);
Worker workerB = new Worker(stationAB, stationBC);
Worker workerC = new Worker(stationBC, stationCD);
Worker workerD = new Worker(stationCD, NULL);
workerA.start();
workerB.start();
workerC.start();
workerD.start();
}
}
とやる。ConveyerBeltクラスん中ではinとoutの二つのbufferを作ってやれ。
323:デフォルトの名無しさん
06/02/14 23:01:34
>>322
> ConveyerBelt NULL = new ConveyerBelt();
> ConveyerBeltクラスん中ではinとoutの二つのbufferを作ってやれ。
馬鹿ジャネーの。
324:デフォルトの名無しさん
06/02/15 00:03:38
>>323
自分の事を良く解ってるじゃないかw
325:デフォルトの名無しさん
06/02/15 00:15:31
俺も
> ConveyerBeltクラスん中ではinとoutの二つのbufferを作ってやれ。
は意味わかんねえ。ConveyerBeltなのに何か処理でもするの?
326:釣りだったのかも...。
06/02/15 01:13:37
>>325
多分、in と out の buffer を取り持つ ConveyerBeltSub
を作るんだよ。
もちろん、その中には buffer が二ついるから、更に
ConveyerBeltSubSub を作って...。(w
# >>322 = >>324 は、基礎から勉強しなおした方がいいぞ。
327:デフォルトの名無しさん
06/02/15 01:48:57
buffer1個でいいでしょ
328:デフォルトの名無しさん
06/02/15 03:43:24
どうでもいいけどなんで4つとも別スレッドで独立して動かす必要がるわけ?
全体としてどんなことをしたいのか今一想像がつかん。
329:デフォルトの名無しさん
06/02/15 15:13:36
あらあら、もう一人馬鹿↑が来た
お前、流れ作業って言葉聞いたことあるか?
330:デフォルトの名無しさん
06/02/15 15:20:00
>Aが物を作るとBに渡し、Bが物を作るとCに渡し、Cが物を作るとDに渡す、というように
>複数の生産者/消費者のベルトコンベヤーでの流れ作業を想定しています。
>>327
お前の読解力は小学生以下か?
buffer一つで出来るもんならやってみろ、馬鹿。
出来ないんならもう来るなよ、ここではお前は邪魔なだけだから。
331:デフォルトの名無しさん
06/02/15 16:06:16
パイプ1個あたりバッファ1個の意味で言った
言葉足らずというか全然意味が通らないねスマソ
332:デフォルトの名無しさん
06/02/15 18:06:14
Java よく知らんのだが、これは要するに
4つのスレッドを3つのキューで繋ぎたい、って「だけ」の話?
333:デフォルトの名無しさん
06/02/15 18:34:54
YES
334:デフォルトの名無しさん
06/02/15 21:04:57
>>329
いやそうじゃなくてどんな処理で4スレッドの流れ作業なんて必要になるのか
想像がつかんのだ。
335:デフォルトの名無しさん
06/02/15 23:29:55
マルチ商法ですた
336:デフォルトの名無しさん
06/02/15 23:46:26
そんなもの想像つかなくていい。
質問に答えりゃそれでいいんだ
337:デフォルトの名無しさん
06/02/16 01:22:58
関連する複数のタスクを回す場合は、個別に分けずに
スレッドプールでまとめてやるのがいいんじゃないの?
やろうと思えばExecuterServiceでも似たようなのできるけど。
□ タスク側
1. 自身のタスク終わったら次のCallableをsubmit()する。
2. 途中のタスクの戻り値としては次のFutureを返す。
3. 最後のタスクは流れ作業全体の値を返す
□ 呼び出し側
1. ExecuterServiceに最初のCallableをsubmit()する。
2. Futureのget()がFutureを返した場合は置き換えてループする。
3. Future以外が返って来たら全タスク完了。
ただ、Callable中で次のタスクをsubmit()すると、バウンド形式なQueueで
最大スレッド数に制限が付いてるとデッドロックの可能性があると思われ。
これはExecuterServiceを流れ作業の数だけ作れば回避できそうかな?
338:デフォルトの名無しさん
06/02/16 01:58:33
>>333
㌧楠。
たったそれだけの事で、こんだけ盛り上がれるなんて
なんの病気なんだ…
>>334
それを実現する手段を知るためじゃね?演習問題みたいな。
339:デフォルトの名無しさん
06/02/16 09:57:05
>>332
たぶんそう。それなのにbuffer二つとか言い出す奴もいて…
そもそも質問があれだし。
340:デフォルトの名無しさん
06/02/17 12:51:20
みんなコロンブスの卵って知ってる?
「コロンブスの卵」は、「誰にできることでも、最初にするのが難しい」という意味で使われる。
1492年にアメリカ大陸(西インド諸島のサンサルバドル島といわれている)を発見したことで有名なコロンブス。
その功績を祝う晩餐会で、ある男が言った「西へ西へと航海して陸地に出会っただけではないか」と言った皮肉に
対して、コロンブスは卵を取り上げ、「この卵を卓の上に立ててごらんなさい」と言った
だれも立てられないのを確認するとコロンブスは、卵のおしり(気室のある鈍端部と思われる)を食卓でコツンとた
たいて立てて言った。「人がした後では何事も簡単です」
>>332
で、その「だけ」の話を理解できなかったのはどこの馬鹿だったっけ?( ´,_ゝ`)プッ
341:デフォルトの名無しさん
06/02/17 13:03:35
なにこの馬鹿…
342:デフォルトの名無しさん
06/02/17 13:13:45
ああ!この↑馬鹿か、その「だけ」の話を理解できなかったのは!
343:デフォルトの名無しさん
06/02/18 00:44:40
文章から頭の悪さが滲み出ている。
344:デフォルトの名無しさん
06/02/18 12:29:01
↑「だけ」の話を理解できなかったのが相当悔しかったんだね。( ´,_ゝ`)プッ
345:デフォルトの名無しさん
06/02/18 16:24:11
なんか雰囲気が悪くなってきたな。
元に戻そうぜ。
これって
Aの生産量≦Bの生産量≦Cの生産量
だよね?でないとCとかDとかが結構待たされるんじゃないのかなーと。
346:デフォルトの名無しさん
06/02/18 21:50:29
↑何もわかってない奴の典型だな!
347:デフォルトの名無しさん
06/02/18 22:38:57
と、必死。
348:デフォルトの名無しさん
06/02/18 23:57:11
荒している馬鹿は、>>322の阿呆レスした奴?
349:デフォルトの名無しさん
06/02/19 03:12:23
ここにいるのは馬鹿ばっかだな
350:デフォルトの名無しさん
06/02/19 03:15:52
>>345
ふいんき(←なぜか変換できない)戻そうと必死なのは分かるが
流れ作業なので
Aの生産量=Bの生産量=Cの生産量
351:332=338
06/02/19 03:40:54
荒らしの相手はやめようや。
>>334
今思い出したが、以前C++ on Windowsで似たような構成にしたことあったわ。
その時は通信スレッド×20→データベーススレッド×2→印刷スレッド×1だったが
キューとミューテックス(各1)で小さいクラス作ったような覚えが。
352:デフォルトの名無しさん
06/02/20 04:08:06
>>350
なんで?
極端な話、Aが2つの整数を流してBがそのxorを流したら半分じゃん。
まぁ別にそんなのはどうでも良くて、
単に4つスレッドを作らなくちゃいけない状況を想像して見たかっただけ。
邪魔してすまん。
353:デフォルトの名無しさん
06/02/20 21:16:12
10メガくらいのメモリをコピー(memcpyとか)するときに、
領域を分割してマルチスレッドにしたら速度上がる?
マルチコアとかマルチスレッディングなら上がるかな?
354:デフォルトの名無しさん
06/02/20 22:57:06
memcpy()だったら変わらない希ガス
fread()とかで、あるスレッドでHDDからデータ読み込み中に、
前回読み込んだデータ解析を行うとかだったらスループットはあがると思う。
355:デフォルトの名無しさん
06/02/21 11:30:13
>>353
CPUが速ければ、
キャッシュを含めたバスシステムがボトルネックになるまでは上がる。
システム依存だから自分のターゲットにしているヤツで試してみて。
356:353
06/02/22 08:10:39
ありがとう。
でも本当はそんなメモリコピーしない設計にするのがいいんだよなorz
357:デフォルトの名無しさん
06/02/22 21:31:45
じゃあ、なんでそんな設計にならざるを得なかったのか、説明してみればいいじゃない。
メモリ参照だけで済むアルゴリズムを誰かが教えてくれるんじゃない?
358:デフォルトの名無しさん
06/02/22 22:06:40
writeで例外起こすようにしてcopy-on-writeだ
359:デフォルトの名無しさん
06/02/23 02:58:53
設計したのは赤の他人。
ワタシはメンテ担当(涙)
360:デフォルトの名無しさん
06/02/23 17:25:34
>>359
その赤の他人よりも上手に設計できたとおもう?
361:デフォルトの名無しさん
06/02/24 00:01:14
何このウスラ馬鹿な突っ込み
362:デフォルトの名無しさん
06/02/26 01:05:49
>>359
設計思想もわからん個所を、色々チューニングしようとしてるの?
悪いことは言わないから「やめとき」。
363:デフォルトの名無しさん
06/02/26 01:08:10
仕事じゃしょうがないよな。
364:デフォルトの名無しさん
06/03/03 07:10:31
UNIXでC++なんですが、URLリンク(d.hatena.ne.jp) ここに載っている、
スレッドローカルストレージを使ったシングルトンの実装って安全でしょうか?
だいたいこんな感じになってます。
public:
static T& getInstance(void) {
static __thread T* tsd_instance = 0;
if (!tsd_instance) {
tsd_instance = getInstance_();
}
return *tsd_instance;
}
private:
static T* getInstance_(void) {
boost::mutex::scoped_lock lk(m);
if (!instance) {
instance = new T;
}
return instance;
}
365:デフォルトの名無しさん
06/03/03 12:00:38
ISO C++の範囲内でポータブルな実装はないんだ。
>>291を読め。
366:デフォルトの名無しさん
06/03/03 23:44:47
>>364
安全ですよ。
getInstance_(void) が既に安全なわけで、
tsd_instance の方は覚えとくだけで、
かつ単一スレッドからしか参照されないので。
メモリモデルの問題については、
たぶんscoped_lock の解放でメモリバリアも処理されるんでしょう。
(pthread のドキュメント呼んでないのであてずっぽう)
367:デフォルトの名無しさん
06/03/04 22:28:46
>365
364はDCL関係ないじゃん
368:デフォルトの名無しさん
06/03/04 22:52:17
>>366
POSIXではmutexの開放はメモリバリア。
369:デフォルトの名無しさん
06/03/05 00:20:02
>>364 例の URLリンク(www.nwcpp.org)
の最後のほうに
> Replace global singletons with per-thread singletons:
> - Each can use thread-local storage.
> -- Threading concerns during initialization thus vanish.
> - But now there are multiple "singletons."
と書いてあって、TLSを364のようには使ってないのが気になります。
一方、
URLリンク(www.cs.umd.edu)
でDoug Leaさんが364方式のTLSの使い方に文句を言っていない(条件
付きながら)ので大丈夫な気もします。まぁ、かなり昔のML投稿ですけど
ね・・。
さて真相は?
370:デフォルトの名無しさん
06/03/06 16:07:01
>>340
普通の卵は比較的簡単に立つよな。表面に凹凸があるから。産みたてほど立ち易い。
・・・コロンブスは卵をツルツルに磨き上げていたに違いない。
371:デフォルトの名無しさん
06/03/06 17:35:06
>>370
まあまあ。
コロンブスもギャグで言っただけなんだから許してやってくれ。
372:デフォルトの名無しさん
06/03/06 19:33:03
後世の作り話ですから。
まあ>>340は底抜けの馬鹿だけど。
373:デフォルトの名無しさん
06/03/07 14:35:11
ゆで卵にして高速で回せば立つよ。
まあ>>372は底抜けの馬鹿だけど。
374:デフォルトの名無しさん
06/03/07 14:57:53
盛り上がっているところ、横から突っ込んでスマンけど。
生卵を立てるには塩をごく少量盛って、その上に立てて、横から
息をゆっくり吹きかけて塩を飛ばすといいという話を聞いた。
とかいう本当にどうでもいい話をマルチスレッドスレでする
自分は底抜けの馬鹿ですw
375:デフォルトの名無しさん
06/03/07 19:27:05
つまり塩スレッドに卵スレッドをロックさせれば桶?
376:デフォルトの名無しさん
06/03/08 10:03:12
卵スレッド発見
377:デフォルトの名無しさん
06/03/08 20:55:31
つまらんよ >>369-376
378:デフォルトの名無しさん
06/03/08 21:34:40
君ほどでも
379:デフォルトの名無しさん
06/03/08 23:26:59
ゆで卵の殻を剥かずに塩をかけるなんて、底ぬけの馬鹿ですね
380:デフォルトの名無しさん
06/03/09 03:03:29
観光地のゆで卵は全部そうなってるよ
381:デフォルトの名無しさん
06/03/09 03:09:09
>>379
卵殻はNa+イオンもCl-イオンも透過するのでちゃんと卵に塩味がつきます。
溶けさえすれば。
382:デフォルトの名無しさん
06/03/09 15:12:11
※注意: このスレはこの卵ネタで1000まで引っ張る覚悟です
383:デフォルトの名無しさん
06/03/09 15:22:01
たまごが立つという状態を定義してください。
384:デフォルトの名無しさん
06/03/09 16:21:34
ブスの卵
385:デフォルトの名無しさん
06/03/09 17:20:48
>>383
案1:
水平方向の任意の角度から卵を投影したときに、水平方向のスパンよりも鉛直方向のスパンの方が長い状態。
ただし卵が他の物体と接することができるのは下部のごくせまい部分のみとする(←うまい定義できないなこれ)
386:デフォルトの名無しさん
06/03/09 20:48:52
ポテンシャルの極大点。
387:デフォルトの名無しさん
06/03/09 21:13:15
あ、あんたなんかにたたれてもうれしくないんだからねっ!
388:デフォルトの名無しさん
06/03/10 00:28:56
>>383
おまいはコンピュータか? んなもん定義しないでも分かるだろ
389:デフォルトの名無しさん
06/03/10 03:03:47
クララが立った、と言う状態を定義してください。
390:デフォルトの名無しさん
06/03/10 03:04:39
精神的な自立
391:デフォルトの名無しさん
06/03/10 03:21:15
それで泣ける、という状態を定義してください。
392:デフォルトの名無しさん
06/03/10 08:40:40
クララが勃った、と言う状態を定義してください。
393:デフォルトの名無しさん
06/03/11 18:55:33
クララが勃った
クララは女である
∴よって勃ったのは乳首である
394:デフォルトの名無しさん
06/03/11 19:03:44
class clitoris extends electiliable {
395:デフォルトの名無しさん
06/03/12 11:42:52
>>394
なんだ、選挙にでも出るんか?
…それを言うならerectibleだろ。
396:デフォルトの名無しさん
06/03/12 16:25:47
Win32
Administrator権限で実行されてるプロセスからスレッドを起こすとき、
スレッドそれぞれに異なるユーザー権限を設定することは可能?
プロセスごとならできるんだが。もし可能ならAPI名などヒントを頼む。
397:デフォルトの名無しさん
06/03/12 16:54:30
インパーソネーションとかいうんだっけ?
ImpersonateLoggedOnUserとか。
まー、RevertToSelfとか呼ばれると、元に戻るけどね。
398:デフォルトの名無しさん
06/03/12 21:06:38
>>397
ありが㌧。
まだ試せてないが、MSDNの説明から目的に適うAPIのよう。
399:デフォルトの名無しさん
06/03/15 14:41:37
なぁなぁ、
class Job extends Thread {
public void run() {}
}
class MyJob extends Job {
public void run() {}
}
ってあったらMyJobのrun()がJobのrun()をオーバーライドするんで
Jobのrun()に書いてある定義とか全部無視されちゃうよね?
ちゅーか、Jobのrun()の一行目に
System.out.println("Hello? Hello? Can you read me?");//never displayed
と書いても表示されないから間違いない。
でも、どうやったら両方のrun()とも動かすこと出来るんだろ?
400:デフォルトの名無しさん
06/03/15 14:42:42
一応ageとく。
401:デフォルトの名無しさん
06/03/15 14:54:45
>>399
1つのスレッドで順番に動かしたいのか?
MyJob.run() と Job.run() を別のスレッドで動かしたいのか?
MyJob と Job のインスタンスをそれぞれ作ったらいけないのか?
402:デフォルトの名無しさん
06/03/15 15:48:21
>>401
ありがと。
二番目の「別のスレッドで動かしたい」かな。
run()直接アクセスするとあかんのよね、.startで始めないと?
どうしようかな?
403:デフォルトの名無しさん
06/03/15 16:35:55
>>402
その手法が可能かどうかの前に、やろうとしていることに対して
もっと単純な方法や、別の解法が無いか検討したらいいんじゃ
ないかな。
ちょっと言語(Java?)の使い方から外れているみたいので、
本当にやりたいことが妥当かどうか見極めた方がいいと思う。
404:デフォルトの名無しさん
06/03/15 22:37:56
>>399
super.run();
405:デフォルトの名無しさん
06/03/16 09:59:17
>>403
確かにそうだったかもしれん。ありがと。
>>404
いや、直接run()にアクセスするのは禁(ry
406:デフォルトの名無しさん
06/03/16 14:36:26
Linux 2.4.31-0vl1.8smp + glibc-2.3.3-3vl1.3
pthread (linuxthread) プログラムでたまーに(でも確実に) seg fault してしまいます。
該当箇所は
pthread_mutex_unlock(&mutex_sleep);
という処理で、mutex_sleep はグローバル。core dump に聞いてみたらこんな返事が。
Program terminated with signal 11, Segmentation fault.
#0 0x080551c7 in __pthread_alt_unlock (lock=0x80cb548) at spinlock.c:600
} else if ((prio = p_node->thr->p_priority) >= maxprio) {
(gdb) bt
#0 0x080551c7 in __pthread_alt_unlock (lock=0x80cb548) at spinlock.c:600
#1 0x08051fc9 in __pthread_mutex_unlock (mutex=0x80cb538) at mutex.c:199
#2 0x0804e3cc in send_proc (arg=0xc) at send_proc.c:112
#3 0x08051709 in pthread_start_thread (arg=0xbdbffbe0) at manager.c:309
何か情報ありますか?
407:デフォルトの名無しさん
06/03/16 20:44:16
mutexがすでに死んでるとか?
408:デフォルトの名無しさん
06/03/16 22:30:14
Windows Threadについて質問です。擬似コードですが、
Thread[] threads = getAllThread();
foreach (Thread t; threads) {
t.suspend();
}
このような全てのスレッドを止めるためのループがあるとします。
このループ中では、既に止められているスレッドと、
これから止められる予定のスレッドがあると思うのですが、
これから止められる予定スレッドが、既に止めたスレッドを再開(resume)するため、
このループでは全てのスレッドを止められない、ということは起こりえるのでしょうか?
409:デフォルトの名無しさん
06/03/16 22:36:16
>>408
起こりうるでしょうね。
避けたいのならばまず自分の優先順位をトテモ高くして、
その後ループに入れば良いと思います。
先方のスレッドも優先順位を上げている恐れがあるのならば
完全ではありませんが。
410:デフォルトの名無しさん
06/03/16 22:36:36
知らね。
だって、普通そんな造りにしないもん。
普通は、終了しろ、っていう合図を各スレッドに送って
自主的に終了なり中断なりするのを待つだけだから。
411:デフォルトの名無しさん
06/03/16 22:37:03
起こりえる。
おまけにこれから止めようとするスレッドが新たにスレッドを作るかもしれない。
全スレッドで、「スレッドマネージ用ミューテックス」などを使用すればいいんでない?
412:デフォルトの名無しさん
06/03/16 22:39:04
他のスレッドを suspend するってのはまず間違いなく設計ミス。
C のランタイムとか Windows に用意されているいろんな dll の
内部まで良く知っていて、何か大事なものの所有権を持ったまま
suspend されちゃったりすることはないと確信を持っているなら
別だけど。
413:408
06/03/16 22:46:12
どうも。
実は、これのpause版とresume版がD言語の標準ライブラリの中にあって、
GCを呼ぶ前にそれでスレッド止めて、後に再開ようとしているみたいなのですけど、
それのへんでアプリケーション側で実装しているスレッドの同期が変になるみたいです。
安心できませんが、安心しました。
414:408
06/03/16 22:52:58
スレッドを止める仕様はどうしようもないのですが、
とりあえずは、全てを止めるループ中(pauseAll)に
pause()、resume()とstart()が実行されないように排他とと
全てを再開(resumeAll)中に、resume()が実行されないように
排他したら大丈夫ということでしょうか?
415:デフォルトの名無しさん
06/03/16 23:01:54
>>414
GC 側が単純なメモリ操作などだけで、
他の処理で使っている(かもしれない)セマフォやミューテックスなどの
所有権なしで実行できるとするなら、問題ないはず。
例えば(MSのドキュメントを信用するなら)Windows API の OutputDebugString は、
内部で他のスレッドを全て Suspend した上でデバッグメッセージの送信を行い、
そののち Resume する、と同様の処理を行っているようです。
AP側のスレッドが変になるのはAP(or Dの何か他のライブラリ)のバグではないでしょうか。
416:408
06/03/16 23:28:41
>>415
resumeThreadの戻りを見ながら、他スレッドのsuspend待ちをしている箇所があるので、
それが、排他されていないresumeAll中に走ると、
GCが止めてこれから再開する予定のスレッドを、
"アプリケーションが思っている理由"でsuspendしたのだと
勘違いして変になるのだと思っています。
417:デフォルトの名無しさん
06/03/17 06:51:35
>>407
ありがとうございます。
pthread_mutex_destroy は呼んでいないので生きていると思っていたのですが、どうやら
syslog(3) が関係しているようです。別の core dump に聞いてみたら syslog 関数で死んで
いるケースが見つかり、付近の syslog(3) をはずしたら seg fault することはなくなりました。
syslog(3) と pthread (linuxthread) は混ぜるな危険とかいう話があるんでしょうか。
とりあえず syslog を自前で用意することにしてみます。
418:デフォルトの名無しさん
06/03/17 07:20:23
その環境ではsyslog(3)はMT-Safeじゃないのに、排他してないだけとか
419:http://www.vector.co.jp/soft/win95/util/se072729.html
06/03/18 19:49:50
TextSS のWindowsXP(Professional)64bit化おながいします
もしくは64bitにネイティブ対応したテキスト置換ソフトありますか?
420:デフォルトの名無しさん
06/03/28 00:13:15
こんな問題助けてください。
I/Oバウンドな処理をする処理プログラムが2個
CPUバウンドな処理をするプログラムが1個
それぞれCPUは85~95%占有するほど負荷が大きいです。
またそれぞれI/O処理は多重スレッドはなく2つの独立した
スレッドプログラムです。
Xeon 64bit x2 (64bitSMPカーネル+ HTTでCPU4個)
Xeon 32bit x2 (32bitSMPカーネル+ HTTでCPU4個)
Opteron 252 x 4(64bitSMPカーネル)
Opteron 252 x 4(32bitSMPカーネル)
いずれの場合も、CPUを占有したいと考えるならばcpu_affinityを
ハードウェア的に割り当てるべきなのでしょうか。
それともカーネルのSMP処理に任せるべきなのでしょうか。
421:デフォルトの名無しさん
06/03/28 06:09:38
page outないくらいメモリが十分にあると考えると、
(OSによってはI/Oキャッシュがメモリを食い潰してしまいますが)
I/Oバウンドな処理をするプログラムにCPU割り当てる意味ないでしょ。
けど、
> それぞれCPUは85~95%占有するほど負荷が大きいです。
で「I/Oバウンド」なの?
それからマルチスレッドじゃないw
422:デフォルトの名無しさん
06/03/28 12:47:04
>>420
CPU占有を占有したいなら、邪魔しに来る恐れのあるほかのプロセスは
どれか他のCPUに割り当てるべき。
CPUを占有することの利点は、
・他のCPUでの処理の邪魔をしない
・各CPUが独立した2次キャッシュを持っているとき、キャッシュの汚染に
よるパフォーマンス低下を避けられる(かもしれない)
の2つくらい。
カーネルに任せるべきかどうかはなんともいえない。
プログラムの性格にもよるし、カーネルのスケジューラーの実装にもよる。
423:420ではない
06/03/29 00:15:05
ぶっちゃけ聞きたいんだが、
「cpu_affinityをハードウェア的に割り当てる」
って、現在存在するOSの中でどれよ?
424:デフォルトの名無しさん
06/04/04 15:54:42
C++で質問ぬ
beginthreadexで作ったスレッド
exitthreadexしないで スレッド関数return で終了して
CloseHandleしても問題ないですか?
サンプルで exitthreadをreturn の前に呼んでるのと
呼んでないの
があったので
425:デフォルトの名無しさん
06/04/04 16:29:21
>>424
寧ろ、exitthreadするとC++のデストラクタが走らないので問題になりがち。
極力returnするべき。
426:デフォルトの名無しさん
06/04/06 01:56:06
世はSPEでプログラミングしたいのじゃ
427:デフォルトの名無しさん
06/04/06 13:02:49
>>423
つ z/OS
428:デフォルトの名無しさん
06/04/16 00:01:57
世界で始めてデッドロックを実際に経験した人って誰だろう。
あまりにもの恐ろしさに震え上がったことだろう。
429:デフォルトの名無しさん
06/05/06 21:33:59
俺
430:デフォルトの名無しさん
06/05/06 22:23:42
哲学者よフォークを取れ!!
431:デフォルトの名無しさん
06/05/06 23:33:04
先生、フォークが足りません!!
432:デフォルトの名無しさん
06/05/06 23:41:15
フォークを取ってどうすんだよw
433:デフォルトの名無しさん
06/05/06 23:46:41
通じてないのかさらに深い洞察なのか…
434:デフォルトの名無しさん
06/05/06 23:47:34
そうかパスタを取れか!!
435:デフォルトの名無しさん
06/05/06 23:50:03
>>434
てめー、すました顔してないで早くフォークよこせよ
436:デフォルトの名無しさん
06/05/06 23:54:39
まず全てのフォークをいったんテーブルに戻して、
そして...
哲学者よフォークを取れ!!
437:デフォルトの名無しさん
06/05/06 23:55:20
すまん、記憶違いだったら悪いんだが。
哲学者よときたら「箸をとれ」じゃなかったか?
438:デフォルトの名無しさん
06/05/06 23:58:02
>>432
哲学者の食事問題を知らない奴キター
439:デフォルトの名無しさん
06/05/06 23:59:11
>>437
ヒント:哲学者は日本人ではない
440:デフォルトの名無しさん
06/05/07 00:00:54
ヒント:ダイクストラ
441:デフォルトの名無しさん
06/05/07 00:10:23
哲学者よ
死ぬくらいなら手づかみで食え
442:デフォルトの名無しさん
06/05/07 00:11:25
哲学者はきわめて明確な論理で行動するため、
臨機応変などという言葉は通用しません。
443:デフォルトの名無しさん
06/05/07 00:17:27
哲学者は、野蛮では無く極めて理知的に出来ております。
444:デフォルトの名無しさん
06/05/07 01:26:53
Dining Philosophers Problem は設定がシュール過ぎて
授業中に笑い出しそうになった
445:デフォルトの名無しさん
06/05/07 04:53:31
シュレディンガーが猫を題材にしたのと通じるものがあるな
446:デフォルトの名無しさん
06/05/07 09:56:09
お前なーやめろよ
話の流れから
シュレディンガーが猫を食材にしたのと通じるものがあるな
と読んじゃったじゃないか
まぁ、たいして違いはないが
447:デフォルトの名無しさん
06/05/07 13:34:52
哲学者よ、明日はパスタにしよう。うん、パスタ。
448:デフォルトの名無しさん
06/05/07 21:18:36
哲学者は手掴みで食べないものなのですか?
449:デフォルトの名無しさん
06/05/07 21:22:19
哲学者はそんなはしたないまねはしません。
しかし決して人に譲ることもしません。
450:デフォルトの名無しさん
06/05/08 00:23:38
哲学者よデスマーチから逃げれ!!
451:デフォルトの名無しさん
06/05/08 09:39:33
age
452:デフォルトの名無しさん
06/05/09 20:31:01
Cでスレッド固有のグローバル変数みたいなものって使えないかな
ほぼ全ての関数でスレッドごとに値の違う変数使ってるんで
毎回引数に加えるのが面倒になってきた
453:デフォルトの名無しさん
06/05/09 20:48:51
処理系固有でTLSなどがあるとは思うが。
454:デフォルトの名無しさん
06/05/09 22:34:47
>>453
サンクス。しらんかった
455:デフォルトの名無しさん
06/05/10 00:58:57
gccだと、
__thread int i;
とか。
456:デフォルトの名無しさん
06/05/10 01:26:42
調べました
pthreadだとpthread_key_create()とかですね
__threadの方が扱いやすいけどポータビリティとしてはどうなんだろう
gcc依存でも別に困りはしないんですけどw
何はともあれありがとうございました~
457:デフォルトの名無しさん
06/05/10 08:23:30
ポータビリティが気になるなら APR とか使うのは?
URLリンク(apr.apache.org)
458:デフォルトの名無しさん
06/05/14 15:00:46
結城浩のデザインパターン スレッド編って買い?
459:デフォルトの名無しさん
06/05/16 12:59:06
. -‐- .
__ 〃 ヽ :
:ヽ\ ノノノ)ヘ)、!〉 :
'. l(0_)!。-‐ ‐〈リ .はわわ~マルチが459ゲットですぅ…
;Vレリ、" (フ/ ;
: l´ヾF'Fl : ∧__∧____
;. 〉、_,ノ,ノ : /|・∀・ ┥ ./\
. /ゝ/´, ヽヽ . . /| ̄∪∪ ̄ ̄|\/
: く/l |_ノト‐'⌒),) . | 拾って |/
460:デフォルトの名無しさん
06/05/20 17:07:49
>>458
買い。
461:デフォルトの名無しさん
06/05/22 00:45:49
longの読み書きについて質問失礼します。
①マルチスレッドで InterlockedExchange を使用し、longの値を変更しています。
②別スレッドで①で変更しているlong値を参照しています。
(読むだけの Interlocked~ の関数が見当たらない為)
この処理って大丈夫なんでしょうか?
実際にソースに組み込んでテストしているのですが、今の所大丈夫っぽいです。。。
462:デフォルトの名無しさん
06/05/22 01:19:41
volatile修飾すれば大丈夫という噂
463:デフォルトの名無しさん
06/05/22 01:25:57
共有リソースを元に、あるメモリに書き込みとかをしなければ問題ないよ。
参照だけなら、何の問題もなし。
464:デフォルトの名無しさん
06/05/22 03:01:15
Interlocked.Read
465:デフォルトの名無しさん
06/05/22 03:01:52
てv1か…
Interlocked.Readは2からだったな…
466:デフォルトの名無しさん
06/05/22 06:15:08
>>461
InterlockedExchangeAdd
467:デフォルトの名無しさん
06/05/23 16:38:37
Pentium XE 840 ではHyper-Threading有効となっているので、
デュアルコア×2スレッドで4スレッド同時処理ができますが、
HTの論理コアを判別する方法はないでしょうか?
SetThreadAffinityMask() を利用して1つのコアを
スレッドに対して独占的に割り当てた場合にHT論理コアだと
処理速度向上が余り望めません。
もしくはWindowsでCPU番号(コア番号)が
どのように割り当てられるかご存知ないですか?
単純に↓とか?
CPU1-Core1-Main
CPU1-Core1-HT
CPU1-Core2-Main
CPU1-Core2-HT
Opteron だと?
CPU1-Core1
CPU1-Core2
CPU2-Core1
CPU2-Core2
468:デフォルトの名無しさん
06/05/23 18:35:25
>>467
何か勘違いしてないか?
469:デフォルトの名無しさん
06/05/23 22:13:13
>>468
何か勘違いしてないか?
470:デフォルトの名無しさん
06/05/26 02:28:01
>>467
それはOSの仕事
471:デフォルトの名無しさん
06/05/26 09:01:15
SetThreadAffinityMask(hThread,0x01);
SetThreadAffinityMask(hThread,0x02);
SetThreadAffinityMask(hThread,0x04);
SetThreadAffinityMask(hThread,0x08);
とした時にどのコアが使用されるか知りたいってことじゃねーの?
472:デフォルトの名無しさん
06/05/26 11:26:01
>>467
URLリンク(www.intel.com)
SetThreadAffinityMaskでCPUにスレッドを固定した後、
当該スレッド APIC ID を入手して core id と SMT ID を入手すればよい。
用語が混乱してるようだけど、Coreっていうのはホントのcoreのことで、
コアの中で演算回路等を共有して独立したCPU風に振舞うのはlogical
cpu とか SMT とか言う。
例えばDualCore でコアあたり2つのSMTをサポートするCPUの論理CPU構成は
Core1-SMT1 / Core1-SMT2 / Core2-SMT1 / Core2-SMT2 だ、
とこんな風に言う。
473:デフォルトの名無しさん
06/05/26 12:26:42
CRITICAL_SECTIONを使う場合ローカルなstatic変数として使用してもよいのでしょうか?
↓のような関数をスレッド内で呼び出す場合です。(ここではcountに同時アクセスしないようにすることを目的とする)
int hoge(int init, int del, int i)
{
static CRITICAL_SECTION cs;
static int count;
if(init) InitializeCriticalSection(&cs);
if(!init && !del)
{
EnterCriticalSection(&cs);
count += i;
LeaveCriticalSection(&cs);
}
if(del) DeleteCriticalSection(&cs);
return count;
}
474:デフォルトの名無しさん
06/05/26 16:39:43
>>470
ヴァカ発見
475:名無しさん
06/05/26 19:42:14
>473
関数のセマンティクスとしてはクソだが、特に問題は発生しないだろう。
476:467
06/05/26 20:21:43
>>472
なるほど…スレッドを固定してCPUIDでチェックすれば判別できそうですね。
用語解説は非常に勉強になりました。
ありがとうございますー
良く考えてみればSMT1が軽い負荷ならSMT2に重い負荷を
かけても遅くならないのかな…?
だとすると、同じコアのSMT1とSMT2に割り当てないようにすれば
効率が良さそうですね。
477:デフォルトの名無しさん
06/05/26 23:31:44
時期尚早な最適化は諸悪の根源だ
478:473
06/05/27 00:41:46
>>475どもです。
479:デフォルトの名無しさん
06/05/27 01:31:47
>>476
みんなpthreadのデバッグってどうやってやってますか?
1ソースコードから処理を推測してデバッグ
2とりあえずなんでもいいからprintf仕込んでデバッグ
3gdbを利用する
4ツールを使って調査する。
もしいいツールとか方法あれば教えてください。
480:デフォルトの名無しさん
06/05/27 11:05:19
>>479
つ【5 - pthreadの気持ちになってみる。】
481:デフォルトの名無しさん
06/05/27 12:17:16
>>479
pgdbgはどうよ? (というかプラットフォームは何よ?)
Linuxは、IBMがpthreadを手がけた時に、
libpthdebug.aがAIXから持ち込まれるかと思ったが、
IBM版はlinuxサイドから拒絶されたので実現しなかった…
482:デフォルトの名無しさん
06/05/27 12:30:20
pgdbgですかぁ渋いですね
それでいっちょ今から会社飛んでデバッグしてきますね
483:デフォルトの名無しさん
06/05/27 17:23:07
基本的に知識足りてねぇって感じなんですが質問させてください。
boostのmutexとconditionでWindowsAPIのEventと同等機能をやろうと思ってやってたんですが
boost::condition::notify_oneを呼ぶときもmutexでロックしないとまずいですか?
これがデッドロックせずに動くってことは多分そういうものだとは思うのですが…
boost::mutex g_mutex;
boost::condition g_cond;
void Wait()
{
boost::mutex::scoped_lock lk(g_mutex);
g_cond.wait(lk);
}
void Notify()
{
boost::mutex::scoped_lock lk(g_mutex); // これって必要ですか?
g_cond.notify_one();
}
484:デフォルトの名無しさん
06/05/27 23:06:05
それでええで。
examples/libs/thread/example/condition.cpp 見てみ。
485:デフォルトの名無しさん
06/05/27 23:06:55
examples/は余分やな…
486:デフォルトの名無しさん
06/05/27 23:20:41
だめだ、pthreadが周りでどうしても落ちる
セグ落ちでどうしてもダメううーん発見できん
神様助けてくれ
487:デフォルトの名無しさん
06/05/28 23:20:52
>>484
ありがとうございます、スッキリしました。
488:デフォルトの名無しさん
06/05/30 18:30:41
>>486
落ち始める直前の状態にまで戻して何やったのか胸に手を当てて考えてみれ。
489:デフォルトの名無しさん
06/05/31 00:36:18
ふっふっふっふ私はもうスレッドは怖くない
スレッドの挙動を完璧把握する方法を知ってしまった
ふっふっふっふ
490:
06/06/01 02:46:02
pthread_cond_timedwaitで、指定タイマーを経過しても待ち状態解除されず
停止したままになってしまっているのですが、引数パラメータに問題が
あるのでしょうか。
gdbで確認したところ引数は問題なさげで、pthread_cond_timedwait内の
pthread_sigsuspendで停止してるっぽいのですが…。
491:デフォルトの名無しさん
06/06/01 12:38:26
糞カーネルを使っているに一票
492:デフォルトの名無しさん
06/06/07 01:46:39
まずOSの種類とカーネルの素性晒せ
493:デフォルトの名無しさん
06/06/07 08:46:05
LINUXですよ(^^)
494:デフォルトの名無しさん
06/06/08 01:10:24
それは windows でない。とだけ言ってるに等しい
495:デフォルトの名無しさん
06/06/08 13:42:04
マルチスレッドとマルチプロセスでは一般的にどちらが効率的ですか?
496:デフォルトの名無しさん
06/06/08 18:36:22
タスク間のデータ参照が多いプログラムと少ないプログラムでは、どちらが「一般的」ですか?
497:デフォルトの名無しさん
06/06/10 01:47:28
volatileで回避できますか?
498:デフォルトの名無しさん
06/06/10 04:22:44
volatileとstaticで8割方回避できます!
499:デフォルトの名無しさん
06/06/10 08:47:58
なにをだ。
500:デフォルトの名無しさん
06/06/10 10:14:15
mutexとvolatileでは一般的にどちらが効率的ですか?
501:デフォルトの名無しさん
06/06/10 12:19:02
コーディング効率か
コードの効率か
で回答が変わってくる可能性がある
502:デフォルトの名無しさん
06/06/10 12:24:23
volatileはLockFreeで高速だが、アトミック操作に限定されるので、
一変数ならともかく、全体の整合性がどういう言い出すとプログラムは
とっても面倒だし、バグがあるかないかの検証も面倒くさい
503:デフォルトの名無しさん
06/06/10 12:54:08
( ゚д゚)ポカーン
504:デフォルトの名無しさん
06/06/10 14:14:06
>>501-502 がマジレスである可能性を想像し、背筋が凍った。
505:デフォルトの名無しさん
06/06/10 15:55:27
そのまま風邪引いて肺炎悪化させて死んでくれ
506:デフォルトの名無しさん
06/06/10 16:56:15
こんにちわ。誘導されてきました。
セマフォの扱い方について、よろしければ教えてください。
以下が環境です。
・HP-UX & aCC
・共有メモリを使用し、その排他制御にセマフォを使用している
・共有メモリとセマフォは専用のクラスを作成して管理している
・上記資源は複数のプロセスで使用する
・上記管理クラスのインスタンスはプロセス内に複数存在する
やりたいことは以下の通りです。
・1つのプロセス内で、同じキー値を利用するセマフォの lock を
ネストさせても2回目以降の lock で固まらないようにしたい
・unlock はネスト中の実際に lock した箇所に対応したところで
実行するようにしたい
void a() { void b() {
CSemafore sem1; CSemafore sem2;
sem1.lock(); sem2.lock(); ←ここで固まらないようにしたい
b(); sem2.unlock();
sem1.unlock(); ←ここで解除したい }
}
セマフォのクラスインスタンスが1つの場合は lock の回数を数えるカウンタを
用意することで解決できそうなのですが、複数の(同じキー値を利用する)インスタンスが
絡んできた場合に、上手に処理する方法が思い浮かびません。
こういったことは可能なのでしょうか。ご教示頂けると嬉しく思います。
よろしくお願いいたします。
507:デフォルトの名無しさん
06/06/10 17:01:47
trylockしてみて無理だったら待てばいいんじゃねぇの?
違うってかゴメンね
508:デフォルトの名無しさん
06/06/10 17:27:39
>>506
どういうデッドロックを想定しているの?
th1がaをlockしてbを得ようとして、th2がbをlockしてbを得ようとしているとか?
入れ子セマフォア
多重セマファオ
で解決できませんか?
509:デフォルトの名無しさん
06/06/10 17:47:33
>>508
>入れ子セマフォア
>多重セマファオ
おチツ毛
510:506
06/06/10 19:05:08
>>507
ご返信ありがとうございます。
trylock とは「lock が可能な状態であれば lock を実行し、そうでなければなにもしないで
終了する」処理との理解で正しいでしょうか。trylock が失敗した場合の処理を実装できれば
よいのですが、出来るだけ単純化したいと考えており、今回の件では少し辛いです。すみません。
>>508
ご返信ありがとうございます。
知識が足りず「入れ子セマフォ」「多重セマフォ」の言葉が分かりません。
検索も試したのですが... すみません。
今回はスレッドを使用していないので基本的にはプロセス単位で考えています。
目的としては同一プロセス(スレッド)による lock でデッドロックを発生させないように
する方法を探しています。ご例示頂いた異なるスレッドによるデッドロックは‥‥実際にやって
いたのですがw、プログラムを直してうまく動くようになりました。
先の投稿に記述した「やりたいこと」について考えていたのですが、以下のようにすれば
出来そうに思えてきました。
・2つめの unlock 位置の判定の件は「カウンタ」の管理で解決できそう
(もっと良い方法があるようでしたらご教示頂けると嬉しいです)
・1つめのネスト時のデッドロック防止については、セマフォのキー値毎に最後に lock を
掛けたプロセス(スレッド)を識別出来るようにして、それが自プロセス(スレッド)で
ない場合だけ lock 処理を実施する
上記の「最後に lock を掛けた(sembuf.sem_op を 0 にした)プロセス(スレッド)を識別する」
方法はあるのでしょうか。お知恵を拝借できれば幸いです。
>>509
少しウケました。そのノリは高校の時以来です。w
511:デフォルトの名無しさん
06/06/10 19:54:30
>>510
URLリンク(ja.wikipedia.org)
古典的って言ったら古典的か.
512:デフォルトの名無しさん
06/06/10 19:56:50
>>510
ロックの話だけで頭がいっぱいになってるけど
そのsem1とsem2の間でどんな処理をするのか
教えてよ。
513:506
06/06/10 21:59:59
>>511
ご返信をありがとうございます。
これは「多重セマフォ」の解説(使用例の項)でしょうか?
残念ですが、今回の件は同時参照を全て止める必要があるため、初期値を大きくすることに
よって解決とすることは出来ないと思います。情報をありがとうございました。
>>512
ご返信をありがとうございます。
不要と判断していました。たとえばですが。
共有メモリにある情報をまとめたテーブルがあるとします。
関数 SetData01() はこのテーブルの特定のデータを変更します。
同様に SetData02() など複数の関数があり、それぞれ関数内部でデータを変更するための
(受取手にとってわかりやすい形から格納に適した形への変換などの)処理を実施しています。
これら関数には対応する GetData**() も存在し、変更/参照時には共に排他制御(sem2)を実施します。
更に上記個別の値をまとめて取り扱う関数として SetGroupData() なる関数があり、
先の個別にデータを変更/参照する関数を内部で使用します。
この関数でのデータの変更時には、関連する全てのデータ更新が終了するまではデータ間での
矛盾発生を防ぐために他からのデータ参照を止めたい場合があるため、この関数の実行時にも
排他(sem1)を掛けたいと考えています。
回避策として、SetGroupData() で SetData01() などを呼ばずに自前で個別データの
設定を行う方法もあるのですが、少々煩雑な処理をするところもあるため、可能であれば
SetData01() などを利用する形に出来ればと思っています。
そのままのことは書けないため、説明が足りないところもあるかと思いますがご容赦ください。
514:デフォルトの名無しさん
06/06/10 23:56:28
>>513
そのよくわからんけど、SetDataなんちゃらっていうメソッドをいくつも用意するの?
そんなことするよりもさ
SetData(class data)を用意してこいつが責任もって共有データを単独で更新すればいいんじゃないのか?
じゃあ、みんなで同時に呼べねーべバーカとか思うなら、このSetDataは要求をスタックに貯めて逐次実行する
仕組みだけを排他制御で実装すればいいよね。共有メモリに置く程度のデータならそれぐらいで間に合わないかな?
515:506
06/06/11 15:27:03
>>514
ご返信、ありがとうございます。
初めからそういう方向性を考えていれば...と後悔しているところです。(汗
次こそわ。
516:デフォルトの名無しさん
06/06/11 20:23:12
いや、変えないと今のも終わらないから。
517:デフォルトの名無しさん
06/06/12 17:52:57
質問です。
_beginThreadを使ってスレッドをつく、その中でゲームの描画をまわしているのですが
void ThreadMain(void* pParam)
{
HANDLE hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
DWORD dwLastTime = timeGetTime();
while(!pApp->m_bStopThread)
{
WaitForSingleObject(hEvent, 16 - __min(16, timeGetTime() - dwLastTime));
dwLastTime = timeGetTime();
//実際はここで描画をするけど、今は空.
}
CloseHandle(hEvent);
_endthread();
}
こんなことを行なうとタスクマネージャー上でCPUパワー使用率が100%近くになってしまいます。
(WaitForSingleObjectは、待機中CPUパワーを使わないとあったので期待したのですが)
Sleepあたりを入れてみたりしても、Sleep(1000);くらい大きく指定しないと使用率0%付近になりません。
スレッドを使った場合、CPU使用率は高くなってしまうものなのでしょうか?
今まではスレッドを使わず、WinMainで処理をしていたのですが、そちらでは使用率が0%に近かったです。
518:デフォルトの名無しさん
06/06/12 17:53:43
今までスレッドをやらないパターンですとこんな感じでした。
CPU使用率は常に0%付近でした。
//WinMainに
while(TRUE){
while(0 != PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)){
if (!GetMessage(&msg, NULL, 0, 0))
return msg.wParam;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else if (16 <= timeGetTime() - dwLastTime){
dwLastTime = timeGetTime();
// 処理
}
}
519:デフォルトの名無しさん
06/06/12 18:04:20
>>517
それ、WaitForSingleObject で待ってない(即リターンしてる)から。
他のスレッドが所有権を持ってないので、呼び出したスレッドが即座に所有権を得ておしまい。
2度目以降の呼び出しは、呼び出したスレッドがすでに所有権を持っているので即座に完了。
他のスレッドに所有権を持たせておくか、selectとかSleepでも使うべし。
520:519
06/06/12 19:39:57
今思いついたんだけど、とにかくタイムアウトさせたいなら
GetCurrentThread() で得たハンドルを wait してもいいのかもしれない。
521:デフォルトの名無しさん
06/06/12 19:45:59
>>519
アドバイスありがとうございます。
ただ、デバッガで追ってみましたところきちんと毎回Waitしている様子です。
Wait時間を分かりやすく5秒にしてみたところ、私の期待通りの動作をしているようです。
selectについてもこれから試してみたいと思います。
522:デフォルトの名無しさん
06/06/12 19:53:00
Sleep、WaitForSingleObject、いずれも、寝ている時間の精度自体は5msも保証できない
523:デフォルトの名無しさん
06/06/12 19:57:04
>>522
なんと、そうなのですか?
やはりFPS60なんていう精度を望む場合
Waitなんて無しでぶんまわしつづけるしかないのでしょうか?
(そもそも、Windowsで精密ゲームを作ること自体、Windowsの設計理念とは反している気がしますが)
524:519
06/06/12 20:25:43
>>521
そですか・・・ところでメインスレッド側は PeekMessage 無しに戻しましたか?
単純に >>518 から else 以降を取ってしまうと、CPU 100% のビジーループに
なるわけですが。
525:デフォルトの名無しさん
06/06/12 21:08:55
ところで、なんで、NOREMOVEでPEEKしたあと、またGetMessage呼んでるの?
単純に、直接REMOVEでPEEKして、Translate,Dispatchすればいいと思うんだけど
526:デフォルトの名無しさん
06/06/13 14:46:50
pthread_create() で作ったスレッドが終了したかどうかの確認は
どうしたらいいんでしょうか? pthread_join() してしまうとその
スレッドが終わるまで待たされてしまいますよね?
やりたいことは、複数のスレッドを作って、作った側で pthread_t
の配列にスレッド識別子を入れておき、それぞれがバラバラの
時間で終わるんですが、作った側で pthread_t の配列に入っている
値を元にそれぞれが終わったかどうかを確認して、終わっていたら
それに対して pthread_join() をやって資源開放をて、配列の側も
その部分を終了しているという値(たとえば0)にしたいんです。
(つまり UNIX で複数 fork() したあとで waitpid() の WNOHANG
みたいにして何が終わったか、あるいは何も終わっていないのかを
確認するのと同じことです)。こういうのは pthread ではどうやる
んでしょうか?
527:デフォルトの名無しさん
06/06/13 21:33:23
pthreadは詳しくないけど自分でフラグ作っても大して開発効率落ちないと思う。
528:デフォルトの名無しさん
06/06/14 00:10:40
SIG_CHLDシグナルで判断しろよ
529:デフォルトの名無しさん
06/06/14 12:15:21
>>528
pthread で作ったスレッドに対して SIGCHLD は使えないのでは?
子プロセスじゃないんだし。(Linux の実装だと使えるとか?)
530:デフォルトの名無しさん
06/06/14 13:11:53
POSIX P1003.1cにpthread_kill()ってのがあって、
signalを指定する引数に0を指定すると、
pthreadがいれば成功(シグナルは何も送られない)、
いなければESRCHのエラーになる。
processに対するkill(2)と同じ仕様。
> 自分でフラグ作っても大して開発効率落ちないと思う。
ではありますが。
531:デフォルトの名無しさん
06/06/14 13:23:26
>>530
あー! その手があったか。
くっそー。 pthread_kill() の man ページは見ていたのに気が付かなかった。
どうもありがとうございます。
532:デフォルトの名無しさん
06/06/17 17:46:23
スレッドのデバッグって何使ってますか?
Linuxだとgdbだけかな?
533:デフォルトの名無しさん
06/06/19 00:32:10
知恵と勇気
534:デフォルトの名無しさん
06/06/19 01:05:12
>>533
そんなのいらねーよ何か教えねーと食うぞ?
535:デフォルトの名無しさん
06/06/19 10:33:24
「ちびくろ! おまえを たべちゃうぞ!」と、とらは いいました。
536:デフォルトの名無しさん
06/06/19 21:49:53
>>532
かん
537:デフォルトの名無しさん
06/06/20 13:18:17
>>532
おれ、この前 gdb でやってみて大混乱。
使い方調べてから使わないといかんね。
538:デフォルトの名無しさん
06/06/24 17:19:02
無茶しやがって…
539:デフォルトの名無しさん
06/06/24 21:26:39
Windowsで、タスク内の複数スレッド間だけで通用する、高速な同期オブジェクトって無いですかね?
なんか、どれもこれも、重そうで。
540:デフォルトの名無しさん
06/06/24 23:41:41
イベント系はユーザーモードで実行される。
イベント系はプロセス間の動機にも使えるという強みがある。
クリティカルセクションのみカーネルモードで実行される。
クリティカルセクションはプロセス間の動機で使えないがイベント系に比べると
非常に高速だという強みがある
541:デフォルトの名無しさん
06/06/24 23:49:15
>>540
クリティカルセクションって何?
542:デフォルトの名無しさん
06/06/24 23:58:44
ミューテックスとほぼ同じ。
タイムアウト指定ができなかったりする。
543:デフォルトの名無しさん
06/06/25 00:07:28
カーネルモードに移行するものが高速で
ユーザーモードのまま実行できるものの方が遅いって?
544:539
06/06/25 03:10:41
クリティカルセクションだと、スレッド間での排他は楽だけど、同期には使えないよね。
イベント系はカーネルまで落ちるし、プロセス間で使えるから重いよね。
同期に使えて、カーネルまで落ちなくても良いようなヤツが欲しいンだけど、
Windowsでは用意されてない気がするんだ。
それって、正しいのかな?
545:デフォルトの名無しさん
06/06/25 03:29:24
2つのスレッドだけでいいのならクリティカルセクションでも同期は取れる。
最初にどちらかのスレッドが所有権を保持するようにする。
片方のスレッドはEnter.....()で所有権が解放されるまで待機。
所有権を持っていたスレッドが所有権を解放すれば片方のスレッドは
実行が開始されるようになる。
高速性が大事でかつ簡易な同期処理でいいならこんな方法もある。
関数自作するとか。排他制御ができれば後は自分でいろいろできる。
546:デフォルトの名無しさん
06/06/25 06:33:19
Fiberでも使ってみたら?
NT以降専用だが。
547:デフォルトの名無しさん
06/06/25 07:21:53
以前も微妙に話題になったが、MeteredSectionとか、
AdvancedWindowsのOptExとかで楽しちゃうってのもある。
MeteredSection
URLリンク(msdn.microsoft.com)
OptEx
URLリンク(www.microsoft.com)
548:539
06/06/26 17:26:10
>>545
>>546
>>547
とりあえず、情報どうも。Fiberだと排他・同期というより切替に近いので、同期にはならない気がする。
問題は、CriticalSection系は、同一スレッド上では同期しないので、>>545さんの方法、OptExはちょっと難しい感じ。
つーか、それだとどちらか片方の処理が重いときにバグになっちまう。
ということで、MeterdSectionを使うのが良いのかなぁ。でも、こいつ、CriticalSectionの拡張版みたいなもんみたいだから、
排他は出来るけど、同期は難しそう。
探したら日本語のページがあったので貼り付け。
URLリンク(www.microsoft.com)
それとも、原始的にロックファイル作るか…うーん、100近いスレッドが立ったとき考えるとやりたくないな…。
とりあえず、Mutexあたりを、最初にまとめて作成することで負担を減らすしかなさそうな感じ。
みなさん、ありがとう。
では。
549:デフォルトの名無しさん
06/06/27 21:28:46
>>548
具体的にどんな処理がしたいの?
単一プロセス内ならCriticalSection で何でも作れるよ
(だからこそOSもCriticalSectionしか提供してないわけで)。
あと「同一スレッド上では同期しないので」ってのはどういうことを
意図してるのかちょっとわからない・・・同一スレッドで非同期に
コードが実行されるのは Unix の signal のケースくらいで、
Windows のユーザモードでは起きないんじゃない?
550:デフォルトの名無しさん
06/06/27 22:11:04
>>549
ありゃ、そういう答えが返ってくると言うことは、
もしかして オレのCriticalSectionについて根本的な使い方や理解が間違ってるのかな…。
スレッドひとつしか無ければ、EnterCritical...をいくつ並べても無視されると思ってたんだけど、違うのかな…。
551:デフォルトの名無しさん
06/06/27 22:13:57
スレッドひとつならマルチスレッドじゃないからな
552:デフォルトの名無しさん
06/06/27 22:21:17
そんなにパフォーマンス気にしてるのに
何でロックファイルとかにいくんだ…
553:デフォルトの名無しさん
06/06/27 22:39:45
英語でプログラミング勉強スレ
スレリンク(english板)l50
554:539
06/06/27 22:53:13
>>551
でも、プログラムは大抵、ひとつのスレッドから開始されるんだよ。最初からふたつってわけじゃない。
まあ、だから、>>545 は使えないんだよな。
555:デフォルトの名無しさん
06/06/27 23:12:31
なにか、壮大な勘違いをしている予感
556:デフォルトの名無しさん
06/06/28 01:48:11
まず、「同期する」をどういう意味で使っているのか説明してもらってからだな
557:デフォルトの名無しさん
06/06/28 01:56:37
同期の人と一緒に仕事をする
同期するじゃね?
558:デフォルトの名無しさん
06/06/28 03:31:41
>>539
そういうのは、ふつーにeventだの何だのをでも使ってみて、重くてやってらんなくなってから考えれば良い。
559:539
06/06/28 14:26:16
>>558
なんだそりゃ。そう言う回答は勘弁して欲しいぞ。
560:デフォルトの名無しさん
06/06/28 16:09:22
なんで>>539は質問してる身分でやたらと偉そうなの?
リアルでもそういう質問の仕方しか出来ない人?
561:デフォルトの名無しさん
06/06/28 16:16:15
>>559
「回答」ではないだろう。
「重そう」と思うだけで実際にやってみることもせず
そのくせ「ロックファイル」なんて単語まで飛び出し
結局何がしたいのか、「同期」が何を指しているのかも
説明してくれない君への
アドバイスじゃまいか。
562:デフォルトの名無しさん
06/06/28 16:45:09
おまえら馬鹿なんじゃね?
563:デフォルトの名無しさん
06/06/28 16:54:40
>>560-561
ウザ
564:デフォルトの名無しさん
06/06/28 17:45:49
つーか、時々デッドロックするようなプログラムしか作ってないのかょ、おまえらは。
565:デフォルトの名無しさん
06/06/28 17:46:52
なにか、壮大な勘違いをしている予感
566:デフォルトの名無しさん
06/06/28 18:17:22
なにかが気に喰わなくて暴れ始めたお母ん
567:デフォルトの名無しさん
06/06/28 18:54:40
予感でプログラムが組めるヤツはニュータイプ。
568:デフォルトの名無しさん
06/06/28 21:21:38
まてまて。
>>539 はWindows のカーネルやAPIを設計した人たちや
普段からマルチスレッドAPなんかさんざ書いてる漏れも
見落としている、何か難しい問題に対処しようとしてるんだよ。
それはたぶんロックファイルと関係のあるなにかなんだろう。
漏れには想像もできないが、頭ごなしに否定しないでだまって
観察してあげるべきじゃないか?
569:デフォルトの名無しさん
06/06/28 22:34:06
なにか、壮大な勘違いをしている予感
570:asdlman
06/06/28 22:40:26
>>569
>>555
lead reth !!!
571:asdlman
06/06/28 22:47:52
>>569
>>555
test
572:デフォルトの名無しさん
06/06/28 23:21:13
Vistaから同期IOのAPIがキャンセル可能になるそうですね!
573:デフォルトの名無しさん
06/06/29 13:12:51
それは、非同期IOのことだろ。
574:デフォルトの名無しさん
06/06/29 15:47:52
>>573
同期IOだよ。非同期IOのキャンセルならWindows98でも出来る。
575:デフォルトの名無しさん
06/06/29 15:54:38
それを非同期というのではないのか?
576:デフォルトの名無しさん
06/06/29 16:11:59
>>575
めんどくさいなーもう。ほらよ↓
今まではCerateFile なんか非同期版がなかったからキャンセルできなかっただろ?
URLリンク(www.microsoft.com)
577:デフォルトの名無しさん
06/06/29 16:29:46
>>575
いや、絡んでるつもりは全くなかったんだ、すまん。
つまり、同期I/Oを他のスレッドで実行することによって擬似非同期I/Oの
ような使い方をしたときに、そのAPIの実行をキャンセルすることができる
ようになったということだな。
同期/非同期とはそういうことだったのか。勉強になった。
578:デフォルトの名無しさん
06/06/29 16:30:17
s/>>575/>>576/
579:デフォルトの名無しさん
06/07/01 17:16:56
Linuxのカーネル層でマルチスレッドのような
設計が必要になっているんですが、
Aという関数が終わったらBの関数で
止めていたところが動き出すような設計って
どうやったら良いもんですか?
セマフォを使った排他処理ってデータに
対する排他処理になると思うんだけど、
そういう形で発想の転換をしないと駄目なのかな?
580:デフォルトの名無しさん
06/07/01 19:10:53
待ちたいところでスピンロックでもasm WAITでもなんでもしておけばいいだろう
581:デフォルトの名無しさん
06/07/01 21:33:47
>>579
condは適当に初期化。
A() {
~;
pthread_cond_signal(&cond);
return;
}
B () {
pthread_cond_wait(&cond);
~;
return;
}
582:デフォルトの名無しさん
06/07/01 22:07:31
>>581
参考になります。
これってAのreturnの直前でBが動き出す
ということですよね?
Aが終わってからってのはやっぱり難しいのかな。
583:デフォルトの名無しさん
06/07/01 22:20:08
>>582
AA() {
A();
pthread_cond_signal(&cond);
return;
}
584:デフォルトの名無しさん
06/07/01 22:23:13
>>522
昔の奴へのレスで恐縮なんだがWindowsのSleepってそんな精度悪かったっけ?
::timeBeginPeriodとか使っても駄目?
585:デフォルトの名無しさん
06/07/01 22:49:29
他に忙しく仕事をする連中が居なければ、だいたいは大丈夫かもね。
586:デフォルトの名無しさん
06/07/01 23:26:40
>>585
なるほど
まあそれほど信用できないってことか。
587:デフォルトの名無しさん
06/07/02 00:04:19
スレッドの教科書ってどんなのあるの?
アルゴリズム系に強いやつが欲しい
588:デフォルトの名無しさん
06/07/02 00:14:48
OSによって違うな。
pthreadなら>>1->>9辺り見て。
589:デフォルトの名無しさん
06/07/02 00:18:29
Lamport's bakery algorithmとかさこんな古典的なやつから
今の新しいアルゴリズムまで載ってるのないのか.....
590:デフォルトの名無しさん
06/07/02 00:49:51
>>583
AAは別の人のソースなので手を加えられないのです。
でも参考になりますた。
ありがとうございますた。
591:デフォルトの名無しさん
06/07/03 06:53:31
windows には win32 API で色々なイベントを使えるようになってますが、
UNIXではpthreadのイベントを使う以外にないのでしょうか?
592:デフォルトの名無しさん
06/07/03 07:26:25
>>591
例えばこういう奴?
URLリンク(www.monkey.org)
どの UNIX を対象にしているかで答えも変わるけど、大抵はググれば色々出て来る。
593:デフォルトの名無しさん
06/07/05 10:16:26
Winsock、_beginthreadで起動して、
グローバル変数で終了要求するような、
簡単なスレッド書いているのですが、、、。
スレッド内でrecv()のような、
ブロックするような関数を呼びたくなりました。
これを終了するにはどうしたらよいでしょう。
594:デフォルトの名無しさん
06/07/05 10:30:57
ソケットオプションでノンブロッキングにすればいいんでない?
595:デフォルトの名無しさん
06/07/05 11:33:24
594>
ありがとう、そうします。
一般的にはどうでしょ?
ブロッキングするような関数をスレッドで呼んではいけない?
596:デフォルトの名無しさん
06/07/05 11:51:06
ブロッキングするべき状況と、そうでない状況がある。
前者ならブロックさせとけばいいし、そうでなければ非同期APIを使うか、
別個にスレッドを作ればいい。
597:デフォルトの名無しさん
06/07/05 11:59:52
>>593
recv()呼ぶ前にMSG_PEEKしておくなりしとかんとあかんよ。
#つーか、TCP受信処理を途中で終わらせると言う仕様そのものが如何なものかと。
598:デフォルトの名無しさん
06/07/05 13:48:39
>>595
一般的かどうかは知らないけど、普通はselect使うんじゃないかな。
599:593
06/07/05 13:49:40
>>596
「強制終了」以外は普通にブロックして、データが届いたときだけ
処理してくれればいいんだけど。って状況でした。
非同期っていうと、WSAEventSelect, WSAAsyncSelectで、通知を待つって
ことでよいですよね?
>>597
ちょっとわかんないのですが、
MSG_PEEKで、受信データが無いときはどうやって次の受信データを待つのが綺麗?
あと、途中で終わらないとしたら、どうやって終わるのがよいですか?
600:デフォルトの名無しさん
06/07/05 18:14:11
>>599
WSAAsyncSelect(s, hwnd, 0, 0);
shutdown(s, 1);
while (recv(s, buf, buflen, 0) != 0) {}
closesocket(s);
601:デフォルトの名無しさん
06/07/05 19:33:20
>>600
それ先方がデータ送ってくれないとCPU100%のビジーループ。
サーバアプリでは非常によろしくないコーディング。
602:デフォルトの名無しさん
06/07/05 19:50:55
recvって、ブロックするんじゃないの?
603:デフォルトの名無しさん
06/07/05 19:54:13
スマソ。ノンブロッキングのソケットと勘違いしてた。
604:デフォルトの名無しさん
06/07/05 20:35:06
WSAAsyncSelectした時点でノンブロックになる
605:593
06/07/06 17:50:25
任意のタイミングで終了させたいスレッド内では、ブロックする関数は呼ぶな。
socketはデフォルト非同期で。
で理解しました。 ありがとう。
606:デフォルトの名無しさん
06/07/06 19:44:58
>>605
そう理解したんならそれでもいいが・・・
607:デフォルトの名無しさん
06/07/06 22:55:34
ソケットを任意のタイミングで終了させると再起動したときにわややがな。
608:593
06/07/06 23:34:44
>>607
どゆこと?
例えばサーバ的なアプリで、その受信用スレッドを、サーバ的なアプリ
のユーザ都合でブチっとしたくなった場合、、、
受信処理を終了させて、クローズなり何なりをしたい。
そんな場合ですが、再起動とは、ここでサーバ的なアプリを再度起動して
受信を始めようとした場合になにかが起こるってことですか?