08/12/07 20:11:23
>>254
そもそも、シングルコア、1スレッドあたりのタイムスライスを10msとすると、
1周するのに単純計算で10ms×2,000=20,000ms=20秒だ。実際には10msよりも
もっと長いのが普通(※1)だし、スレッド切り替えにもコストがかかる(※2)し、
マルチコアとしてもコア数分の1にしかならない上に、コア間の調停にも
やっぱりコストがかかる(※3)。
あと、ネットワークの実効速度についても、デカいパケットが順番に流れる
なら、かなり帯域上限に近付けることができるが、細かいパケットが非同期に
衝突しまくりながら流れるようだと、いいとこ1/3くらいしか出ない。
ぶっちゃけ、アプローチが間違ってるとしか思えん。
※1:ぐぐってみたところ、Windowsについてはこんなんが引っかかった。
URLリンク(itpro.nikkeibp.co.jp)
もっと良い資料やUNIXについての言及があれば教えてくれ。
※2:レジスタ等のコンテキスト情報を全部保存してパイプラインを捨てて
他スレッドのコンテキストを読み込む。キャッシュから溢れてたら最悪
メインメモリまで取りに行くハメになるぞ。
※3:各コアが互いに読み書きできるレイヤまでデータが届く必要があるため。
262:デフォルトの名無しさん
08/12/07 20:37:21
たしか一般に、CPUサイクルで見て、
スレッド作成が数万~10万サイクル(ひょっとすると数十万~だったかも)、
コンテキストスイッチが数千~1万サイクル
とか見た気がする。
263:デフォルトの名無しさん
08/12/07 20:38:37
おっと、スレッドに関わるオーバーヘッドの話ね。
264:デフォルトの名無しさん
08/12/08 01:15:52
>>262
>コンテキストスイッチが数千~1万サイクル
今時LinuxでもO(1)スケジューラなわけだが。
265:デフォルトの名無しさん
08/12/08 01:22:44
そりゃ的外れなレスなこって
266:デフォルトの名無しさん
08/12/08 01:48:56
ワロタ
267:デフォルトの名無しさん
08/12/08 09:39:27
WindowsとかLinuxとか・・・
そんな貧乏臭いOSの話ばっかでワロタ
268:デフォルトの名無しさん
08/12/08 10:27:54
そうですか
269:デフォルトの名無しさん
08/12/08 13:48:37
アセンブラ級はついていけn
270:デフォルトの名無しさん
08/12/08 18:58:28
何十万ものスレッドをサポートするようなシステムもあるんだよね?
どういう構造になってんだろ
根本的に考え方からちがうのかな?
271:デフォルトの名無しさん
08/12/08 19:01:51
>>270
カーネルスレッドは使わない(ユーザスレッドでやる)、か、そういうスレッドを
サポートしたカーネルでないと無理。普通のUnixの普通のカーネル(含むLinux)
とかだと無理。
272:デフォルトの名無しさん
08/12/08 21:55:16
OSはWindowsXPなんですよ
で、ソースですが
for( int i=0; i<2000; i++ )
{
_beginthred( DoIt, 0, NULL );
}
void DoIt( void * )
{
DownloadURL( URL, filename );
_endthread();
}
ってな感じですけど
ほとんど同時時間にスレッドを起動させてるのですが、
タイムスライスが各スレッドに割り当てられないのでしょうかね?
それともやっぱり >>232 さんの言っているように
サーバー側が延滞処理をほどこしているんでしょうかね?
問い合わせたくてもあまり進んで聞けるようなことではないので
273:デフォルトの名無しさん
08/12/08 22:05:16
>272
スタック用の仮想メモリが足りなくなってない?
あるいは、その呼んでいるDownloadURLが
STAみたいな実装とかw
>261
IOが支配的なスレッドで、タイムスライスの意味なんか
ほとんどないとおもうけど。
274:デフォルトの名無しさん
08/12/08 22:48:50
同一サーバにHTTPコネクションを2000張ろうとしていたオチと予想
275:デフォルトの名無しさん
08/12/08 23:28:21
Irvineとかで試してみればどうかな
276:デフォルトの名無しさん
08/12/08 23:41:31
>>274
攻撃とみなされても仕方ありませんな
277:デフォルトの名無しさん
08/12/09 00:06:27
>>273
仮想メモリなのに足りなくなるとは、これいかに。
278:デフォルトの名無しさん
08/12/09 00:15:39
2000個のスレッドでスタックだけで仮想メモリ使い切るだろWin32なら。
279:デフォルトの名無しさん
08/12/09 00:20:56
いくらIOバウンドだって普通2000はやりすぎ。
普通はせいぜい100までだろう、CPU数にもよるがそれでも多いくらいだろう。
だいたい2000個の各ファイルのサイズはどのくらいで、
単体での転送速度はどのくらいなんだ。
ってダウンロードが2個までしか同時に動いてなかったりしてなw
あとサーバ側も普通は当然そんなに同時処理できない
キューに入って順番に処理されるだけ。
280:デフォルトの名無しさん
08/12/09 01:06:30
>>278
> 2000個のスレッドでスタックだけで仮想メモリ使い切るだろWin32なら。
相変わらず意味不明。
281:デフォルトの名無しさん
08/12/09 01:07:09
俺がワーカスレッドをプールする場合は、
特に深く考えずに単にコア数の倍だけ用意しとく。
IOブロックで動けるようになった他のスレッドもIOでブロックされるだけだしね。
282:デフォルトの名無しさん
08/12/09 01:23:17
>277,280
正確には仮想メモリ空間。
Win32では、ふつー、プロセス毎に、ユーザ空間として
使用可能なのは、下位から7fffffffあたりまでで、2GB。
だいたい、ポインタが32bitであることの限界とみていい。
で、Win32のスレッドは、1つあたり、規定では1MBの
スタックを仮想メモリ空間に確保する。他にもDLLとかの
コード領域も同じ2GBの空間を使うわけで。
283:デフォルトの名無しさん
08/12/09 01:35:04
>>282
仮想メモリというのはプロセス毎にあってだな・・・
284:デフォルトの名無しさん
08/12/09 01:47:50
>>283
>237嫁
285:デフォルトの名無しさん
08/12/09 01:56:53
>>283のおバカさを示すなら>>191の方が適切だろ。
286:デフォルトの名無しさん
08/12/09 09:08:47
>>281
だったらコア数の2倍はちょっと少なくない?
まあIOってもネットワークなどの場合で、
もちろん少ない投入数で帯域使いきれるような場合や
同一サーバにつなぐような場合は別だが。
287:デフォルトの名無しさん
08/12/09 10:26:51
Win32(笑)
288:デフォルトの名無しさん
08/12/09 10:28:16
ネイティブなプロセスやスレッドで並列性増やす方法は全然スケールしないから
軽量プロセス/スレッドが流行るんだろ
Erlangのような言語は言語のレベルでそういうものをサポートしている
目的がI/O多重化なら昔ながらのselect系のシステムコールが使える
WindowsならIOCP
Javaは1.4以降でnioという形でそれをサポートしてるし
Cならlighttpdで使われているlibeventのようなものがある
それはそうと、Windows XPあたりだと、デフォではTCPの同時接続数が10だかに
制限されているはずだが
289:デフォルトの名無しさん
08/12/09 12:08:39
>>288
ソースは?
290:デフォルトの名無しさん
08/12/09 12:11:40
>>289
「どれ」についてのソースなのか分からんが、
最後のものについてなら、そのまんま
Windows XP 同時接続数
でぐぐればいくらでも情報が手に入るだろ
291:デフォルトの名無しさん
08/12/09 12:18:08
UDPは制限あるの?
292:デフォルトの名無しさん
08/12/09 12:19:40
知らん
UDPにはconnectionという概念がないから、多分無いんじゃないかとは思うが
自分で調べたらどうだ
293:デフォルトの名無しさん
08/12/09 12:25:13
いやです
ありがとうございました
294:デフォルトの名無しさん
08/12/09 12:40:30
ググってみたが、XPのSP2から1秒間につき10コネクションという
制限がついたらしい。
時間をあければ万単位までいけるみたいだが。
295:デフォルトの名無しさん
08/12/09 12:40:39
Windows XP Professional の場合、ネットワーク経由で同時に接続することができるコンピュータの最大数は 10 です。
とありますが、
メッセンジャーに繋げてますが
この状態だと最大数は9になるのでしょうか?
296:デフォルトの名無しさん
08/12/09 13:11:01
制限解除するパッチもあるよ。公式じゃないけど。
297:デフォルトの名無しさん
08/12/09 13:11:23
もう少し詳しく調べてみた。
同時最大接続数が10に制限されるのは、listenする側の制限。
ようするに自分がサーバになる場合。
外向きの接続に関する制限は、half-open connectionが
1秒間に10個までに制限されている。(SP2から)
half-open connectionは相手がacceptしてない接続のこと。
外向きの接続数に関しては、能力的な限界以外に制限は無さそう。
ただし1スレッドにつき64ソケットの上限有り。(回避は可能)
298:デフォルトの名無しさん
08/12/09 13:13:51
>>297
え?内向きの制限はもともとサーバー系でない奴にはついていて、
XP SP2以降のは、外向きの制限だろ?
299:298
08/12/09 13:15:20
要は、listenじゃなくて、外に貼りに行くコネクション数に制限がついたってことな
300:デフォルトの名無しさん
08/12/09 14:35:58
>>298-299
そういう制限は見当たらなかった。
日本語の非プログラマ系のブログでそう書いてるところはあるが、勘違いだろう。
実際にセッションモニタ見てると、10なんて余裕で超えてるし。
301:デフォルトの名無しさん
08/12/09 14:47:37
>>300
は?
Event ID 4226でぐぐれよ
秒間の「外向きの」同時接続試行回数に関する制限で、
非公式のtcpip.sysに対するパッチも出ているから
302:デフォルトの名無しさん
08/12/09 15:00:15
P2Pとかやると直ぐでるからわかる
303:デフォルトの名無しさん
08/12/09 15:12:52
ああ、論点のずれが分かった
10個以上のTCP/IPのコネクションが維持できないって制限じゃないだろ
秒間に10個以上SYNパケット(TCPの最初のハンドシェイクで使う)を
投げないようにしているだけのはずだ
要するにスレッド沢山つくって並列でダウンロードさせようとしたところで
10個目以降ではconnect()呼んだ時点で制限にひっかかり、少なくとも他の
ハンドシェイクが完了するまでは待たされるってこった
304:デフォルトの名無しさん
08/12/09 15:36:05
ちゃんと297でhalf-open connectionと書いたんだが。
それを否定されたら、同時セッション数としか読み取れないよ。
305:デフォルトの名無しさん
08/12/09 15:45:44
そうだな、よく読んでなかった
すまん
306:デフォルトの名無しさん
08/12/09 17:47:13
クライアントでどこまでスケールさせる気だ。
307:デフォルトの名無しさん
08/12/09 20:04:18
googleのクローラでね?w
308:デフォルトの名無しさん
08/12/10 17:25:35
シングルスレッドでダウンロードするとうまくいくのですが
マルチスレッドでダウンロードするとエラーが返ってきて
GetLastError() で戻り値を調べても 0 で何が原因か分からないのですが
どなたか分かりませんか?
WinXP です
309:308
08/12/10 17:29:32
マルチスレッドといっても、デバックの為、スレッドはひとつなので
競合などはおきないように設計しているのですけど、うまくいかないのです
310:デフォルトの名無しさん
08/12/10 17:39:11
さすがにそれだけで答えろって言われても、俺には無理だな。
GetLastErrorを呼ぶスレッドは合ってるの?
311:デフォルトの名無しさん
08/12/10 17:42:36
ダウンロードはどのAPIを使っているの?
312:デフォルトの名無しさん
08/12/10 19:15:01
>>311
ググってもでないのよねフフフフフフフフフ
313:308
08/12/10 19:19:36
>>311
機密事項なので答えられません><
314:デフォルトの名無しさん
08/12/10 20:40:26
>>311
WinInet
InternetOpen
以外のAPIだけとは言っておく
315:デフォルトの名無しさん
08/12/10 20:42:31
>>311
とあるライブラリなんです
何かはいえませんが
316:デフォルトの名無しさん
08/12/10 20:55:51
俺は原因わかったよ
ここには書けないけど
317:デフォルトの名無しさん
08/12/10 21:36:55
内々に連絡しておいた。
318:デフォルトの名無しさん
08/12/11 03:36:59
Debug版を納品とかフフフフフフフフフフフフフフフフフフフフフ
フフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフ
319:デフォルトの名無しさん
08/12/11 09:31:46
ソースも示さずデバッグ依頼とな。
320:デフォルトの名無しさん
08/12/11 09:37:51
ソース。
スレリンク(mnewsplus板)
残念ながらもう消えてしまったようだが。
321:デフォルトの名無しさん
08/12/11 12:06:37
>>318
お主もなかなかのフフフフフフ
でもユーザー名ばれるのよねフフフフフフフッフフフフフフッフ
322:デフォルトの名無しさん
08/12/11 12:29:11
夜中にひとりでデバッグしてる時に
フフフフフフフフフフフフフフフフフフフフフフフフフ
とか
feeefeee feeefeee feeefeee feeefeee
とか見ると鳥肌が立ちそうになる・・・
323:デフォルトの名無しさん
08/12/11 14:11:44
POSIXスレッドでmutexロックでのデッドロックの回避法教えてください
324:デフォルトの名無しさん
08/12/11 14:27:28
馬鹿どもにマルチスレッドを走らせるな
325:デフォルトの名無しさん
08/12/11 14:36:53
>>323
2個以上のmutexを同時にロックしないというルールを徹底させるのが一番簡単かと
326:デフォルトの名無しさん
08/12/11 15:32:14
走る~♪
走る~♪
スレッドーたーちー♪
327:デフォルトの名無しさん
08/12/11 15:32:57
馬鹿ですいません><
328:デフォルトの名無しさん
08/12/11 15:58:59
_beginthread( multi, 0, data );
>はわわわわ~
>はわわわわ~
>はわわわわ~
>はわわわわ~
>はわわわわ~
>はわわわわ~
>はわわわわ~
>はわわわわ~
>はわわわわ~
>はわわわわ~
>はわわわわ~
>はわわわわ~
>はわわわわ~
>はわわわわ~
>はわわわわ~
>はわわわわ~
>はわわわわ~
>はわわわわ~
>はわわわわ~
329:デフォルトの名無しさん
08/12/11 18:46:03
APIの問題ではなかったようだ
設計の問題だったようだ
これは普通気づかない
330:デフォルトの名無しさん
08/12/11 20:45:05
Critical!
Criticalなのぉ~
Criticalな処理をしていなかったのぉ~
んぼおおおおおおおおおおおおおおおお
331:デフォルトの名無しさん
08/12/12 04:49:09
馬鹿はマルチスレッドやっちゃだめだよ。
死んだじっちゃんの口癖だった。
馬鹿って言うのは思考力が著しく劣る人なんだけど、
具体的に例をあげれば、自分で調べて答えを見つけられない人の事なんだ。
332:デフォルトの名無しさん
08/12/12 07:20:42
だ~か~らぁ~
ぐぐってもgooで聞いてもダメなのぉぉぉぉ~~~~
333:デフォルトの名無しさん
08/12/12 11:05:47
デッドロック 予防 とか、デッドロック 回避 とかで検索して、端から見ていってみ。
334:デフォルトの名無しさん
08/12/13 13:36:29
1スレッド
2スレッド
3スレッド
4スレッド
5スレッド
全部ためしたののですが1スレッドが一番早かったです
どうしてでしょうか?
335:デフォルトの名無しさん
08/12/13 14:23:51
よくあることです。
336:デフォルトの名無しさん
08/12/13 14:40:12
何を試したんだよ
337:デフォルトの名無しさん
08/12/13 17:25:44
キアイ
338:デフォルトの名無しさん
08/12/13 19:48:33
あるスレッドで処理した結果をメインスレッドに渡したいのだがどうすればいい?
_beginthreadexの第3引数に結果用のポインタを渡せばいいのか
339:デフォルトの名無しさん
08/12/13 20:43:24
典型的にはソウデスナ
処理してほしい内容と
処理結果の格納場所を
与えるのがよろしいかと思いますダ
340:デフォルトの名無しさん
08/12/14 01:39:30
>>338
CPUにお祈りする
341:デフォルトの名無しさん
08/12/14 02:58:11
>>334
マルチスレッド化して速くなるかどうかは状況による。
その状況がわからなきゃ、何とも言えない。
342:デフォルトの名無しさん
08/12/16 07:49:17
>>338
グローバル変数でいいよ
メモリ空間を共有してるのがスレッドのメリットなんだし
343:デフォルトの名無しさん
08/12/16 09:18:38
…
344:デフォルトの名無しさん
08/12/16 11:09:40
volatile最強
345:デフォルトの名無しさん
08/12/16 11:13:32
>>388
俺はそういう場合スレッドセーフなスマートポインタ使うな
スレッドにデータを渡す前に参照カウント増やしといて
スレッド側では使い終わったら解放
メインスレッドは結果が必要なくなればスレッドが終了していなくてもデータを解放できる
346:デフォルトの名無しさん
08/12/16 11:22:01
クラスにしてthis渡してるな
class tiny_thread abstract {
protected:
HANDLE m_hthread;
unsigned m_id;
: いろいろメンバー
private:
static unsigned WINAPI thread_start(void *o) {
tiny_thread *tt = (tiny_thread *) o;
return tt->run();
}
public:
bool start() {
m_hthread = (HANDLE) _beginthreadex(NULL, 0, thread_start, this, 0, &m_id);
return m_hthread != 0;
}
virtual int run() = 0;
};
347:デフォルトの名無しさん
08/12/16 15:41:15
>>388は素人童貞
348:デフォルトの名無しさん
08/12/16 15:56:58
>>388 に期待
349:デフォルトの名無しさん
08/12/17 01:34:39
・メインスレッドが必ずサブスレッドより長生きするようにする。
メインがサブをjoinなり必要に応じて中断するなりする。
・結果格納場所のポインタやコールバック関数のアドレスをサブに渡す。
メインがUIスレッドの場合、サブからPostThreadMessageした方が楽かも知れない
・通信用メモリの解放責任をメイン側と決めておく
>>345みたいなサブスレッドだけ生き続ける設計は個人的に(GCの無い言語では)嫌だ
これらが難しいと思うなら>>342だね。カッコ悪いけど確実かな
350:デフォルトの名無しさん
08/12/17 01:53:27
PostThreadMessageは取りこぼしが発生するので使っちゃいけません。
PostMessageを代わりに使おう。
351:デフォルトの名無しさん
08/12/20 00:19:42
ところで、ファイバーってどうなん。
アイドル状態のスレッドでパカパカやって動かすとか
スケジュール処理なワーカスレッド代わりとかしか思い浮かばん。
漏れは、スレッドの処理は概ね、待ち処理とか先行処理なので、
あまり使い方が思い浮かばない。
352:デフォルトの名無しさん
08/12/20 01:51:56
>>351
ファイバーは移植のためにあるようなもので
新規プロジェクトで使う価値は無に等しい。
353:デフォルトの名無しさん
08/12/20 02:10:30
>>352
短絡杉
プリエンプティブであることは必ずしも望ましいことじゃない。
ゲームではファイバーが好まれる。
Larrabeeでもシェーダはファイバーで実装されるそうだ。
マルチコアでハイパフォーマンスだすためにファイーバーは重要。
354:デフォルトの名無しさん
08/12/20 02:31:59
自分でコンテキストスイッチとかめんどくせぇぇぇ
355:デフォルトの名無しさん
08/12/20 03:01:53
ちまちま排他処理すんのめんどくせぇぇぇ
356:デフォルトの名無しさん
08/12/20 12:21:50
>>352、353
マルチスレッドで複数の関数叩くのと、ファイバーを複数キックするのの違いってやっぱ、
同期処理が不必要(他のスレッドでキック中のファイバーは自動的に同期される?)だとか
スタックの制限(ファイバーキックされた段階でスタック指定できる)ですか?
いえ、無論色んな意味合いで違うことは判るけど。
357:デフォルトの名無しさん
08/12/20 16:20:24
int result = write( buf, size );
if( result == -1 && errno == EAGAIN ) SwitchNextCoroutine();
I/Oイベントドリブンなスケジューラをみたことある。↑みたいなの。
あとは同期が要らないってのが素晴らしい。
358:デフォルトの名無しさん
08/12/20 20:34:51
VisualStudio 2010にはC#のyieldを使ったファイバーもどきライブラリが付いてくるらしいね
URLリンク(channel9.msdn.com)
359:デフォルトの名無しさん
08/12/20 23:50:27
それは歪でいまいちだね~
まずコルーチンがあって
それにスケジューラを足してファイバー
イテレータ風に味付けしてジェネレータ(C#のyieldのことね)
という階層があるべき姿だと思うな。
360:デフォルトの名無しさん
09/01/10 00:18:47
64CPU環境でスレッドを256本生成したときに
struct data[2000];
なんてあって、dataの個々の要素を排他的にアクセスしたい場合
pthread_mutex以外に使えそうな手段ってありますか?
CASってどうやって使うのかよくわからんし助けて
361:デフォルトの名無しさん
09/01/10 00:48:43
pthread_mutexでマズい理由は?
362:デフォルトの名無しさん
09/01/10 00:58:20
>>361
2000個もpthread_mutex_tって用意して使えるのですかね?
363:デフォルトの名無しさん
09/01/10 01:08:25
発想が変?
364:デフォルトの名無しさん
09/01/10 01:47:06
mutexを2000個作って問題ないと思うよ。
自分だったら、struct data[200] 全体に対して1個のmutexにして、それ
でパフォーマンスの問題が出たらそのときに対処を考える。
reader-writerロックが使えれば使う。
365:デフォルトの名無しさん
09/01/10 01:47:49
訂正。
> 自分だったら、struct data[200] 全体に対して1個のmutexにして、それ
struct data[2000] ね。
366:デフォルトの名無しさん
09/01/10 18:28:23
>>362
pthread_mutex_t はただのデータだから、何個作っても
そのプロセスのメモリ以外の資源は使わない
367:デフォルトの名無しさん
09/01/11 00:54:05
連結リストをCAS使って実装するときのお手本ってありますか?
368:デフォルトの名無しさん
09/01/11 01:04:19
>>367
URLリンク(www.cs.rochester.edu)
369:デフォルトの名無しさん
09/01/11 01:14:01
双方向は無いのか........................
370:デフォルトの名無しさん
09/01/11 01:50:26
双方向でできると思ってんのかっ
371:デフォルトの名無しさん
09/01/19 00:40:02
rw_lockAPIが存在する環境で
同じrw_lock変数を以下のような構造で使うのって
問題ないでしょうか。
func()
{
rw_lock(read)
if 条件{
rw_lock(write)
rw_unlock(write)
}
rw_unlock(read)
}
372:デフォルトの名無しさん
09/01/19 02:34:03
オレオレOSのオレオレrw_lock APIなら大丈夫だけど?
373:デフォルトの名無しさん
09/01/19 13:24:35
実装次第だが、普通に考えるとデッドロックするな
374:デフォルトの名無しさん
09/01/19 21:32:54
r_lock 確保してるんだから if の中の w_lock が取れないだろjk
375:デフォルトの名無しさん
09/01/20 06:28:27
なぜrでロックしないといけないのかわからんけど、条件に関わるのか?
376:デフォルトの名無しさん
09/01/20 11:21:30
>>375
このパターン自体は典型的なケースだろ
APIによっては、ReaderとWriterの他に「Writerに変更可能なReader」が用意されていることもある
377:デフォルトの名無しさん
09/01/27 16:00:09
WindowsでCreateThread中Cランタイムに含まれる関数を使うとリークを起こすとありますが、
普段からCreateThreadは使わずbeginthreadを使ったほうがいいんですか?
完全にCランタイム使わずってのも面倒だし、内部で使ってる関数があるかもしれない
そういうことまで考えてあえてCreateThreadを使うメリットはあるのでしょうか?
378:デフォルトの名無しさん
09/01/27 16:06:34
軽い
379:デフォルトの名無しさん
09/01/27 16:14:38
ない
380:デフォルトの名無しさん
09/01/27 17:56:15
_beginthreadexでおk
381:デフォルトの名無しさん
09/01/28 14:15:26
ないな
382:デフォルトの名無しさん
09/02/01 13:59:30
pthreadでmutexで
再起ロックする場合と
依存関係をハッキリさせてスレッドIDとFAST_MUTEXで判別
どっちが高速ですか?
383:デフォルトの名無しさん
09/02/01 15:33:29
後者。
以前計測したことがある。
ただし、依存関係の洗い出し作業がとても大変だった。
デッドロックに直結するから、とても気をつけないといけない。
要求性能がシビアだったから後者で仕事のためにやったけど、趣味ならば前者をお薦めする。
排他制御がボトルネックになるようなら、前者で実装すればいい。
俺の場合は、本当に特殊で制限が厳しかったから前者でやっただけ。
384:デフォルトの名無しさん
09/02/01 15:35:13
×排他制御がボトルネックになるようなら、前者で実装すればいい。
○排他制御がボトルネックになってから、後者で実装すればいい。
385:デフォルトの名無しさん
09/02/01 15:38:02
FAST_MUTEXって何?
386:383
09/02/01 16:18:24
色々ぐだぐだだな。
お家で寝たいよ。
387:デフォルトの名無しさん
09/02/01 23:25:11
struct hoge{
int var
pthread_mutex_t m;
struct hoge * next;
};
こんな構造体あって
while(h){
pthread_mutex_lock(h->m);
h->var++;
pthread_mutex_unlock(h->m);
h = h->next;
}
こんな風にリンクリストを舐める前後を排他して
舐めていくという処理は正しいでしょうか?
388:デフォルトの名無しさん
09/02/01 23:54:31
加算をアトミックにしたいなら正しいんじゃない。
389:デフォルトの名無しさん
09/02/02 00:06:27
>>388
では、これもレースコンディション無く
検索可能ですかね?
struct hoge{
int var;
int id;
pthread_mutex_t m;
struct hoge * next;
};
void search(id)
{
while(h){
pthread_mutex_lock(h->m);
if( h->id == id){
h->var++;
pthread_mutex_unlock(h->m);
return;
}
pthread_mutex_unlock(h->m);
h = h->next;
}
}
390:デフォルトの名無しさん
09/02/09 14:04:10
shared_ptrで管理するオブジェクトAをスレッドXに渡し、スレッドXからdllを呼んで、dll内でオブジェクトAのメモリを確保する、
ということをしたいのですが、以下のコードでjoin終了時、shared_ptr<A>の解放処理のところで例外が発生します。
どういった理由が考えられるでしょうか?
マルチスレッドでもdllを使わなければ問題なし、dllを使ってもマルチスレッドにしなければ問題なしでした。
struct A {}; // スレッドXにshared_ptrで渡されるデータ
typedef void (__cdecl* DllFunc)(std::tr1::shared_ptr<A>& a); // スレッドから呼ばれるDLL
struct X { // boost::threadに渡すスレッドオブジェクト
std::tr1::shared_ptr<A> a_;
X(std::tr1::shared_ptr<A> a) : a_(a) {} // DLLに渡すデータ
void operator()(void) { // スレッド実行時に呼ばれる関数
HMODULE handle = LoadLibrary(L"dll_func.dll");
DllFunc dll_func = (DllFunc)GetProcAddress(handle, "dll_func");
dll_func(a_);
FreeLibrary(handle);
c.notify_one();
}
};
int main(int argc, char** argv) {
std::tr1::shared_ptr<A> a(new A);
std::tr1::shared_ptr<X> x(new X(a));
boost::thread th(*x);
th.join(); // ここで例外発生
}
<dll_func.cpp>
BOOL WINAPI DllMain (HINSTANCE hinstDll, DWORD fdwReason, LPVOID lpvReserved) { return TRUE; }
extern "C" __declspec(dllexport) void __cdecl dll_func(shared_ptr<A>& a) { a.reset(new A); // これがなければ大丈夫 }
391:デフォルトの名無しさん
09/02/09 15:33:18
よりによってここに書くか。すれ違いだWin32スレ行け。
DLLの勉強一からやりなおせ。
最初から全コードのせときゃもっと早く回答ついたんだろうが、ウザイからオシエネ。
392:デフォルトの名無しさん
09/02/09 16:58:44
DLL内でnewしたのをEXE内で解放したらエラー出るんじゃない?
そもそもshared_ptrだって内部で参照カウント用にnewしてるからDLLじゃ使えない気がするなー。
393:392
09/02/09 17:02:58
スレッドは全然関係ないね。うん。
394:デフォルトの名無しさん
09/02/10 05:13:43
>>390
たぶんこれだけで死ねる。
std::tr1::shared_ptr<A> a(new A);
X(a)();
395:デフォルトの名無しさん
09/02/10 21:54:55
DLLか・・・COMについて調べたほうがいいんじゃないですかね
いろいろヒントあるよ
396:デフォルトの名無しさん
09/02/14 15:33:17
shared_ptr使ってるくせにdeleter知らないとか
397:デフォルトの名無しさん
09/02/19 23:31:28
>>288
Windows Xp home SP3 で自作のTCPサーバ運用してるけど、インバウンド接続の
同時接続数の制限が10ってことはないよ。
今モニタ見ても20人くらい繋がってる。
p2pがすごい数でつながってるだろうし
この件についてはいろいろなひとがよく確かめずにいろいろ書いてる。
自分でちょっとやってみればすぐわかる。
398:デフォルトの名無しさん
09/02/19 23:33:34
>>397
実装はともかくライセンスで制限されてるはず
399:デフォルトの名無しさん
09/02/19 23:37:37
そうなんだよね。 使わないでくれという約束で みんな破って使ってるわけだ。
400:デフォルトの名無しさん
09/02/19 23:46:20
SQLだったかで試してたときにイベントログに制限されたメッセージが
出たことある。あとShare動かしてる時とか頻繁に出る気がする。
単純にセッションの制限では無かった筈。
401:デフォルトの名無しさん
09/02/20 00:12:50
MS製のサーバは独自に制限した実装 IISじゃなくてPWSだっけ
WMEとかはレジストリいじって50人くらいつないだりしてたな。
402:デフォルトの名無しさん
09/02/20 02:13:42
それとは別に、セキュリティ的な話で、
SYN_SENTなソケットをシステム全体で
10くらいしか持てないって制限もあったはず。
403:デフォルトの名無しさん
09/02/22 19:23:55
初心者な質問ですが、
Thread A Thread B
for(;;) for(;;)
printf("AAA\n"); printf("BBB\n");
という処理を行うと、AAA行とBBB行が入り乱れて表示されるんですが、
AABABB\n\n などと表示されることはありえないんでしょうか。
環境はWindows XPで、VC++2008EEでプログラムを書いてます。
404:デフォルトの名無しさん
09/02/22 19:36:03
>>403
ここらへんに何か書いてあるんじゃねーの?
URLリンク(msdn.microsoft.com)
405:デフォルトの名無しさん
09/02/23 04:04:56
>>403
バッファリング
406:デフォルトの名無しさん
09/02/23 21:19:24
スレッドに別のスレッドから信号を送って途中で処理をキャンセルしたいのですが、
現状、以下のようにしています。
void run() { // スレッド実行部
for () { // 長いループ
...処理...
if (check()) return; // 処理をキャンセル
}
}
check()でキャンセルのフラグをチェックし、このフラグを別のスレッドから書き換えるという方法です。
でもこの方法だとループ内の処理が重くなったときにキャンセル操作に対する反応も遅くなってしまうため
どうしたものかと悩んでます。
スレッド内でタイマーのようなものを発行して、定期的にcancel()のチェックをするといった方法はできないでしょうか?
環境はVC9です。
407:デフォルトの名無しさん
09/02/23 22:47:56
>>406
別スレッドから強制停止するとリソースリークの元だよ。
if (check()) return; // 処理をキャンセル
を重い処理の途中に幾つか入れる方がまし。
408:406
09/02/23 23:51:22
>>407
> を重い処理の途中に幾つか入れる方がまし。
どうも。やっぱりこういう単純な方法しかないですか。
重い処理を別スレッドで行わせながら
キャンセル操作の反応がよい安全な方法ってのはないんでしょうか。
cancel()を挿入しまくるというのもなんだかスマートじゃないなぁ・・・。
409:デフォルトの名無しさん
09/02/24 00:50:35
非同期に飛ばされるぐらいならコードが汚くなる方が良い
と思うのは俺だけじゃないよな?
410:デフォルトの名無しさん
09/02/24 01:12:42
その重い処理ってのがなんなのか
スマートとか言うならその重い処理をスマートに分割すりゃいいじゃない
どうしてもチェックしまくりたくないっていうなら処理を持ってるクラスのインスタンスを急にnullにしてやって
例外捕らえて終了してしまえ、最悪だけど
411:デフォルトの名無しさん
09/02/24 01:40:59
別プロセスにして殺すってのは?
結局そういうのって要求されるキャンセル応答時間次第。
人間相手ならmsecオーダでおkでしょ。
きっとループ1回につき1msecもかからないのでは?
412:デフォルトの名無しさん
09/02/24 01:51:03
ワーカースレッド2つ以上用意にして
対処すればよくね?
複数個のスレッドでビジー状態になるなら
その処理内容そのものを分割しタスク化した方がいい
413:デフォルトの名無しさん
09/02/24 02:50:07
違う質問スレで質問した後でこちらを見つけたので一応こちらでも・・・
CreateThread関数で第三引数をクラスのメンバ関数にしたい場合は
どういう記述をすればいいのか教えてください
よろしくお願いします
414:468
09/02/24 02:56:15
>>410
>その重い処理ってのがなんなのか
例えば大きなサイズの行列計算や、待ち行列を使った探索問題なんかを想定しています。
問題を分割することはある程度はできるんですが、それはそれで頑張るとして、
それ以外のアプローチははないかなと。
>>411
> 別プロセスにして殺すってのは?
すみません。よくわかりません。
別プロセスならば殺しても元のプロセスに影響がでないという意味でしょうか。
>>410の後半で言ってることに近い
>>412
> ワーカースレッド2つ以上用意にして 対処すればよくね?
同じスレッドオブジェクトをAとBの2つ用意して、
Aが動いてるときにキャンセルしたときはキャンセルしたふりをして
(Aの計算は次のcancel()チェックまで続いてる)、
新規の呼び出しがあったときはBを動かすというイメージですか?これはいけるかも…。
415:468
09/02/24 02:58:01
一部修正
>>410の後半で言ってることに近い
↓
>>410の後半で言ってることに近いですか?
416:デフォルトの名無しさん
09/02/24 07:10:44
>>413
コールバック関数にはstaticなメンバ関数(クラスメソッド)しか使えない。
コールバック関数を使うAPIは大抵ポインタ型の引数を渡せるから、
クラスを使いたいときはそこにthisポインタを渡して使う。
417:デフォルトの名無しさん
09/02/24 08:52:04
>>413
できない
普通の関数作ってその中で呼び出す
418:デフォルトの名無しさん
09/02/24 16:53:09
>>416‐417
ありがとうございます
とりあえず、>>417の方法でやってみます
419:デフォルトの名無しさん
09/02/24 20:52:23
>>414
別プロセスにすると、ターミネートしたときのリソースの開放をOSがやってくれる
ってことではあるまいか。
それはともかく、その長い処理がうまく分割できず、どうしても時間がかかる場合は
汎的には、キャンセルボタンの入力を取得する側(フラグを立てる側ね)で、キャンセルが
押されたからしばらく待てっていうサインをユーザーに与える方が重要な希ガス。
420:デフォルトの名無しさん
09/02/24 21:45:33
別プロセスのほうがクリーンアップの点では簡単&安心だなあ
ただ、多くの情報を受け渡したり、途中で通信が必要だったりすると
しんどいけどな
421:デフォルトの名無しさん
09/02/24 23:05:03
しんどいと言うか、性能の問題がでるかも
422:406
09/02/25 00:45:53
>>419-
なるほど。別プロセスにすることも検討できそうです。
なんとなく雰囲気は分かりました。どうもありがとう。
423:デフォルトの名無しさん
09/02/25 18:38:04
処理毎に別プロセスって、昔の業務アプリみたいだな。っていうか、
今でもVBあたりでそんな開発やってそう。
1画面=1exeファイルで、画面間はsystem()でプロセス呼び出し。
画面フォーム上で入力したデータ等は、ファイルに書き出して渡す。
大抵、exeファイルの名前は全部数字と意味不明なアルファベットで、
メモリ食いまくりで、やたらに遅い。(w
424:デフォルトの名無しさん
09/02/25 19:28:47
大規模なアプリはマルチプロセスの方が開発しやすいね
Windowsの場合は性能的にマルチタスクに向かないけど
425:デフォルトの名無しさん
09/02/25 21:04:19
>>423
unixだとマルチプロセスは多いけどな。
VB6のアプリだとそういう作りになるのは仕方ない。
モジュール分割の手段がCOMしかない。
20画面もあるとロードモジュールが10M超える。
IDEに読み込んだりコンパイルするのにも一苦労。
プロセス間でDBのセッションを引き継げたらマルチプロセスでも軽くなるはずなのだけど、
それも出来ないからDBの接続でどうしても画面遷移が重くなってしまう。
426:425
09/02/26 01:19:09
>>424
マルチスレッドは、スレッド間のメモリ保護機構がないので、他スレッド
による破壊のリスクと引き換えに、高速なデータ共有が可能と思うが?
Windowsがマルチタスクに向かないとか、何を根拠に?
>>425
昔はメインメモリが少なく高価だったという事情もあるし、「unixだと」
という括りはどうかな?
20画面なんて、そんなに大きな規模なプログラムじゃないよね?その程度
の規模で単純にVBのソースだけなら、10MBを超えるようなことはないの
では?
確かにVB6当時のハード環境(Pentium 300MHz~1GHz, メモリ64MB程度?)
でのビルドは遅かったかもしれないが、VBはVCよりは速かった様に記憶
しているけど?
それと、プロセス間でDBのセッションを引き継げないのは、VBや、Windows
に限定された話ではないのでは?
極端に処理が遅い業務アプリは、データベースの設計自体に問題があり、
無駄にDB間でレコードをコピーしたり、テーブルのリンクが必要だったり
ということが多い気がする。
427:デフォルトの名無しさん
09/02/26 01:55:03
プロセス間のデータ共有なら共有メモリがあるよ
特に親子関係があれば、mmap ANON とかでお手軽極楽
スレッドのメリットは(スレッド間なら)高速にディスパッチ出来る点だね
heap だろうとなんだろうとメモリは全部共有されるというのは
メリットでもあるけど、デメリットでもあるかな。
バグの原因になりがちだよね
428:デフォルトの名無しさん
09/02/26 03:45:35
構造化されたデータを別プロセスと共有メモリ経由でやりとりするとして
c構造体ならまあなんとかなるんだが(いやそれでも大変だが)
c++クラスだとすんごいやりにくい
何かウマい方法あります?
受け渡し用にクラス作るのもアホらしいし・・・
変態的テンプレートでなんとかなるもんだろうか
それとも単なる通信バッファとしてしか使わない?
429:デフォルトの名無しさん
09/02/26 03:52:42
C++ならCの構造体も使えるんじゃ…。
430:デフォルトの名無しさん
09/02/26 04:07:16
そういうのはソケット使って単純化してる。
プロセス間共有メモリは後で環境や仕様が変わったときに
変更が大変だし流用も難しい。バグも入りやすい。
パフォーマンスを上げたいとか、よっぽどの理由でも
ない限り使われないんじゃないかな。
スレッドと違って>>428の言うデメリットもあるし。
ウマい方法はありません。
431:デフォルトの名無しさん
09/02/26 04:53:41
>>426
酷いミスリードだな。>424はマルチプロセスによるマルチタスクという技法がWindows向けでないと言っているように見えるが。
432:デフォルトの名無しさん
09/02/26 04:59:25
IE8はマルチプロセスですぜ
433:デフォルトの名無しさん
09/02/26 05:49:22
>>426
お前は誰なんだ
434:デフォルトの名無しさん
09/02/26 06:45:39
unixといえば今でもパイプをfork/execで分け合ってというイメージが強いな。
DBのコネクションは知らないがファイルハンドルならプロセス間で受け渡せる。
Windowsにもハンドルを複製して子プロセスに渡すオプションはあるのだが、
OS/2やNTは最初からスレッドをサポートしてたのであまり使われない。
435:426
09/02/26 17:42:01
>>425
ハンドルの複製に失敗しますた。orz 426=423です。
>>431
未だにWindowsがunixに劣っていると思っている原理主義者か、TRON房かも。
何を以ってunixを定義しているのか聞いてみたい。
>>434
ハンドルをコピーしたりは、MS-DOSにもあったかな。INT 28Hだか忘れたけど、
プリンタスプーラ用の割込使えば、一応擬似マルチタスクで一部のシステム
コールを呼べた。
デュアルコアやクァッドコアのCPUだと、マルチスレッド化すると理論上
2倍や4倍で動くと勘違いしているヤツもたまにいるよね。おまえのOSは
いったいいくつプロセスが動いていると思っているんだと、小一時間。(略
436:デフォルトの名無しさん
09/02/26 18:11:07
WindowsがUNIXより優れてると思い込んでるなら
まずはその幻想をぶち壊す!
437:デフォルトの名無しさん
09/02/26 18:40:58
>>436
上条さん乙。
つか、んな事誰も言ってないから。
438:デフォルトの名無しさん
09/02/26 23:22:19
マルチスレッドスレでマルチプロセス云々言ってる時に何の前提もなく
「マルチタスク」なんて言う奴は普通にスルーでいいと思うんだけど...
439:デフォルトの名無しさん
09/02/26 23:47:59
よ~し、おじさんもマルチプログラミングとかタイムシェアリングとかの古語を持ち出しちゃうぞ。
440:デフォルトの名無しさん
09/02/26 23:51:02
>>435
実質、4coreXeonのシステムだとOpenMPで4スレッドにして3.9倍速くなるけどね。
逆に、>435のCPUはOSをアイドル状態で動かすだけでどんだけ負荷喰ってるんだって話だな。
441:426
09/02/27 10:22:04
>>440
スレッドでどんなコードを走らせているか知らないけど、スレッド内で
アクセスするデータもコードも、CPU内のキャッシュに収まるくらい
小さなプログラムでもない限り、そういう結果はまずありえないと思うな。
それとも脳内キャッシュ?
442:426
09/02/27 10:43:15
非同期I/Oを使わずスレッド内でファイルI/O待ちしているとか、ネット
ワーク物理層の帯域幅に比べて通信速度が遅く、スレッド化でマルチ
セッション化できるといった、ある意味冗長な造りのプログラムなら
ありえるね。
OSのアイドル状態を持ち出すあたり、他に何個のプロセスがいつ走って
いるか考えていないのかな?(w
443:デフォルトの名無しさん
09/02/27 10:43:58
>>441
OpenMP知らないなら黙っていた方がいいと思うよ。
444:デフォルトの名無しさん
09/02/27 10:45:51
>>443
3.9倍早くなるって
作ったプログラム全体?それとも特定の処理に
限定された内容?どっちなの?
445:443
09/02/27 11:04:31
>>444
私に聞くなw
恐らく演算に集中している部分じゃないの?
MKLなんかは大き目のデータのFFTでそれくらいのリニアリティを叩き出すから。
446:デフォルトの名無しさん
09/02/27 13:15:48
embarrassingly parallel なワークロードならそれくらい行ってもおかしくない
でも大抵の処理は並列化不可能な部分が無視できない量存在してて、
アムダールの法則でもって高速化の限界が簡単に見えてしまうと思うよ
447:デフォルトの名無しさん
09/02/27 13:58:29
>>436
コンシューマー相手のソフトウェアのパッケージ販売の観点からは
明らかに優れている。全然スレ違いだが。
448:デフォルトの名無しさん
09/02/27 19:47:19
>>443
OpenMP に期待しすぎ。
何でもかんでも 3.9倍になる魔法なら俺も欲しいが。(w
449:デフォルトの名無しさん
09/02/28 02:39:25
>デュアルコアやクァッドコアのCPUだと、マルチスレッド化すると理論上
>2倍や4倍で動くと勘違いしているヤツもたまにいるよね。おまえのOSは
>いったいいくつプロセスが動いていると思っているんだと、小一時間。(略
略とか言われても。誰か解読してあげてよ。
少なくとも実測で3.9倍でてるわけだから、理論上は4倍出ると言っても問題ないよな。
たくさんのプロセスが動いてるとき、マルチコアだとちゃんと速くなるよな。
意味不明。
450:デフォルトの名無しさん
09/02/28 03:13:14
どういう問題を解いて3.9倍なのか書かないと意味がないかと。
知人の計算屋さんがAMDの8CPU機にメモリしこたま積んで
巨大グラフを相手にした問題を解いていたことがありましたが、
問題の構造上メモリアクセスに局所性が全くないのでCPUの
速度や数以前にメモリ帯域が飽和して速度が頭打ちになると
ぼやいていた事が。
451:デフォルトの名無しさん
09/02/28 14:17:04
>>450
まあその辺に桁違いのコストを掛けてクリアしてることが
スパコンの存在意義だしね
452:443
09/02/28 16:53:30
>>448
期待するも何も、実験した結果だし。
>>450
>445に書いた通り、只管FFTを計算するようなプログラムと言うくらい。
その結果では、4core2cpuのシステムで、4並列まではびっくりするほどリニアリティがあるけど、
その先は一つ増やしても0.7個分くらいしかパフォーマンスが上がらなかった記憶が。
# 8並列で7倍くらいかな? 必要なら記録を探してくるけど。
尤も、自作のプログラムだと4並列でも8並列でも殆ど変わらなくて泣けた罠。
インテル某氏の話だと、MKLはOpenMPで並列化してもリニアリティを確保できるように
作られているそうで、折角FFTを使わない版を作ったのにお蔵入りになりそうだったり。
453:デフォルトの名無しさん
09/02/28 16:55:08
スパコンと言えばTOP500で10位にWin鯖クラスタが付けてたけど
(CPUとメモリだけ)似たような構成の他のと比べて特に劣ってるようでも秀でてるようでもなかった
454:デフォルトの名無しさん
09/02/28 18:46:09
>>452
OpenMP に頼って満足してる人はこのスレに用はないでしょ。
どうぞお引取りください。
455:デフォルトの名無しさん
09/02/28 19:01:43
>>454
>452じゃないけどここはマルチスレッド全般でしょ?
>1にも「OS・言語・環境は問わない」って書いてるんだからいいと思うけど
ただし>452=443=440はおバカさんだと思うけどねw
456:デフォルトの名無しさん
09/02/28 21:22:08
OpenMP の話題がまずいと言ってるわけじゃなくて、「OpenMP
に頼って満足してる人」って書いてあるんだが...。
スレタイに「相談室」って書いてあるのが見えませんか?
457:デフォルトの名無しさん
09/02/28 21:41:20
>>456
相談した人にOpenMPに頼って満足してるってレスするのは問題ないだろ
458:デフォルトの名無しさん
09/02/28 22:04:33
で、どこに相談した人がいるんだ? (w
459:デフォルトの名無しさん
09/02/28 22:09:48
俺は>452個人の話はしてないんだが。お前誰と闘ってるんだ?
460:452
09/02/28 22:13:07
まぁ、私は「OpenMPに頼って満足してる」のではなく、「OpenMPを巧く使うMKLに勝てなくて泣いてる」のだけれどねw
461:デフォルトの名無しさん
09/02/28 22:13:48
よくわからないけど、置いときますね。
#light
open System.Threading
let tid = fun () -> Thread.CurrentThread.ManagedThreadId
let sleep = fun (t:int) -> System.Threading.Thread.Sleep t
let x1() = [|1..100|] |> Array.map(fun x -> sleep(100); [|x ; tid()|])
let x2 = [|1..100|] |> Array.map(fun x -> async { sleep(100); return [|x ; tid()|] } ) |> Async.Parallel
let _ = printfn "%A" (x1()); printfn "%A" (Async.Run x2)
462:デフォルトの名無しさん
09/02/28 22:35:01
>>450
おれは、>>452 個人の話をしてるんですけど。
まさか、>>454 に書いてあるアンカーすら見えなくなるほど
頭に血が上ってるとか? (w
463:デフォルトの名無しさん
09/02/28 22:48:56
>>462
俺は「OpenMPに頼って満足してる」のを理由に追い出そうとしたことに
ついて話をしている。>>452個人のことはどうでもいい。
どうやらただの煽りあいになりそうだからこの話題は終了する。
464:デフォルトの名無しさん
09/03/01 02:32:16
>>460
何故勝てなくて泣く必要があるのか少し気になる。
465:デフォルトの名無しさん
09/03/01 16:47:46
>>463
「相談した人もいないのに勝手に OpenMP に頼って満足してる人」は
このスレに用はないでしょ。
これでいいか?
> >>452個人のことはどうでもいい。
# >>452 にレスしてるのに、勝手に割り込んできて逆切れかよ...
466:デフォルトの名無しさん
09/03/01 18:49:02
OpenMPってどんなの?たとえば、Videoのエンコード・デコード
処理が書いてある逐次処理のCなりC++のソースコードが
あったら、ほとんど変更なしに並列化できるん?
それとも、既存のソースは一から書き直しくらいしないと
パフォーマンスは出ない?
467:デフォルトの名無しさん
09/03/01 18:53:11
相談者が現れたので>>452の出番ですwww
468:デフォルトの名無しさん
09/03/01 18:55:20
それ以前に446にふさわしい言葉は「ググれカス」だろう。
469:デフォルトの名無しさん
09/03/01 19:14:45
>>466
OpenMPスレという物もあってだな(ry
470:デフォルトの名無しさん
09/03/02 02:02:51
OpenMP詳細しらんが、既存のソースは1から書き直しまで
いかなくても、大幅に書き直さないとパフォーマンスは
でないのだろうな。常識的に考えて。
コア数に応じてリニアにパフォーマンスがあがって、既存
のソースから簡単に移行できますよ、っつーなら神なのだが。
471:デフォルトの名無しさん
09/03/02 02:35:03
それを可能にするには関数型など副作用のない言語が有利
今更言うことでもないが
472:デフォルトの名無しさん
09/03/02 02:38:08
>>471
んなこたーわかってんだよ。新規にはじめる分野はそれでもえーよ。
資産の移行も重要なんだよ。
473:デフォルトの名無しさん
09/03/02 02:42:00
おまえの書いたコードなんぞ資産と呼ぶ価値も移行する価値も無いから気にすんな
474:デフォルトの名無しさん
09/03/02 02:46:42
>>473
俺の書いたコードが資産だなんて、いついったんだよ?
煽るにしろ、頭の悪さが透けてるんだよ。
475:デフォルトの名無しさん
09/03/02 03:08:36
>>472の「おまえ」が>>474だなんて、いついったんだよ?
煽るにしろ、頭の悪さが透けてるんだよ。
476:デフォルトの名無しさん
09/03/02 11:59:03
これは惨めなミス。
477:デフォルトの名無しさん
09/03/02 13:39:15
>デュアルコアやクァッドコアのCPUだと、マルチスレッド化すると理論上
>2倍や4倍で動くと勘違いしているヤツもたまにいるよね。おまえのOSは
>いったいいくつプロセスが動いていると思っているんだと、小一時間。(略
478:デフォルトの名無しさん
09/03/02 23:44:21
>>477
こいつの言ってることまじでわからんのだが・・・。
こいつがアフォなのか、俺がアフォなのか誰か解説よろしく!
479:デフォルトの名無しさん
09/03/03 00:03:02
コア1 ●◎◎◎◎◎◎◎◎◎
コア2 ●○○○○○○○○○
コア3 ●○○○○○○○○○
コア4 ●○○○○○○○○○
↓
コア1 ●◎◎◎◎◎◎◎◎◎
コア2 ●◎◎◎◎◎◎◎◎◎
コア3 ●◎◎◎◎◎◎◎◎◎
コア4 ●◎◎◎◎◎◎◎◎◎
○ 空き
● 別プロセス
◎ 自プロセス
4倍になる
480:デフォルトの名無しさん
09/03/03 00:28:55
>>477
基本的には>>477がちょっとずれていると思う。
コア数に比例してリニアに2倍4倍にならないのは事実。
でもハウスキーピングなプロセスの数云々は性能を押し下げる
理由としてはどちらかというとマイナーな部類だと思う。
481:デフォルトの名無しさん
09/03/03 00:29:19
ちょっとゲロでちゃった
482:デフォルトの名無しさん
09/03/03 00:35:18
並列化効率の話がまず最初だよね。
アムダールの法則。
483:デフォルトの名無しさん
09/03/03 00:38:03
>>480
いや、こうまで単純化していいかどうかわからんが、
ハウスキーピングのプロセスがほぼsleep状態と
仮定したら無視できるわけで。
というより、4コア100%使用する処理走らせるんだったら、
無視できるほどなわけで(スワップデーモンとか
ハードアクセスの重いスレッドが走らない前提なら)。
バスネックでリニアに伸びないとか、キャッシュの競合
だとかいうならまだしも。やっぱり俺には>>477はさっぱ
りわからん。
484:デフォルトの名無しさん
09/03/03 01:50:33
アイドル状態のプロセスでもビジーループでCPU消費してる
とか思ってんじゃないの
485:デフォルトの名無しさん
09/03/03 01:56:06
>>484
単に1つのプロセスが1コアを占有し続けると考えているのではあるまいか。
486:デフォルトの名無しさん
09/03/14 05:22:42
マルチスレッドについて質問です。
環境は VC++2005 SDK です。
子ウィンドウの WM_CREATE にて無限ループをさせても
親ウィンドウが操作できる
事を実現したいです。
他スレにて、
>Windowsのウィンドウはスレッドに属する。
>ウィンドウプロシージャはウィンドウの属するスレッドで実行される。
>さて、どのスレッドに属するかというと、CreateWindow(Ex)を呼んだスレッド。
というレスをいただき、新しいスレッドにてCreateWindow する手段を取りました。
子ウィンドウの WM_CREATE までは処理が進むのですが、
無限ループどころか for (i=0; i<100; i++) { i = i; } を WM_CREATE 内に
記述した途端にフリーズする様になってしまいました。
コメントアウトすれば、問題なく動作します。
ファイルをアップロードしたので、見ていただけないでしょうか?
URLリンク(www3.uploda.org)
受信パスは test です。
どのように修正すれば良いか、ご教授願います。
よろしくお願いします。
487:デフォルトの名無しさん
09/03/14 05:54:15
>>486
windowsのウィンドは、プライマリスレッドで生成しないと
いろいろいろいろいろいろいろいろトラブルが起こるので、そういう設計は見直した方がいい。
そもそも子ウィンドウは親ウィンドウと同じスレッドで生成しないとトラブルになる。
例えば親をAスレッドが、子をBスレッドが作ったりすると、
親のプロシージャはAスレッドが実行し、子のプロシージャはBスレッドが実行することになる。
子から親への通知や親から子への通知がメッセージで発生したら発生したら、
デッドロックの宝庫になることは想像に難くない。
それ以前にメッセージループって親子で共通のような気が・・・
488:デフォルトの名無しさん
09/03/14 06:05:38
>>486
アップロードしたプログラムだとそもそも子ウインドウは表示されないだろ。
動くようにするには子ウインドウと呼んでいるものを、新しいスレッドのウインドウにすること。
つまりメッセージループをそこでまわす。
MSG msg;
ShowWindow(hChild, SW_SHOWDEFAULT);
UpdateWindow(hChild);
while(GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
//static int k = 0;
//k = 1;
//while (1)
// k++;
489:デフォルトの名無しさん
09/03/14 06:16:38
WM_CREATEで無限ループしたらCreateWindowから制御が戻らないわけだが
490:486
09/03/14 15:00:34
>>487
色々と問題があるという事ですか...
そこまでは考えておりませんでした。
ですが、今はこの枠組みで作ろうと思います。
アドバイスありがとうございます。
>>488
メッセージのループを回すのを忘れておりました。
ありがとうございます。
ただ、今回はメッセージのループのみが欲しいので
ウィンドウは非常時で構いません。
>>489
確かにそうでした。
あるメッセージを受けた時に
その中で Sleep(1000); を実行する事にしました。
・・・が、それでも親ウィンドウが 1000 ミリ秒 固まってしまいました。
以下の様にしておりますが、
これでは各ウィンドウは別スレッドで動かないのでしょうか?
URLリンク(www2.uploda.org)
受信パスは test です。
よろしくお願いします。
491:デフォルトの名無しさん
09/03/14 15:07:12
作ろうと思います、じゃねー
動作が未定義なんだからそんなプログラミングすんな
492:デフォルトの名無しさん
09/03/14 15:18:07
>>491
互いのウィンドウでメッセージのやり取りを頻繁にするような事は致しません。
親スレッドとは独立したウィンドウプロシージャのメッセージループ
(表現が合っているかは自信がありませんが)が欲しいのです。
以下、長文失礼します。
5 [msec] の情報が入るサイズのバッファを複数用意し
信号をバッファに入力し、あるバッファが満タンになったら
windows からメッセージが投げられ、
受け取ったメッセージ内で信号処理をする、
というものを作っています。
この時、信号処理に時間がかかるため
常にメッセージを受け取った時の処理を行ってしまい
メニュー操作が出来なくなる状態です。
アプリケーションを強制終了すると、信号処理した数値列が
ちゃんとファイル出力されているので
信号の入力及び信号処理は問題なく進んでいます。
これを解決するにはメニューを持つウィンドウと
メッセージループのあるウィンドウを別スレッドで走らせれば良い
と考えました。
493:492
09/03/14 15:53:32
連稿失礼します。
Sleep(1000); を
int i, j;
for (i=0, j=0; i<1000000000; i++)
j++;
としてみましたが、結果は同じでした。
親ウィンドウのスレッドにフォーカスが戻っていないのでしょうか?
494:デフォルトの名無しさん
09/03/14 16:43:47
子ウィンドウ作る必要なんて無いところを、
わざわざ回りくどいやり方しているようにしか思えないんだけど。
ワーカースレッドにデータ送りたいだけじゃないの?
495:デフォルトの名無しさん
09/03/14 18:10:18
>>494
ワーカースレッドについて知識が無かったのでググってみました。
MFCでのみ使用可能な関数でしか作れない事が判りました。
今はSDKで組んでおり、MFCは使った事が無いので今の私には使えそうにありません。
情報ありがとうございました。
496:デフォルトの名無しさん
09/03/14 18:28:36
>>495
ワーカースレッドは概念であって、SDKのみだから作れないということは無いよ
そもそも、貴方のやろうとしていること自体がワーカースレッドの利用だ
497:デフォルトの名無しさん
09/03/15 15:23:44
>>496
ワーカースレッドについて調べ方が間違っていたようです。
もっと調べを進めます。ありがとうございます。
498:デフォルトの名無しさん
09/03/15 20:09:14
>>492
ワーカースレッドというのは、作業を行うスレッドという程度の意味です。
信号処理中はGUIが不要のようですので、GUIは1個のスレッドにまとめて下さい。
以下、基本は次のような処理になります。Q0とQ1のアクセスを排他制御して下さい。
プライマリスレッド
メインウィンドウの作成。
バッファ群を作成する。例えば5ms用のバッファをN個作成して、
2個のキューQ0(未使用バッファ用)とQ1(充填済みバッファ用)を作成する
バッファを全てQ0に格納し、スレッドA・Bを作成・実行する。
以降はGUIによるスレッドA・Bのコントロールを行う
スレッドA(バッファ充填処理)
1.信号受信処理の初期化
2.Q0からバッファを取り出す。無ければ待つ。
3.バッファを充填する処理(この辺で外部からのスレッド終了通知チェック)
4.バッファが一杯になったらQ1へ入れ、2へ戻る
スレッドB(信号処理スレッド)
#スレッドAで、Q1の格納数が0->1になったとき起こされる。
1.Q1からバッファを取り出す(なければ待つ)
2.信号処理(この辺で外部からのスレッド終了通知チェック)
3.結果の出力
4.バッファをQ0へ入れ、1へ戻る
499:デフォルトの名無しさん
09/03/15 20:18:36
>>498
あー便所で説明してくれないと解らない
500:デフォルトの名無しさん
09/03/15 20:42:55
>>499
ウホッいい男!
501:492
09/03/15 20:45:19
>>498
詳しい構成、本当にありがとうございます。
頑張って理解してみます。
502:デフォルトの名無しさん
09/03/27 03:19:19
void A::sync_fun() {
boost::mutex::scoped_lock lock(m_);
// 何かの処理
}
上のlockで待機しているスレッドがあるときにAのオブジェクトをdeleteするとスレッドは待機したままですね。
下のようにするかtimed_waitにする必要があるのか、そこまで気にすることもないのか。
みなさんはどうされますか?
void A::sync_fun() {
boost::mutex::scoped_lock lock(m_);
cond_.wait(lock, bind(&A::pred, this));
if (invalid_) return;
// 何かの処理
}
bool A::pred() const { return stat_ || invalid_; }
A::~A() throw() {
{
boost::mutex::scoped_lock lock(m_);
invalid_ = true;
}
cond_.notify_all();
}
503:デフォルトの名無しさん
09/03/28 18:55:17
>>502
どうするかは、何のクラスかによるだろう。
一般論でAが、sync_fun()実行中に破棄される可能性があって、
どうしても回避できないならAのデストラクタでunlockする。
504:デフォルトの名無しさん
09/04/04 16:12:48
ダウンローダをマルチスレッドで作成しようと思っているのですが
スレッドを10個作り
それぞれにURLを追加して、次々にダウンロードさせる仕様にしようかと思っていますが
このスレッドの終了タイミングはどういった条件で終了すればいいでしょうか?
メインスレッドが終了するとこの10個のスレッドも終了するので
どうしたものかと考えています
505:デフォルトの名無しさん
09/04/04 16:19:45
あげます
すいません
506:デフォルトの名無しさん
09/04/04 16:20:37
.
507:デフォルトの名無しさん
09/04/04 16:36:26
>>504
何を聞きたいのかよく分からんけど、
メインスレッドで10個のスレッドの
終了待ちさせれば良いんでないの。
508:デフォルトの名無しさん
09/04/04 16:45:56
>>507
なるほど
そういう手がありましたか
ありがとうございました
509:デフォルトの名無しさん
09/04/04 17:26:41
何か一冊マルチスレッドの本読むのおすすめする
510:デフォルトの名無しさん
09/04/05 04:12:53
class Hoge{
public:
void End(){
/*他のスレッド、シグナルハンドラとかから呼ばれる */
Lock_.GetLock(); // 実際はRAII使ってるよ
continuable_ = false;
//その他のリソース会報処理
}
void Task(){
// thread poolから実行されるタスク。
Lock_.GetLock();
if( continuable_ == false ){ return; }
// IO処理とか色々非同期でやる
}
};
なんか、フラグ使ってやるのが嫌なんだけど、
非同期で実行されるオペレーションをキャンセルさせる
スマートな方法ってない他にない?
この実装は間違ってる?
511:デフォルトの名無しさん
09/04/05 11:59:52
いいんじゃねえの。
スレッドを自発的に終了させるには
スレッド自身が何かをチェックしなけりゃならんし。
512:デフォルトの名無しさん
09/04/05 13:17:02
間違ってないし、フラグを使う方法は普通によくある
513:デフォルトの名無しさん
09/04/05 19:31:13
別プロセスにしてkill -9、これが最強。
514:デフォルトの名無しさん
09/04/05 19:36:59
せめてSIGTERMでやんわり殺してやれよ。
515:デフォルトの名無しさん
09/04/06 12:50:48
そうそう、せめて覚悟する時間くらいは与えてあげないと。
尤も、そうすると逆切れして殺しに来るかも試練が。
516:デフォルトの名無しさん
09/04/09 00:33:31
変数か構造体かクラスのインスタンスa,b,c,dがあるとして、
まず、スレッド1がaとbを使用、スレッド2がc,dを使用する。
その後、スレッド間通信とかでスレッド1も2も上のa,b,c,dを使用した処理が完了したことをスレッド1,2に伝える。
そして、スレッド1がa,cを使用、スレッド2がb,dを使用する。
といったような処理をするときに、特別にロックとか必要ですか。
517:デフォルトの名無しさん
09/04/09 00:58:51
>その後、スレッド間通信とかでスレッド1も2も上のa,b,c,dを使用した処理が完了したことをスレッド1,2に伝える。
これで同期取ってるから、そこをちゃんとすればよい。
518:デフォルトの名無しさん
09/04/09 01:47:33
弱い順序付けの場合だめな場合がありえるかもね
519:デフォルトの名無しさん
09/04/09 17:49:21
ねーよw
520:デフォルトの名無しさん
09/04/09 19:12:35
>>518
お前にとって同期ってなんだ?
521:デフォルトの名無しさん
09/04/09 19:52:20
グローバル変数keyに対して、他のスレッドで値を変更してループの続行、終了を決める場合に
while ( key ){ count++; }
というコード書くとコンパイラの最適化によって、無限ループになる可能性があるということですが、
while ( *pk ){ count++; }
のようにアドレスから参照しようとしても同じことになるのでしょうか。
522:デフォルトの名無しさん
09/04/09 20:54:12
わかんない。
つーか key を volatile にすりゃいいんでない?
523:デフォルトの名無しさん
09/04/09 21:01:11
>>521
うん。十分ありえる。
524:デフォルトの名無しさん
09/04/09 21:07:43
volatileで大丈夫そうですね。ありがとうございました。
525:デフォルトの名無しさん
09/04/12 11:51:26
マルチスレッドがどういうタイミングで割り込まれるのかわからないのですが
たとえば、if(++i == n) のコードなら
iをインクリメントしてからnを比較するまでの間で
割り込まれる可能性はあるんでしょうか?
526:デフォルトの名無しさん
09/04/12 12:30:10
あるよ
そもそも正しくインクリメントされることも保証されない
(CPUやコンパイル出力によるけど)
なぜなら、
(1) メモリからiの値を読み出す
(2) 値+1を計算する
(3) iの領域に計算結果を書き込む
という3ステップになる可能性があるから
527:デフォルトの名無しさん
09/04/12 12:43:39
>>526
そのステップ間で割り込まれるんですか、結構分割されるものなんですね
ありがとうございました
528:デフォルトの名無しさん
09/04/12 14:33:39
>>527
ただし、いつもそのように分割されるとは限らない。
529:デフォルトの名無しさん
09/04/13 22:54:34
volatile最強杉www
530:デフォルトの名無しさん
09/04/14 10:18:14
fread等でのデータ読み込みをシングルスレッドで実行する場合と
マルチスレッドで実行し、メインスレッドでは出来るだけ何もしない場合の速度は同程度になるものでしょうか?
531:デフォルトの名無しさん
09/04/14 10:27:26
>>530
速度は実測が基本。
たぶんその比較内容だと、激しく環境(ハードウェア、OS、コンパイラ)に依存する。
532:530
09/04/14 10:57:26
WindowsXP、vc2003、C2D E7200です。
timeGetTimeで測定した所、
マルチスレッド側の速度が安定しないのですが、
100kb程度のデータで2倍、1mb程度だと4割程度の速度差になりました
メインスレッドは以下のようなループになっていています
while(1){
if(PeekMessage(&msg,0,0,0,PM_NOREMOVE)){
TranslateMessage(&msg);
DispatchMessage(&msg);
} else {
// メインスレッド
}
}
533:デフォルトの名無しさん
09/04/14 11:00:25
色々条件がよく判らんが、ここが一番判らん。
>100kb程度のデータで2倍、1mb程度だと4割程度の速度差になりました
2倍の速度差と4割の速度差ってどういう意味なんだか。
シングルスレッドに対してマルチスレッド版は2倍の速度差、つまり3倍所要時間が掛かったのか?
534:530
09/04/14 11:11:23
すみません、
所要時間
シングル マルチ
100kb 0.013秒 0.025秒
1mb 0.100秒 0.140秒
です
535:デフォルトの名無しさん
09/04/14 11:17:22
>>530
マルチスレッドは、複数のことを同時にしたいときに使う技術なので、
そういう視点で選択した方がいいですよ。
ただ速度といっても、プライマリスレッドからストレージアクセスを
しているときキャンセルボタンを押したいんだけどその反応が鈍い、とか、
ストレージをアクセスしながらムービーを表示しているのだけれどコマ落ちする、とか、
単純コピーを速くしたい、では、とるべき手段に違いがありすぎます。
単にあるデータをストレージから読み込む処理だけに着目するなら、シンプルな
シングルスレッドの方が高速になることが多いと思います。
予め別のスレッドで利用するファイルを予測してアクセスし、キャッシュに入れておく
などというのはまた別の問題ですが。
536:530
09/04/14 11:33:30
>>535
ありがとうございます
極力シングルで動作できるような方法考えることにします
537:デフォルトの名無しさん
09/04/19 14:10:04
>>435
Phenomの2コアで2スレッド動かしたら2.2倍以上のスコアを叩き出した。
確かに2倍になる訳じゃないね。但し、配列をL2とL3に合わせて巧く分割
できた場合に限るけど。あと、OSのや他プロセスのボトルネックがある分
やっぱりマルチコアの方が早いね。実質90%でしか動けないシングルは倍
にしても180%だけど、90%+100%で動けるマルチコアだと実質190%で10%
ぐらい早くなる。
538:デフォルトの名無しさん
09/04/19 14:41:22
>>521
別にvolatile使わなくても問題なくね?
static int key=1;
void Thread0()
{
key=0;//volatile指定が無い場合消失する可能性がある。
Sleep(100);
key=1;
}
void Thread1()
{
while ( key ){ count++; }
}
こんな事でもしない限り無限ループにならんべや。
こんなコード書くことまず無いだろ。
それと、そもそも、グローバル変数使うなよ。
539:デフォルトの名無しさん
09/04/19 19:33:59
>>538
バカでしょ
540:デフォルトの名無しさん
09/04/19 22:08:19
>>538
まず、ネタなのかマジなのかを書いてくれ。
541:デフォルトの名無しさん
09/04/19 22:25:33
>>538
バカなの?死ぬの?
542:デフォルトの名無しさん
09/04/19 22:53:09
>>539-541
まじか。何で?
543:デフォルトの名無しさん
09/04/19 23:02:48
volatileを使うと排他制御しなくて
よくなるから必要
544:デフォルトの名無しさん
09/04/19 23:19:55
それは誤り
545:デフォルトの名無しさん
09/04/19 23:50:48
keyをテストする所にメモリバリア入れないと駄目じゃないかね
546:デフォルトの名無しさん
09/04/20 01:29:15
例えばJavaやC#などだと参照してる変数がvolatileだと期待通りに動くが、
そうじゃないとどうなるか分からんのじゃない?
547:デフォルトの名無しさん
09/04/20 15:54:13
>>543
volatileと排他制御はなんの関係もないぞ。
volatileは最適化の抑止で、せいぜい>>538の様な事や
レジスタだけでなくメモリ側にも変数を割り当てるぐらいだ。
そもそも、CやC++に排他制御なんて概念は無いから
クリティカルセクションなんかを使う他無い。
ちなみに、Javaは排他制御がかかるが、グローバル変数
と言っているからCかC++だ。もしかして、間違えてないか?
548:デフォルトの名無しさん
09/04/20 16:04:59
で、>>539-541は、人をバカ呼ばわりしただけの
まっとうな理由あるんでしょうねぇ。まさか、Javaや
C#のvolatileしか知らない癖にバカにしてたなんて
恥ずかしい理由じゃありませんよねぇ当然。
549:デフォルトの名無しさん
09/04/20 16:23:18
|
J
550:デフォルトの名無しさん
09/04/20 19:35:31
【OS】WindowsXP SP3
【言語】C
ソース URLリンク(f50.aaa.livedoor.jp)
↑をcygwinでコンパイルすると
In function `thread_func':
14: warning: assignment makes integer from pointer without a cast
In function `main':
54: warning: passing arg 3 of `pthread_create' from incompatible pointer type
というエラーが出ます。
14行目と54行目が悪いことはわかりますが具体的な原因がわかりません。
ちなみにexeファイルは生成されます。
よろしくお願いします。
551:デフォルトの名無しさん
09/04/20 20:32:51
>>550
4: warning: assignment makes integer from pointer without a cast
In function `main':
キャスト無しじゃ整数をポインタにできないっていうような事書いてあるね。
pthreadのプロトタイプはこんな感じで第3引数には関数ポインタを、第4引数にはvoidポインタを取るように
なってる?
int pthread_create(pthread_t * thread, pthread_attr_t * attr, void * (*start_routine)(void *), void * arg);
君のコードだといずれもdoubleにキャストしているけど何故だい?
pthread_create(&a[i], NULL, (double *)thread_func, (double *)array);
※スレッドなんて飛躍したものに手を出す前にこの手のエラーを自己解決できる
程度には言語機能を勉強し直した方がいい。
552:デフォルトの名無しさん
09/04/20 20:41:56
>>550
んだんだ、
それに、Cなんだから、void * が絡むときはキャストしない方が
素直で、読みやすいコードになる。
たとえば、
double *data = (double *) arg;
は、
double *data = arg;
としろ、ってことね。C++から来た人はこれをやりたがるのね。
C++だとこの場合にもキャストが必要だから。
乱文澄まそ
553:デフォルトの名無しさん
09/04/21 01:49:59
>>551
pthread_create(&a[i], NULL, (double *)thread_func, (double *)array);
は単に見落としていたようです。
お手数掛けて申し訳ないです。
直したらこの行のエラーは出なくなりました。
>>552
C++をやっていたわけではないのですが、配布されたソースコードの例にはこの形で書かれていたのでそれに準じて書きました。
そしてまだ14行目でエラーが出ますがpthread_selfの扱い方はそもそもこれでよいのでしょうか?
ちょろっと調べて出てきたものを使っただけなのでよく理解していません。
554:553
09/04/21 02:06:23
すみません、調べたらわかりました。
ただし他の問題が浮上しました。
pthread_t型をint型か何かに変換できないんですかね・・・。
555:デフォルトの名無しさん
09/04/21 02:31:33
>>554
pthread_tはポインタか構造体かなんかでしょ。
そもそも、別の型に代入しちゃいけない。
語のライブラリだと結構やろうと思えば別の型
に無理やり代入する事も出きるけどしちゃいけない、
内部に干渉しちゃいけないものがある。
大体識別値(discriptor)と呼ばれるものなんかがそう。
あと、初心者の内はメモリ操作が簡単にできる事が解って乱用する
人がいるがポインタのキャストはやたらめったらつかうもんじゃない。
てか、君の悩みはスレッド以前の問題だから、Cの初心者スレなんか
で質問しなさい。
556:デフォルトの名無しさん
09/04/21 20:37:55
言い方は気にくわないなw
小さい芽潰して楽しんでるふうにしかみえねーよ老害
>>554
pthread_tはunsinged longのtypedefだよ
557:デフォルトの名無しさん
09/04/21 21:56:02
>>556
何を言ってるんだおまえは? >>550のwarningを100回読み直してから出直してこい
558:デフォルトの名無しさん
09/04/22 00:05:38
>小さい芽潰して楽しんでるふうにしかみえねーよ老害
ふーん
芽をつぶして楽しんでて害なんだ
ふーん
559:デフォルトの名無しさん
09/04/22 01:49:54
そうなんじゃね、多分。
560:デフォルトの名無しさん
09/04/22 02:46:06
大人なんだからもっと仲良くしろよ
561:デフォルトの名無しさん
09/04/22 21:38:45
歯痛制御で俺の虫歯を何とかしてくれ
562:デフォルトの名無しさん
09/04/22 22:28:22
チュイーン ギキィィーー
563:555
09/04/22 22:56:29
>>556
俺、21歳なんだが。3D関連でC++始めて5年以上にはなるが、
そうか俺も、もう老害か・・・。
564:デフォルトの名無しさん
09/04/23 00:01:02
>>561
本業歯医者の趣味グラマだけど何か用?
565:デフォルトの名無しさん
09/04/23 02:10:25
>>564
医者の趣味グラマっておおいな。
LHAも医者だし猫プロの筆者も医者。
しかも、本業より優秀そうなんだよな・・・。
566:デフォルトの名無しさん
09/04/23 02:33:52
本当は工学系にいきたかったのに、
なまじっか頭いいと医療系への進学を勧められちゃう奴って多いからな
567:デフォルトの名無しさん
09/04/23 09:19:51
いつも思うんだけど、歯科治療技術も日々発展してるだろうから
古い医者より新しいところの方がいいのかねえ
568:デフォルトの名無しさん
09/04/23 11:19:32
ジャストシステムのスタートアップにも医学生がいたな。
人間って本当に不公平にできてるよ。
569:デフォルトの名無しさん
09/04/23 12:48:15
>>564
予約時間の十分前には歯科に着いているのに
待合室で一時間待たされ、診察室に通されたと思ったら
また三十分以上待たされるのを何とかしてくれ
どう見ても歯科医と歯科助手がデッドロックを起こしているようでなかなか回ってこない
570:デフォルトの名無しさん
09/04/23 19:35:34
>>569
誰がうまいこと言えとw
デッドロックは言いえて妙だったわ。
571:デフォルトの名無しさん
09/04/23 23:58:32
>>567
少なくとも、レントゲン撮影したら「現像するから日を改めて」なんてところは止めた方がいい。
今時、治療椅子ごとに端末があってそこで見られるのが当たり前。
572:デフォルトの名無しさん
09/04/24 09:00:21
>>571
端末は無いけど、数分で現像したフィルムができるのが普通じゃない?
2,30年前からそうだったと思うんだけど
573:デフォルトの名無しさん
09/04/24 09:44:28
いい加減にしとけよ
574:デフォルトの名無しさん
09/04/24 11:57:45
マルチスレッドと減増
関係あっても、遠い存在のような
575:デフォルトの名無しさん
09/04/24 17:51:20
>>556
老害ではなく、基地害だ
576:デフォルトの名無しさん
09/05/02 22:30:20
俺の日記帳
今日は5月2日です。
何してるの?
577:デフォルトの名無しさん
09/05/04 23:25:22
C++0xではマルチスレッドプログラムを組むのは
容易になるのであろうか
578:デフォルトの名無しさん
09/05/04 23:26:23
C++でマルチスレッドは危険ですよ
579:デフォルトの名無しさん
09/05/04 23:36:49
>>578
Win32本では平気でマルチスレッド走らせる例が書いてあるけど
デッドロックについても詳しく説明してある
580:デフォルトの名無しさん
09/05/05 04:20:22
>>579
なんだその会話になってないレスは
581:デフォルトの名無しさん
09/05/05 06:50:37
CやC++の言語レベルではマルチスレッドについての取り決めはない。
ライブラリ(pthreadなど)やプラットフォーム(osやハードウェア)や実装(コンパイラ)レベルで、
扱いが決められているので、そういったものの前提抜きでマルチスレッドは語れない。
582:デフォルトの名無しさん
09/05/05 09:33:35
メモリモデルの仮定が入っちゃうからやりにくいだろうなあ
583:デフォルトの名無しさん
09/05/05 09:58:42
>577
concurrency 周りが大幅に強化されてるんで、恐らくは。
584:デフォルトの名無しさん
09/05/09 12:04:34
マルチスレッドにする利点は何?
複数の処理を同時に走らせることができるなんて妄想は無しで。
585:デフォルトの名無しさん
09/05/09 12:10:53
世界の全てが妄想なので、答えは消滅しました。
586:デフォルトの名無しさん
09/05/09 12:12:54
複数の処理を同時に走らせることができる、妄想で無しに。
587:デフォルトの名無しさん
09/05/09 13:11:27
個人的には>>584が何故「複数の処理を同時に走らせることができる」ことが妄想だなんて妄想を抱いたのか知りたい希ガス。
マルチスレッドの利点は全てそこから派生しているはずなのだが。
588:デフォルトの名無しさん
09/05/09 13:25:02
>>587
TSSは同時ではないとでも言いたいんじゃないか?
589:デフォルトの名無しさん
09/05/09 15:05:51
>複数の処理を同時に走らせることができる
ってのはいわゆる手段なんで。
大元の目的は「暇をもてあましてるリソースを有効活用する」だな。
マルチスレッドはCPUがヒマしてる場合の、GPGPUはGPUがヒマしてる場合の手段だな。
>584がどんな妄想してるか迄はわからんが。
590:デフォルトの名無しさん
09/05/09 15:53:09
>>589
それ以外にもあるぞ。むしろプログラマ的にいちばんうれしいのは、コンテキストの異なる処理を明示的な切り替え無しに同居させられることじゃなかろうか。
重い処理を別スレッドでガリガリ処理しつつ、その進行状況をGUIで表示するとか。
591:デフォルトの名無しさん
09/05/09 23:10:29
ハァ?
すべてをファイル・デバイスにしてそれをpollすればシングルスレッドで可能ですが何か?
592:デフォルトの名無しさん
09/05/09 23:20:27
スレタイ無視
593:デフォルトの名無しさん
09/05/09 23:39:00
昔のunixはスレッドなしでもfork/execだけでたいていの事はやれてたな。
594:デフォルトの名無しさん
09/05/10 05:27:53
>>591
ちょっと話違うが、Androidのセンサーまわりの設計もそんな感じ。
だが、そのファイルディスクリプタをもらう元が、1つしかなかったり
してセンサーごとにドライバが作れない。
1.0のころはモジュール化すらされてなかったり、1.5になっても
いまだダセー設計だし。設計したやつの顔が見たいな。
595:デフォルトの名無しさん
09/05/10 08:32:10
ドライバといった低レベルI/O処理の基本はスレッドより割り込み。
割り込みがないディバイスだとポーリングも使うけど。
596:デフォルトの名無しさん
09/05/10 09:07:05
何かの処理で待ちも含めてぐるぐる回りながら、他の処理も同時にやりたい、とかいう場合に
いちいち処理を細切れにしてpollを含むメインループから呼び出す形に縛られるのは面倒だわな。
マジレスすると。
597:デフォルトの名無しさん
09/05/10 10:29:43
>>593
でも今はマルチスレッドがサポートされているということは、その煩雑な方式では力不足だったってことだよね。
598:デフォルトの名無しさん
09/05/10 10:51:01
今のところは、
やることを細切れにできるようにしておいて
pollするスレッド(大半の時間は待機)が
少数のワーカーに仕事を振り分け
ワーカーはひたすら仕事だけを待ちつづける、というやり方が
I/O待ちやマルチCPU(コア)を有効に生かせ、
メモリやコンテキストスイッチのロスも少なく出来ると言われてるな。
599:デフォルトの名無しさん
09/05/10 10:56:07
開発効率という効率を無視すれば、それがベストだねw
600:デフォルトの名無しさん
09/05/10 13:17:08
OSのスケジューラをエミュレートしてるだけのような
601:デフォルトの名無しさん
09/05/10 15:04:43
コア数を大幅に越えるスレッドを生成すると、
コンテキストスイッチのせいでむしろ性能が低下する。ってのは本当なの?
実測して確かめたいんだけど、どういうコードを書けばいいのか解らん。
えろいひと教えて
602:デフォルトの名無しさん
09/05/10 15:07:34
スレッドプールにすりゃ解決よ
603:デフォルトの名無しさん
09/05/10 15:11:52
>>601
本当
スレッドに手を出した頃それに嵌ったことがある
各スレッドの同期にmutex/conditionを使う形で大量のスレッド作って試してみればわかるよ
むやみにスレッド数を多くするのはそもそも設計が良くないです
604:デフォルトの名無しさん
09/05/10 16:01:38
オーバーヘッドが増大する。 スレッドの多さは関係無し。
たとえば1ms以内で終了するスレッドを生成すれば効率悪い。
605:デフォルトの名無しさん
09/05/10 16:02:56
>>601
スレッドって、一般にはコンテキストスイッチが入らない
(だから軽い)というモノだろう?
原理的には性能低下は無い。
但し、実際のところコア間でキャッシュを共有してたり、
メモリバスを共有してるので、複数のコアを同時に使うことで
シングルコアよりも性能低下することはありうる。
606:デフォルトの名無しさん
09/05/10 16:22:26
マルチスレッドのプログラム組んでるんでて
ある変数に複数のスレッドから同時にアクセスできるときは
排他的処理しないとだめ?
というか たぶん今のエラーはそうだろうと思う
607:デフォルトの名無しさん
09/05/10 16:24:10
複数スレッドからアクセスしても、OSがエラーはいたことはないな。
値は、ぶっ壊れるけどね。
608:デフォルトの名無しさん
09/05/10 16:28:00
読むだけなら問題ない
609:デフォルトの名無しさん
09/05/10 16:29:54
読み書きしても、エラーでたことない。
たとえばグローバルsum=0に、複数スレッドから足し算してもエラーで停止しないが。
610:デフォルトの名無しさん
09/05/10 16:31:49
どういった場合に、メモリーエラーが起こるのかが知りたい。
611:デフォルトの名無しさん
09/05/10 16:33:36
>>605
> スレッドって、一般にはコンテキストスイッチが入らない
今コンキストスイッチしないのって絶滅危惧種だろ
612:デフォルトの名無しさん
09/05/10 16:36:05
なるほど
変数がスタックで削除したり追加したりだからダメなのか
613:デフォルトの名無しさん
09/05/10 18:23:53
>>605
マテ、スレッドでもコンテキストスイッチは発生するぞ。
スレッドが(プロセスに比べて)軽いのは、スタックとレジスタだけ
切り替えれば済む(これもコンテキストの切り替えだ)からであって、
コンテキストスイッチそのものが行われないからじゃない。
614:デフォルトの名無しさん
09/05/10 18:26:42
1CPUの場合はタイムスライスだけになるから減らないが、
CPUが複数ならスイッチ自体を減らせるという話じゃないかい。
615:デフォルトの名無しさん
09/05/10 22:05:51
>>613
ユーザランドでのスレッド実装だと
カーネルモードに入る回数が少なくて済むとかじゃね?
というかこの手のは、何が重いか時代により激しく違ってくるから
一般論といってもそれが何時のものかによるなあ
616:デフォルトの名無しさん
09/05/11 21:55:27
昔を語るのが一般とは思えない。
617:601
09/05/11 22:46:47
時代によって変わるもんなのか。
レジスタ、スタックの退避とか、カーネルに入って出てくる処理とかが重いのかとかとか思ってたんだけど。
fiberは軽いよ。とか聞くけど、それはおいといて。
>>603
mutexとか排他は考えないで、純粋に「コンテキストスイッチ」処理がどれくらい重いもんなのか
図りたい。
linuxでpthread使ってやろうと思ってるんだけど、どんなコードを書けばいいんだろ
単純に0から0xffffffffまで足す処理をシングルスレッドでやるか、
0~0xffを足す処理を0x1010101個のスレッド立てて計算させて、どっちが早いか。とか?<そりゃないだろって
618:デフォルトの名無しさん
09/05/11 22:57:13
>>617
CPUの数だけ分割するのが速い
619:デフォルトの名無しさん
09/05/11 23:28:58
例えば
20ms(OS次第)以上かかる計算処理を一つのJobとして
Job計10000個をキューに入れる。
スレッドをプールしておいて、各スレッドはキューからJobを取り出してひたすら実行する。
この時、プールするスレッド数をプロセッサ数と同数の場合と2000個の場合とで実行時間を計る。
現実的には、スタック領域以外にも
各スレッドで多少の独立したメモリ領域は使うことが多いと思われるので
ただの(レジスタやスタックで納まる)計算はではなく、
16Kなり64Kなりの領域をスレッド毎に確保しておいて
その内部の値を使った計算とする。
等というのはどうだろうか。
620:デフォルトの名無しさん
09/05/11 23:39:02
別にキューに入れる必要無いな。
同じことを繰り返すだけなんだから、CASを使ったカウントアップだけして
一定の数字になったらスレッド終了で充分か。
これなら、共有メモリを使えば、プロセスとの比較も出来る。
ただ、スレッドは「スタートのシグナル」を全部同時に出すことが出来るけど
プロセスだとどうなんだろ。全然知らない。
621:デフォルトの名無しさん
09/05/21 21:54:47
昔はPVM、今の時代はMPI
そしてOpenMPとMPIのハイブリッド実行が主流なのだろうか
622:デフォルトの名無しさん
09/05/21 22:39:20
>同じことを繰り返すだけなんだから、CASを使ったカウントアップだけして
>一定の数字になったらスレッド終了で充分か。
こんな非現実的な処理の時間を計測して何の意味があるわけ?
623:デフォルトの名無しさん
09/05/21 22:40:10
おそらくプロセッサ(コア)が増えれば増えるほど遅くなると思うけど。
624:デフォルトの名無しさん
09/05/21 22:44:10
ああ読み違えてたすまんのう
単に処理繰り返し数のカウントで使うだけってことね…
625:デフォルトの名無しさん
09/05/21 23:23:37
VC(VisualStudio2005)でコーディングしております。
「g_hThread = (HANDLE)_beginthreadex(NULL,0,MainLoop,0,0,&g_dwThreadId)」
で、スレッドを生成し、そちらで、
if(GetAsyncKeyState(VK_UP)&0x8000)
ではキーが取得できるのに、
GetKeyboardState(diks)
if(diks[VK_UP] & 0x80)
ではキーが取得できません。
どうも、メッセージキューやらが原因みたいですが、理屈がイマイチわかりません。
解決策や問題点など、教えていただけると幸いです
626:626
09/05/22 00:14:01
追記です。
そもそもGetKeyboardState()はメッセージキューに溜まったものを見るものであって、
新しく生成したスレッドでは、肝心のメッセージを取得することができない、、、
というあたりまではなんとなく理解できました
ちなみにやりたいことはキー情報の一括取得(できればリアルタイムの)です。
(GetAsyncKeyState()では1つ1つしか取れないので・・・
引き続き、解決策などありましたら、お願いします
627:626
09/05/22 01:06:46
生成したスレッドの方で、
// Threadのインプットのアタッチ
int targetThread, selfThread;
targetThread = GetWindowThreadProcessId(GetForegroundWindow(), NULL);
selfThread = GetCurrentThreadId();
AttachThreadInput(selfThread, targetThread, TRUE );
/*===== メインループ =====*/
// Threadを切り離す
AttachThreadInput(selfThread, targetThread, FALSE );
とすれば、GetKeyboardState()でも一応取得できました。
荒療治な気がしますが・・・
もっと良い方法などありましたら、お願いします
628: ◆0uxK91AxII
09/05/22 02:41:05
>>617
適当なsystemcallを行い、前後でCPUのtimestampでも読めば、
最も軽い場合については、調べられる。
>>625
DirectInputを使うとか。
629:デフォルトの名無しさん
09/05/22 03:20:02
>>627
GetKeyboardState()が使用する入力情報は、スレッドごとにある。
AttachThreadInput()はそれを共有させるためのAPIなので、その目的なら
それが一番適切な方法。
ただ、フォアグラウンドウインドウにAttachしてるのは間違いじゃないか?
GetAsyncKeyState()は自分のプロセスが非アクティブでもキー情報を取得できるAPI。
自プロセスの別スレッドでキー入力を拾う目的で使うのは、使えないことはないが
自分がアクティブかどうかの確認が必要で面倒。
630:626
09/05/22 04:59:32
>>628
DirectInputは同じような理由で取得できず...(・ω・
>>629
問題なく動いてるんで今の形(フォアグラウンド)で放置してたんですが、
ウインドウハンドルって引数以外で取得できるんでしょうか
631:デフォルトの名無しさん
09/05/22 06:02:44
>>630
GetWindowThreadProcessIdもGetForegroundWindowもいらない。
beginthreadexを呼んだスレッドで、そのままAttachするだけ。
そもそも、自分のウインドウを取得するのにGetForegroundWindowを
使うこと自体おかしい。
アプリケーションを起動したら必ずフォアグラウンドになるわけではないし。
632:626
09/05/22 15:13:54
確かにかなり回りくどいことしてました。
ただ、Attachの処理は生成処理の直下で一度だけ呼び出しても機能しなかったので、
beginthreadexを呼んだスレッドID(MainThreadId)だけをセーブして、
>>627と同じ場所で「AttachThreadInput(CurrentThreadId, MainThreadId, TRUE );」という形にまとめました。
633:デフォルトの名無しさん
09/05/22 16:18:42
新しく作成されたスレッドはGUI関連のAPIを呼び出すまでメッセージキュー等が
作成されないから、スレッド作成直後だと失敗するね。
新しいスレッドでウインドウを持っているならウインドウ作成後、ウインドウが
なければPeekMessageの空呼び出しの後でAttachがいいかな。
634:???
09/05/22 16:58:17
アセンブリ言語によるプログラミングで、1+2+3+・・・・+10と、1から10までの足し算をするプログラムはどのようなものになりますか?
16進数表現です。
635:デフォルトの名無しさん
09/05/22 17:14:22
まずは正しいスレッドを探すことからだな
636:デフォルトの名無しさん
09/06/09 21:56:35
質問です。
constで定義されている、読み込み専用の変数に対して
複数のスレッドがアクセスするとき、同期(クリティカルセクションなど)は
必要ありますか?
637:デフォルトの名無しさん
09/06/10 07:47:41
よっぽど変なハードウェアでない限り
要りません。
638:デフォルトの名無しさん
09/06/10 19:52:05
volatileで十分w
639:デフォルトの名無しさん
09/06/13 18:02:44
volatile使うやつは情弱
640:デフォルトの名無しさん
09/06/26 02:20:50
WindowsXP、VC2008EEの環境で作っています。
>>636の質問とかぶるのですが、1つのコンテナを複数のスレッドからイテレータでアクセス(読み込みのみで書き込みはない)しています。
実行時にイテレータを使った部分(直接使用しているのはSTL)でエラーが出て強制終了になってしまいます。
試しにスレッドを1つにしたらエラーは出ませんでした。
どういった原因が考えられるでしょうか?
641:デフォルトの名無しさん
09/06/26 03:48:25
そのSTL実装がスレッドセーフじゃないんでしょ。
機能としての読み込みであっても、内部で書き込みしていて競合する場合もあるだろう。
アトミックなところまでスレッドセーフが保証できないならロックすべき。
642:デフォルトの名無しさん
09/06/26 04:59:50
>>641
なるほど・・。
マルチスレッドは難しいですね。
643:デフォルトの名無しさん
09/07/04 11:06:03
>>640
単純に興味本位なんだが、const_iterator でも駄目なの?
644:デフォルトの名無しさん
09/07/04 11:09:45
最近マルチスレッド環境下でスレッド毎にプールを持つ
malloc() 実装がよくあるよね? 諸々の事情でそれが使
えない場合、アプリ側で出来る事ってある?
OO 的に小さなオブジェクトを生成/破棄するんだけど、
スレッドを跨って破棄を委譲するケースもあるんだ。で
も、単純にメモリ管理スレッド作っても過去の効率の悪
い malloc() 実装の焼き直しみたいになって多分効率悪
いと思うんだよね…。
645:デフォルトの名無しさん
09/07/04 11:16:05
アプリ側でそういう実装をやってるのはあっても動作環境側でそんな実装やってるの在るか?
複数のプール持つ実装はあるだろうけどスレッド固有になるような実装してたらそれこそスレッド跨げないし
646:デフォルトの名無しさん
09/07/04 11:49:37
>>645
ああ、中央ヒープはあるんだよ。でも、スレッド毎にも
管理されるよね? 多分細かくスレッドが生成/破棄され
るようなケースではかなり改善されるんだと思う。
URLリンク(goog-perftools.sourceforge.net)
↑Google の tcmalloc はコアヒープとスレッド毎のキャッ
シュという形で実装されている。
URLリンク(people.freebsd.org)
↑FreeBSd の jemalloc もスレッド毎に管理されてるみ
たい(TLS)だけど、要求されるサイズによって割り当て
部を買えるような話がある。
でも、やっぱりスレッド跨ると古い malloc() と同じ話?
うーん、ここまで来ると「どのコアで動くか」まで関連
するかなぁ…。
647:デフォルトの名無しさん
09/07/04 12:19:54
jemallocは自分が割り当てられたarenaをヒープのメタデータにつっこんでおいてfree時にはそこから解放するようになってる
割り当てはそれこそぽんぽん次のarenaをTLDに結ぶけどさ
そうでもしなきゃFreeBSDのデフォルトになれてない
完全に一切ロックせずスレッド固有のヒープにするなんてのはアプリ内の実装でなきゃ出来んよ
648:デフォルトの名無しさん
09/07/04 12:35:06
いやだからそのアプロ側でどうすんの? ってのを聞いてるわけで…。
649:デフォルトの名無しさん
09/07/04 12:43:37
一体何を心配して居るんだお前は?