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

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

その1 http://pc3.2ch.net/test/read.cgi/tech/997345868/
その2 http://pc5.2ch.net/test/read.cgi/tech/1037636153/
その3 http://pc8.2ch.net/test/read.cgi/tech/1098268137/
2デフォルトの名無しさん:2005/11/03(木) 11:24:14
3デフォルトの名無しさん:2005/11/03(木) 11:25:03
Pthread関係

The Single UNIX Specification, Version 2 Threads Extensions
http://www.unix.org/version2/whatsnew/login_threads.html

Multithreading in the Solaris Operating Environment
http://wwws.sun.com/software/whitepapers/solaris9/multithread.pdf

Building an open-source Solaris-compatible threads library
http://www.opensource.hp.com/the_source/linux_papers/scl_solaris.htm

Pthread Support in Microsoft Windows Services for UNIX Version 3.5
http://www.microsoft.com/technet/itsolutions/interop/sfu/pthreads0.mspx

Programming with POSIX Threads
http://www.awprofessional.com/title/0201633922
4デフォルトの名無しさん:2005/11/03(木) 11:25:58
ダグ・リー「Javaスレッド・プログラミング
並列オブジェクト指向プログラミングの設計原理」
http://www.amazon.co.jp/exec/obidos/ASIN/4881359185/
5デフォルトの名無しさん:2005/11/03(木) 12:05:29
>>1
お疲れさん。
6デフォルトの名無しさん:2005/11/03(木) 15:05:45
メッセージ通信がわからん
関数呼び出しが、同期なのに対比して、
同期・非同期よびだしどっちもできる
ことをメッセージ通信っていって区別してんのかな
7デフォルトの名無しさん:2005/11/03(木) 16:51:02
>>6
メッセージキュー使ってるだけでしょ。
8デフォルトの名無しさん:2005/11/03(木) 17:11:08
>>1
OS・言語・環境は問わないと言っているくせに
unix関連だけか?テンプレート書き直せ
9デフォルトの名無しさん:2005/11/03(木) 19:49:44
>>8
じゃあ、テンプレ追加よろしく。

俺からはJava関連をいくつか挙げる。

Java Memory Modelについて
http://www.cs.umd.edu/~pugh/java/memoryModel/
"Double-Checked Locking is Broken"
http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html
The JSR-133 Cookbook for Compiler Writers
http://gee.cs.oswego.edu/dl/jmm/cookbook.html

特に下2つはJava以外のプログラマにもお薦め。
メモリモデル関連では↓も面白い。
http://lse.sourceforge.net/locking/wmbdd.html
Linuxでlock-freeアルゴリズムの一つである
RCU(Read-Copy Update)を実装するときの話。
10デフォルトの名無しさん:2005/11/04(金) 02:46:51
ここのスレのひとは、どんなプログラム作ってるんですか?
11デフォルトの名無しさん:2005/11/04(金) 09:31:12
糞スレ立てたり
12デフォルトの名無しさん:2005/11/05(土) 02:06:21
【狂牛情報】アルツハイマーによる死者が50倍以上に アメリカ

159 - 衆 - 農林水産委員会 - 13号 平成16年04月27日 ○山田委員

エール大学神経病理学科外科部門の研究チームの検討を含め複数の研究で、剖検によりアルツハイマー病
あるいは痴呆症と診断されていた患者の三―一三%が実際はクロイツフェルト・ヤコブ病に罹患していた
ことが判明したとしている。米国では毎年アルツハイマー病と診断される患者が四百万人、痴呆症患者は
数十万人が発生していることから、最も少なく見積もって一万二千人以上のクロイツフェルト・ヤコブ病患者
が検出されず、公式統計に含まれない可能性がある。 注:12万人以上と思われる
                           
実際、アルツハイマー病と診断された死亡患者数は一九七九年には八百五十七例であったものが、
二〇〇〇年には五十倍以上の五万例近くとなった。

159 - 衆 - 農林水産委員会 - 7号 平成16年03月18日 ○松木委員 

記事の中に、アメリカでは、アルツハイマー病あるいは痴呆症と診断される人が年間四百万人いるそう
なんです。複数の研究機関の合同研究によると、このうち三から一三%が実際はヤコブ病であったことが
判明しております。少なく見積もっても十二万人はヤコブ病の公式統計に含まれていない可能性がある。

「アルツハイマーや若年性痴呆の中に変異型ヤコブ病患者が」・・米国牛輸入再開に京大医学部教授衝撃的指摘
http://news18.2ch.net/test/read.cgi/dqnplus/1120196765/
【vCJD】牛海綿状脳症(BSE)と同じ病気“日本人発症しやすい”…厚労省研究班
http://news16.2ch.net/test/read.cgi/scienceplus/1088575874/l50
13デフォルトの名無しさん:2005/11/07(月) 10:54:34
ちょっとばっかし知恵を借りたいのだが。

Linuxでとある画像フィルタリング処理を書いている取り引き先から、
マルチスレッド化して処理を高速化してくれと依頼がきている。
2CPUマシンで動かすから1CPUマシンでは動かなくてもいいらしい。
現状では、1枚の画像に対する処理にある程度時間がかかっていて、
それを複数枚処理してから先に進むロジックなのでその部分で
複数枚分のスレッドを起こせば2CPUに適当に分散できるのではないかと考えているらしい。

そこで相談。
・2CPUマシンでマルチスレッド化はどの程度高速化が期待できるか。
#まさか理論どおり2倍になるなんて期待していないが。
・マルチスレッドだとしたらどんな技術を使うことになるのか。
・マルチスレッドではなくマルチプロセスでやるとしたらどうか。

マルチスレッド云々以前に、数千行のmain()をなんとかしてから高速化を検討しろといいたいのだが……
#あ、そのなんとかするのもこっちに依頼が来るらしいのだが、マルチスレッド化と抱き合わせなのがなんともはや。
14デフォルトの名無しさん:2005/11/07(月) 11:03:51
>>13
> Linuxでとある画像フィルタリング処理を書いている取り引き先から、

この処理がCPUボトルネックなら、

> #まさか理論どおり2倍になるなんて期待していないが。

2倍近くになっても何の不思議もないが。

一般論としては、一枚をマルチスレッドで処理してもいいし、
一枚ごとにスレッド割り当ててもいいし。いずれにせよ簡単だろ?
1513:2005/11/07(月) 11:55:10
>>14
レスTHX。

>2倍近くになっても何の不思議もないが。
スレッド生成のボトルネックが気になるのだけど。
#プロセス生成よりは小さいのだろうけど。

man on wwwで調べてみた。
一枚の処理を分割するのは面倒なので、一枚ごとにスレッド分けるとして、
for (画面枚数分) {
pthread_create();
}
for (画面枚数分) {
pthread_join();
}
なんて安直なコードでもいいものかな?
#だとしたらmain()を分割した段階で半分以上仕事が終わったようなものなんだがw
16デフォルトの名無しさん:2005/11/07(月) 13:08:22
>>15
まあいいんじゃねえ?
一枚ごと独立に処理出来るんでしょ?

画像がでかけりゃメモリの取り合いで遅くなる可能性もあるけど、
まあとにかくやってみればいいと思う。
# 数千行のmain()に画像処理が埋め込まれているわけね…
17デフォルトの名無しさん:2005/11/07(月) 13:39:08
C#スレで質問していたのですがこちらのスレのほうが適切化と思ったので再度質問させていただきます。

たとえば次のような場合どうします?
株価などのように高頻度に値が更新されてそれに対する処理、その値を基にしたほかの株価データをを必要とする計算や表示などを行う必要がある。
値が更新されるー>対象となるデータノードを検索ー>それに対し値などに応じた必要な処理という流れ。
対象となるデータのノード数は10万単位。ただしすべてメモリ処理するものとする。
複数のノードにまたがる更新処理はない。
ノードの削除処理はない。

こんな場合どんなロックの粒度にしてどんなデータ構造にします?
自分の場合だとデータノードをインスタンスとしてそれをコレクションクラスにぶっこんであるとして、データノードにその変化に応じて処理するobserverが引っ付いている。
コレクションクラスをロックー>データノード検索ー>コレクションクラスのロック解除ー>ノードの必要な箇所にロック->
ノード内の関連データをその部分にロックかけながらアトミックにupdate->
該当箇所のロックをはずしobserverに通知->各observerがおのおの独自の処理を行う。その際におのおの必要なロックをかける。
こんなんなんですが、皆さんはどんな風にされるんでしょう?

1813:2005/11/07(月) 13:52:40
>>16
>まあいいんじゃねえ?
うい、THX。

>一枚ごと独立に処理出来るんでしょ?
そそ、全画像処理後、集計してフィルタリングパラメータを変える繰り返し。

>画像がでかけりゃメモリの取り合いで遅くなる可能性もあるけど、
>まあとにかくやってみればいいと思う。
小さい小さい。最大128x128。
#なのに現状は2048x2048x16の実数値バッファがグローバルに固定で取られてて(512MB!)泣けます。

># 数千行のmain()に画像処理が埋め込まれているわけね…
そそ、あのパラメータを変えてフィルタリング、このパラメータを変えてフィルタリング、
って具合に同じ処理が繰り返し登場するのでその行数。
これをばらしてメモリを必要なだけ動的確保してやれば
1スレッド辺りのメモリ使用量も1MB程度に抑えられそう。
19デフォルトの名無しさん:2005/11/07(月) 15:58:55
>>18
> 小さい小さい。最大128x128。

小さすぎてスレッド生成のオーバーヘッドが気になる時は、
スレッドプール使ってください。
2013:2005/11/07(月) 17:06:30
>>19
オーバーヘッドが大きいようならスレッド分割単位を見直すから多分問題にはならないと思うのだけど、
参考までにスレッドプールとは何か、ポインタを示してもらえませんか?
#ぐぐったけどWebアプリか.NetかC#かJavaの話題しか見つからなかった。
21デフォルトの名無しさん:2005/11/07(月) 17:26:57
2213:2005/11/07(月) 18:12:55
>>21
THX。
一通り読んでみます。
#日本語で検索してたよ_/ ̄|○
23デフォルトの名無しさん:2005/11/07(月) 19:30:54
>>13
ちょっと待てよ、お前。
さっきから聞いてりゃ言いたいことぬかしやがって。
飯食ってんだろ?できる見込みないものを依頼受けるなよヴォケ。
お前の相談は「丸投げ」なんだよ。ここは宿題片づけスレか?
気になるなら自分で実験したらいいべ?
2413:2005/11/07(月) 21:25:15
>>23は、せっかくいいこと言っているのに、最後の
「いいべ」という田舎者丸出しの言い方で
説得力が無くなってしまった。
25デフォルトの名無しさん:2005/11/07(月) 21:36:15
華麗に>>17がスルーされてる件について
26デフォルトの名無しさん:2005/11/07(月) 22:05:23
C#わかんねえんだもん

Javaで我慢してくれ。
Overview of package util.concurrent Release 1.3.4.by Doug Lea
http://gee.cs.oswego.edu/dl/classes/EDU/oswego/cs/dl/util/concurrent/intro.html
2713:2005/11/07(月) 22:22:05
取り敢えず>15に書いたような簡単なサンプルは作ってみましたが何か。
余りに単純すぎてスレッドが複数実行しているかどうか判らないような代物ですが。
水曜に客先の端末(2CPU)で分散処理するかどうかは見てくる積もり。

#あー、そもそも依頼を受けたかどうかは書いてない罠。
28デフォルトの名無しさん:2005/11/07(月) 22:24:23
>>27
xosview動かして、1CPU版と比べたら、分かるかも〜
29デフォルトの名無しさん:2005/11/07(月) 22:32:49
ランチャー作って二つプロセス起動させれば
全てOK。
30デフォルトの名無しさん:2005/11/08(火) 21:27:03
31デフォルトの名無しさん:2005/11/08(火) 22:22:38
YOU行ってみちゃいなよ。
32デフォルトの名無しさん:2005/11/08(火) 23:22:59
むしろ↓がきになる

Java Concurrency in Practice
by Brian Goetz, Tim Peierls, Joshua Bloch, Joseph Bowbeer, David Holmes, Doug Lea
http://www.amazon.com/gp/product/0321349601/

なにこのメンバー
33デフォルトの名無しさん:2005/11/12(土) 22:57:52
// TEMPファイルを作成する関数の様なもの。このままスレッドで使うとバグる。
char * create_unique_file(char *file) {
 FILE *fp;
 if(NULL != (fp = fopen(file, "rb"))) {
  // 同名のファイルが既に存在する。
  fclose(fp);
  // ※ここで違うファイル名を生成する処理を行う。
 } else {
  // 同名のファイルが存在しないのでそのままのファイル名でファイルを作成する。
  if(NULL != (fp = fopen(file, "wb"))) {
   // ここにきてほしい。
   fclose(fp); return file;
  } else {
   // なぜかここにくる場合がある。errno:13(EACCES)
  }
 }
 return NULL;
}
// 上の関数をマルチスレッドで使うために若干のセーフティーを加えてみた。
void funk(char *file) {
 EnterCriticalSection(&cs);
 create_unique_file(file);
 Sleep(100);// これをコメントアウトするとバグる(時間が短いとバグりやすい?)。
 LeaveCriticalSection(&cs);
}
// 上側の関数をマルチスレッドプログラム(HTTPDもどき)で使用していたところなぜかバグります。
// ・"wb"が失敗する。及び、プログラム全体のファイル送信がおかしくなる。
// 下側の関数のようにしたところ、
// ・Sleep(50〜)を入れると両方のバグが(見た目)出なくなる。
// fopen()が極短時間で重なっておかしくなっているのではないかと思っています。
// どうなんでしょうか・・・
34デフォルトの名無しさん:2005/11/12(土) 23:24:42
>>33
排他していない版は、典型的なバグだね。

static int a;
static void foo()
{
 while(a != 0){
 }
 // <-- (A)
 a = 1;
 // 処理
 a = 0;
}

と同じ。
(A) の所で、スレッドが切り替わって同じルーチンが呼ば
れた時を考えればなぜバグっているかわかるはず。

ところで、排他制御を追加した版でも Sleep() がないと、
> // ・"wb"が失敗する。及び、プログラム全体のファイル
> 送信がおかしくなる。
の現象が出るの?

ちなみに、シングルスレッド用のライブラリをリンクしてるっ
てことはないよね。
35デフォルトの名無しさん:2005/11/12(土) 23:26:03
>>33
>   if(NULL != (fp = fopen(file, "wb"))) {

freopen()しろ、この呆けが!
36デフォルトの名無しさん:2005/11/12(土) 23:31:39
3733:2005/11/12(土) 23:38:59
>>34>>35>>36どうもです。

更に実行しまくってたらクリティカルセクション+Sleep()でもバグが出てます;;

>ちなみに、シングルスレッド用のライブラリをリンクしてるっ
>てことはないよね。
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <winsock2.h>
#include <stdio.h>
って感じでインクルードしてます(これらを用いて作成した関数群など)。外部のライブラリなどは使用していません。
"シングルスレッド用のライブラリ"を意識したことがないのですが、
"シングルスレッド用のライブラリ"ってことは<stdio.h>や<windows.h>のマルチスレッド用のがあるとかですか?
#define MULTI_THREAD// こんな感じの。
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <winsock2.h>
#include <stdio.h>
38デフォルトの名無しさん:2005/11/12(土) 23:41:26
>>37
シングルスレッド・マルチスレッド用のライブラリの切り替えは、
VCならプロジェクトのプロパティの中のどこかにあるはず。
ただしここでいうライブラリはCランタイムライブラリのことなのでWinAPIは関係ない。
39デフォルトの名無しさん:2005/11/12(土) 23:49:25
ファイル名を返すかわりに直接ハンドルでも返せば?
4033:2005/11/13(日) 00:04:52
>>36
読んでいます難しいです;

>>38
CLコマンドでコンパイルしているのですが/MTオプションを指定してみました。
ファイル送信のバグは今のところ目に付かなくなりました。
しかし"wb"のほうが激しくなりました。
ちなみにCとAPIのみで作成しています。
マルチスレッド用のライブラリについて調べてみようかと・・・

>>39
"rb"のかわりにGetFileAttributes()で判定するようにしてもだめでした。"wb"が開けないのはどうにも・・・
41デフォルトの名無しさん:2005/11/13(日) 00:18:47
まさか、InitializeCriticalSectionしてないとか?
あるいは、違うファイル名を生成する処理がおかしいとか。
あるいは、戻ってきたファイル名の扱いがヒドいとか。
42デフォルトの名無しさん:2005/11/13(日) 00:25:13
>>40
> ちなみにCとAPIのみで作成しています。

へぇー fopen() と言う API がある OS もあるんだ…。

あと、>>39 は、GetFileAttributes() なんかにつ
いて言ってるんじゃないと思う。

そもそも、ファイル名返してもそのファイルを書き込み
オープンする前に他のスレッドが書き込みオープンする
かもしれない。つまり、funk() から戻った時に既に
そのファイル名のファイルが作られてるかもしれないか
ら、ファイル名なんか返しても意味がない。
43デフォルトの名無しさん:2005/11/13(日) 00:33:11
そうそう、普通に「そのまま使える物」を返すか
単に「呼ぶ度に違う名前を生成する関数」を作って、ファイルが開けなければ再試行するとか。

後者のものは、C標準にあるけどな。
4433:2005/11/13(日) 00:45:38
>>41
それは・・・ないとおもいますっ;><

>>42
vc++をインストールしているがコマンドラインでコンパイルしてて
MFCは使わずc言語標準関数とWin32APIで作ってます。

fopen()やfclose()を繰り返すのがまずいのかなと思い"rb"のfopen()を使わないようにしたのを作ってみましたが結果は同じでした。
"wb"がfopen()できないのにファイルポインタは返せないのでは?
初めのを閉じずに使用すれば次のもバグらなくなってウマーということでしょうか。
4533:2005/11/13(日) 01:02:38
とりあえず閉じずに返すようにしてみます。
46デフォルトの名無しさん:2005/11/13(日) 01:29:19
>>44
すまん、>>42 で大嘘書いてた。
fopen(〜, "wb") でファイルが作られるから、他のス
レッドがそのファイルを作ることはないはず。まあ、でも
わざわざファイル名を返して戻った先で再度オープンする
ならそのままファイルハンドルを返せばいいと思う。

そもそも、俺なら fopen(〜, "a") でファイルを開い
て、fgetpos() で取得したファイルポインタが 0 なら、
そのままそれを返すし、0 でなかったら違うファイル名で
再トライを繰り返すように作ると思う。
47デフォルトの名無しさん:2005/11/13(日) 01:41:44
(他と衝突しない)ファイル名を作る
ファイルを書き込み+排他で作ってファイルポインタを返す
の一連の処理をクリティカルセクションでやるのはどうか.

>>42の「そもそも〜」は合ってると思う.
>>33の関数だとファイルを "wb" で作っても fclose ですぐ閉じる
ようになってるから.すでにあるファイルを "wb" で開くと
元のファイルは破壊される.
4833:2005/11/13(日) 03:30:42
TEMPファイルの作成は通し番号で作成するようにしたところバグがでなくなりました。
何とかいけそうです。

現在スレッドを作成するのにCreateThread()関数を使用しています。
調べているとCランタイム関数を使う場合CreateThread()はまずいようです。
以前から、rand()やsrand()を使っているプログラムでもCreateThread()を使っており謎のバグが発生しておりました。
とりあえず_beginthread()を使うように書き直してみます。
今は/MTオプションをつけなくてもコンパイルは通っています。

これが致命的だったのかもorz
49デフォルトの名無しさん:2005/11/13(日) 08:20:26
なぜFILE*を返さないのかわからん。
OSが提供するロックのようなものなのに。

> これが致命的だったのかもorz

_beginthreadexにするのは正しいが
33でやろうとしている内容であれば問題は起きない
50>>46:2005/11/13(日) 10:12:04
>>47
> >>33の関数だとファイルを "wb" で作っても
> fclose ですぐ閉じるようになってるから.すでに
> あるファイルを "wb" で開くと元のファイルは破
> 壊される.

いや、排他が入ってる版ならその前の
fopen(〜, "rb") のファイル存在チェックではね
られるから「すでにあるファイルを "wb" で開く」
ことはないはず。

>>48
> TEMPファイルの作成は通し番号で作成するように
> したところバグがでなくなりました。

おいおい、前はどうやってたんだよ…。

> 今は/MTオプションをつけなくてもコンパイルは通っ
> ています。

コンパイルが通れば OK なんて考えてるうちは、マルチ
スレッドプログラムなんか組まない方がいいと思う。
5133:2005/11/14(月) 08:02:54
TEMPファイルの作成は、
以前はtmp.txtが既に存在する場合はtmp(1).txtが存在する場合はtmp(2).txtみたいにしてました。
通し番号の方はtmp1.txt次はtmp2.txt次はtmp3.txtを問答無用に作成するようにしました。

_beginthread()を使用するようにしたところ、以前は謎のアクセスバイオレーションが発生していたのですが
それ以前にどうみてもヌ○ポを踏んでいるようなエラーが出ます。
なんとなくSleep()でタイミングをずらしてみたところエラーが出なくなったりします。

マルチスレッドの場合、同じメモリ領域を同時に”読む”のもNGですか?
if(NULL != *hoge)と*p = hoge;やi = hoge->num;が別スレッドで同時に起きるような場合もNGですか?
5233:2005/11/14(月) 08:08:11
踏んでいる場所を見つけようとチェックを埋め込んでみてもつかまりません。
自分で書いたコードよりも奥の方で発生しているようです・・・。
53デフォルトの名無しさん:2005/11/14(月) 08:11:48
もはやマルチスレッド関係ないだろ。
初心者スレに行け。
create_unique_file()の稚拙なロジックが痛々しい。
5433:2005/11/14(月) 08:14:51
×if(NULL != *hoge)
○if(NULL != hoge) // hogeは構造体へのポインタです。

痛々しいロジックの方は忘れてください;><
55デフォルトの名無しさん:2005/11/14(月) 11:16:38
>以前はtmp.txtが既に存在する場合はtmp(1).txtが存在する場合はtmp(2).txtみたいにしてました。
こんな文章しか書けないくらいだから、コードもとっ散らかってるんだろ。
小学校辺りから「頭の使い方」を勉強しなおしてみたら?
56デフォルトの名無しさん:2005/11/14(月) 17:20:12
重複しないテンポラリファイルなんて、API使えば一発だろ。
57デフォルトの名無しさん:2005/11/14(月) 23:23:11
>マルチスレッドの場合、同じメモリ領域を同時に”読む”のもNGですか?

スレッド生成前にメモリ領域を確保して値しかいじらないのなら、同時に読んでもOK
マルチプロセッサではメモリバリアを使って同期すればOK
メモリ領域を複数スレッド内で確保と消去をくり返すような場合はリードライトロック。

> if(NULL != *hoge)と*p = hoge;やi = hoge->num;が別スレッドで同時に起きるような場合もNGですか?

別スレッドが *hoge ポインタの示す場所をいじるのなら、同期しないと全部アウト。
58デフォルトの名無しさん:2005/11/15(火) 01:05:11
>マルチスレッドの場合、同じメモリ領域を同時に”読む”のもNGですか?

intサイズだったらOKだよ。
前スレでそういう結論になった。
5933:2005/11/15(火) 05:26:59
/ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
| 作成された子スレッド内部で継続中flagを立てる前に
| 親スレッドでflagチェック→終了判定→構造体NULLクリア
| していたのがNULLを踏む原因でした。

   ̄ ̄ ̄|/ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
  ∧_∧       / ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
  ( ・∀・)  ∧ ∧ < おめーのバグだな、
 (  ⊃ )  ( ゚Д゚)  \____________
 ̄ ̄ ̄ ̄ ̄ (つ_つ__
 ̄ ̄ ̄日∇ ̄\| NullPo |\   ナントカナリソウデス
       ̄   =======  \ イロイロトドウモアリガトウゴザイマシタ
60デフォルトの名無しさん:2005/11/15(火) 08:03:23
親でflag立ててから呼べばいいじゃん。
61デフォルトの名無しさん:2005/11/20(日) 03:06:17
http://pc8.2ch.net/test/read.cgi/tech/1131691023/312-317
に書いたんだが、誘導されました。
返答求む。
62デフォルトの名無しさん:2005/11/20(日) 16:27:20
windows には win32 API で色々なイベントを使えるようになってますが、
UNIXではpthreadのイベントを使う以外にないのでしょうか?
63デフォルトの名無しさん:2005/11/20(日) 16:46:47
はぁ?
64デフォルトの名無しさん:2005/11/20(日) 17:19:57
>>62
意味がわかんない。
自分が言ってる単語について全部調べてみたら?
わかんない言葉は使うもんじゃないよ。
65デフォルトの名無しさん:2005/11/20(日) 17:29:22
セマフォをつかって、ある処理に関してロック、アンロックの処理が
したい場合、ソースは以下のようなかんじ問題ないですか?
※以下のプログラムを2つ同時に動かした場合、
セマフォの開放は1つ目のプロセスによって行われているので、
2つ目のプロセスはIPC_RMIDの際に、エラーが出てしまいますよね。
これって、基本的にはどうするといいんですかね?
6665:2005/11/20(日) 17:29:42
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h> 
#include <sys/sem.h>
union semun { int val;
struct semid_ds *buf; unsigned short int *array;
struct seminfo *__buf; };
int lock(int argc, char *argv[]) {
union semun semaphore_union;
struct sembuf semaphore_buffer;
int semaphore_id;
semaphore_id = semget((key_t)1000, 1, 0666 | IPC_CREAT);
semaphore_union.val=1; //sem init
if ( semctl(semaphore_id, 0, SETVAL, semaphore_union) != 0 ) {
exit(1); } //lock
semaphore_buffer.sem_num = 0;
semaphore_buffer.sem_op = -1;
semaphore_buffer.sem_flg = SEM_UNDO;
if ( semop(semaphore_id, &semaphore_buffer, 1) == -1 ) {
exit(1);  }
sleep(30) // 何かの処理の変わり  //unlock
semaphore_buffer.sem_num = 0;
semaphore_buffer.sem_op = -1;
semaphore_buffer.sem_flg = SEM_UNDO;
if ( semop(semaphore_id, &semaphore_buffer, 1) == -1 ) {
exit(1);
}
//sem end
if ( semctl(semaphore_id, 0, IPC_RMID, semaphore_union) != 0 ) {
exit(1);
}
return(0);
}
6765:2005/11/20(日) 17:30:42
//sem end
if ( semctl(semaphore_id, 0, IPC_RMID, semaphore_union) != 0 ) {
exit(1);
}
 この際に、一つめのプロセスが既に削除しているので、
 2つ目のプロセスでは、エラーが帰ってきてしまいます。
 基本的にセマフォの扱いって、どう記述するものなんですか。
6865:2005/11/20(日) 17:31:19
正しいやり方かはわからないが。
@プロセス1の処理が終わったら、セマフォに「プロセス1終わったよ」書き込む。
A「プロセス1終わったよ」になるまで待機してから、
 「プロセス2も終わったよ」を書き込んでから、プロセス2を削除。
B「プロセス2も終わったよ」を確認してから、プロセス1を削除
6965:2005/11/20(日) 17:31:49
>>68
それぞれのプロセスをIPC_RMIDさせる直前までwait させろってことですよね。
  そのケースは、事前に立ち上がるプロセス数(たとえば、自分で
  fork して作成したプロセス)が分かっている場合、有効ですよね。
 
 何個のプロセスがあがるか分からないときの手段としては、
 IPC_RMID させる時は、手動で打つがいいのかな。
70デフォルトの名無しさん:2005/11/20(日) 17:35:42
>>65
ここはマルチ「スレッド」のスレだ。
決してマルチ「プロセス」のスレではない。
71デフォルトの名無しさん:2005/11/20(日) 17:38:09
マルチプロセスプロ倉羅民具スレなんてねーんだから
ここでいいじゃん
72デフォルトの名無しさん:2005/11/20(日) 17:39:15
いや、素直にUnixプログラミングスレかUnix板に行くべきだろう。
73デフォルトの名無しさん:2005/11/20(日) 23:03:49
shared libを作ろうとしてまして、
その中でスレッドを起動して使いたいのでつが、
問題ないでしょうか?

74デフォルトの名無しさん:2005/11/20(日) 23:31:14
>69
親が代表してセマフォを造って、削除する。
子供は親の造ったセマフォをみて触るだけ(無ければエラーにする)とか。

セマフォを開いてみて、無ければ造る。
造る時に排他制御して、唯一造れた人が責任をもって廃棄する、とか。
7565:2005/11/21(月) 00:29:05
>>70 >>72
 Unixプログラミングすれから、誘導されたんですよ。
>>74
 実務レベルだと、
 親=オペレータが、起動スクリプト(セマフォ作成)をたたく。
    サーバー終了時に、終了スクリプトをたたく。

    オペレータ介さないと考えると、init.dに、SXXXXスクリプト)を作成し、
    runレベルに合わせて、起動、終了のシンボリックリンクをはる。
   
 なんて感じですかね。
            
76デフォルトの名無しさん:2005/11/21(月) 02:49:56
>>75
そりゃ気の毒に、誘導が間違ってる。無責任にこの辺に誘導しとくよ。
「VIPPERでもわかるプログラミング」
77デフォルトの名無しさん:2005/11/21(月) 12:01:13
>>73
過去の経験から言わせてもらうとライブラリ側で勝手にスレッドを起動するような
作りはあらゆる意味で良くない。
どうしても必要ならばまずそのスレッドで起こりえる可能性をすべて列挙してみる。
スレッドが起動するという事、その際例外が発生した場合どういう処置がなされるべきか、など。
判断がつかなければコールバック等でそのスレッドのトップレベルループや
ドメインに該当する処理に対してユーザーが干渉できるようにしたほうがいい。
↑domain
|user_thunk_procedure
|thread_callback
これらをドキュメント等も含めきちんと導出できないと第三者にはまず提供できない
代物になる。もしくは欠陥を持ったライブラリが完成する。
78デフォルトの名無しさん:2005/11/22(火) 00:23:28
マルチスレッドの例外処理ってどうやってまつか、みなさん。
79デフォルトの名無しさん:2005/11/22(火) 00:30:02
大域くくって落ちたらやりなおし、
ループでもなんでも、気をとりなおして次の処理。
8073:2005/11/22(火) 01:45:30
>>77
ありがとうございますた、

厳しいみたいでつね、もっと勉強しまつ。
81デフォルトの名無しさん:2005/11/28(月) 01:09:25
winapiスレと迷いましたが、_beginthreadex()に関して質問があります。

現在_beginthreadex(NULL, 0, .....);
としてメモリ割り当てを特に指定していません。

現在は実験のためにあるスレッドをいくつも作りたいのですが、
そうすると、エラーが起こりその原因の場所を調べると
#endif /* _WIN64 */
return HeapAlloc(_crtheap, 0, size);
という箇所でした。毎回ここでエラーが出ているようです。

この原因としてスタック領域のメモリ不足だと自分では思っているのですが、
実際のところはどうなのでしょうか?
また何かいい解決方法を教えていただけないでしょうか?
現在は数十スレですが、将来的には数百スレを扱いたいと考えています。
82デフォルトの名無しさん:2005/11/28(月) 01:33:22
いいえ、その情報だけですとスタックではなくヒープの確保が失敗したと思われます。
マルチスレッド云々以前に初心者歓迎スレ辺りでソースを晒してみては如何でしょう。
83デフォルトの名無しさん:2005/11/28(月) 01:40:39
スレッドが多すぎてヒープ(のアドレス空間)が足りなくなるという可能性も無くはないけど
数十スレッド程度でそんなことになる筈もなく
そもそもスタック領域がヒープを圧迫するかどうかという問題も
8481:2005/11/28(月) 10:47:04
舌足らずですいません。
エラーが起こるのは_beginthreadex()内の処理のようです。
_beginthreadex()を呼び出して目的のスレッドを作成しようとすると
その過程の最中で81のようなエラーが出現してしまいます。

あと、
「メモリがreadになることはありませんでした。」
というメッセージボックスが表示されるのですが
何か関係あるのでしょうか?
スレッド数は32、64、96と増やしていきたいのですが
32の段階でのエラーです。
85デフォルトの名無しさん:2005/11/28(月) 11:28:40
だから、マルチスレッド以前のレベルでバグってるんだろってば。
自分のソースも追えないような蛸なら初心者スレでソース晒せって。
86デフォルトの名無しさん:2005/11/28(月) 13:27:17
> あと、
> 「メモリがreadになることはありませんでした。」
> というメッセージボックスが表示されるのですが

自分で確保したメモリ領域外のアドレスを読みに行ったときに出る.
87デフォルトの名無しさん:2005/11/28(月) 16:58:56
エスパーの俺様が、スレ違いのバグを解決してやろう。

malloc系を呼び出したときにライブラリ内でエラーが起こるのは
ヒープの管理ブロックが壊れている時だ。

つまり、mallocした領域以外をfreeしたり、同じ領域を2度freeしたり
あるいは確保した領域をはみ出して書き込みをした場合に起こる。
8881:2005/11/28(月) 22:43:36
すいませんでした
>87さんのレスを手がかりにmalloc(), free()を中心に調べていったところ
p = (int *)malloc(sizeof(short) * num);
という箇所がありました。
sizeof(int)に直したところ変なエラーはでなくなりました。
心配されていた方々申し訳ございませんでした。
89デフォルトの名無しさん:2005/11/29(火) 00:00:44
だから>82や>85がマルチスレッド以前のバグだって指摘してたのに……
90デフォルトの名無しさん:2005/11/29(火) 04:05:55
うるせえ黙れ
91デフォルトの名無しさん:2005/11/29(火) 08:26:55
>>88
心配してねーよ。
こいつ馬鹿だなと思っていただけ。
92デフォルトの名無しさん:2005/11/29(火) 09:50:47
>>88
誰も心配はしてないとおもいます。アドバイスしてただけ。
日常でもそのような勘違いをしているとなぜあの人は自分のことしか考えないのかと思われるので注意しましょう
93愛也:2005/11/29(火) 15:57:01
質問なんですが・・・・どなたか教えていただけないでしょうか?

(1)
特定のデータを指定するにはアドレス信号を用いる。どれだけのアドレス信号が発行できるかはアドレスバスの本数による。
アドレスバスの本数が8本のときは(  1  )個、12本の時は(  2  )個のアドレスを発行する事ができる。

(2)
容量32KBのメモリがある、このメモリにバイト単位でアドレスをつけた場合(アドレス幅は8ビット)、全アドレスを指定するには、最低(  3  )本のアドレスバスが必要である。
同時に256MBの場合は(   4   )本必要である。

上の問題をどなたかお時間がある方がいらっしゃれば教えていただけないでしょうかぁ??

何卒よろしくお願い致します。
94デフォルトの名無しさん:2005/11/29(火) 16:05:54
>>93
板違い
95デフォルトの名無しさん:2005/11/29(火) 16:43:14
>>93
そのうえ問題自体に間違いがある(w
コピペミスかもしれんが(w
96デフォルトの名無しさん:2005/11/29(火) 20:19:25
HTマシンでpause命令使って効果実感した人いる?
97デフォルトの名無しさん:2005/11/29(火) 23:05:15
メール欄が空ですよ
98デフォルトの名無しさん:2005/12/06(火) 03:43:50
93は、
スレ題名に「マルチスレッドプログラミング相談室」と書いてあるから、
「ここはマ板共用の相談スレに違いない!」と思ったんじゃないの?
99デフォルトの名無しさん:2005/12/06(火) 12:03:49
マ板?
100デフォルトの名無しさん:2005/12/07(水) 16:08:17
Windows でマルチスレッドを実現するには CreateThread API 以外に方法はありますでしょうか?
101デフォルトの名無しさん:2005/12/07(水) 16:55:31
_beginthread
102デフォルトの名無しさん:2005/12/07(水) 21:07:21
>>101
_beginthreadex使えよ。
103デフォルトの名無しさん:2005/12/09(金) 18:32:43
つうか何がしたいんだ
104デフォルトの名無しさん:2005/12/09(金) 18:52:57
いろんな恋がしたい
105デフォルトの名無しさん:2005/12/10(土) 01:12:51
マルチフ恋奴
106デフォルトの名無しさん:2005/12/13(火) 10:40:34
ほしょ
107デフォルトの名無しさん:2005/12/13(火) 22:06:28
>>104
マルチスレッドな恋なんかしてると火吹くぞ
108デフォルトの名無しさん:2005/12/13(火) 23:24:21
俺のセマフォは3カウントまで。
109デフォルトの名無しさん:2005/12/14(水) 00:13:25
セマフォなんてニッチで泥臭いものは今日日使わないよ
110デフォルトの名無しさん:2005/12/14(水) 00:29:54
オレのMutexは一度もLockされたことがない…orz
111デフォルトの名無しさん:2005/12/14(水) 00:32:21
そこはまさにCriticalSectionなので、触れてはいけない。
112デフォルトの名無しさん:2005/12/14(水) 00:33:55
一生一WorkerThread。
113デフォルトの名無しさん:2005/12/14(水) 00:35:11
オレのFutureはいつまでたっても実体を返さない…orz
114デフォルトの名無しさん:2005/12/14(水) 00:36:37
オレのQueueはいつも空っぽ…orz
115デフォルトの名無しさん:2005/12/14(水) 00:44:57
Terminateされたい性分なんです、スレッド失格でしょうか?
116デフォルトの名無しさん:2005/12/14(水) 00:50:19
だれかJoinしてクレー!
117デフォルトの名無しさん:2005/12/14(水) 01:10:22
オレのQueue、気付いたときにはStackになってた
118デフォルトの名無しさん:2005/12/14(水) 01:41:29
恋はいつも非同期(asyncronous)
119デフォルトの名無しさん:2005/12/14(水) 02:02:00
クリスマスなのにDaemonです…orz
120デフォルトの名無しさん:2005/12/14(水) 02:45:54
僕の人生Suspendしています。誰が解除してくれるんですか?
121デフォルトの名無しさん:2005/12/14(水) 03:08:52
俺はreturnしちゃったよ
122デフォルトの名無しさん:2005/12/14(水) 07:50:37
signal投げてくれる筈のプロセスがゾンビになっていた件について
123デフォルトの名無しさん:2005/12/14(水) 07:55:39
それマルチスレッドじゃねーし
124デフォルトの名無しさん:2005/12/14(水) 21:50:08
彼女といつも同期に失敗しまつ
125デフォルトの名無しさん:2005/12/14(水) 21:52:06
俺はいつもシングルスレッド。
126デフォルトの名無しさん:2005/12/15(木) 00:29:14
漏れのセフレはヂュアルコアだから2穴使って楽しめるよ。
127デフォルトの名無しさん:2005/12/17(土) 01:08:57
おまいら、そろそろ戻ってこい
128デフォルトの名無しさん:2005/12/17(土) 04:50:34
goto 107
129デフォルトの名無しさん:2005/12/17(土) 08:34:28
mutex と spin lock の使い分けの基準て何?
130デフォルトの名無しさん:2005/12/17(土) 10:49:07
使い分けってお前
131デフォルトの名無しさん:2005/12/17(土) 15:45:08
mutex: 居間のテレビのチャンネル権取得に使う
spin lock: 朝、トイレの空きを待つ時に使う
132デフォルトの名無しさん:2005/12/17(土) 15:57:25
後者、spin lockになるのはガマン出来ないときに限られると思われ
133デフォルトの名無しさん:2005/12/17(土) 16:18:01
スピンロックって、カーネルモードへの移行よりも短い時間しかブロックされない処理、
例えば単純な変数の読み書きなんかに積極的に使いたくなるのだけれど

シングルプロセッサのシステムで、
ロックしているときにコンテキストスイッチが起きて
別スレッドがロック取得しようとすると
すげー時間が無駄になるんだよね。
それがちょっと嫌。
134デフォルトの名無しさん:2005/12/17(土) 20:56:42
>>133
知ったかはよくないぞ。入社2年目のおぬし。天狗の鼻をへし折られろ。
135デフォルトの名無しさん:2005/12/17(土) 21:16:38
我が社では、spin lock の事を
フレンドリーに「ぐるぐるくん」と呼んでいる。
136デフォルトの名無しさん:2005/12/17(土) 21:35:35
我が社では回転元彌チョップと呼んでいる。
137129:2005/12/17(土) 22:48:09
>>131
よくわからんです

>>133
その単純な変数の読み書き以外に、どうしても spin lock を使い
たいんじゃ! とか、spin lock じゃないとうまくいかないような、
典型的なケースってないすか?
138デフォルトの名無しさん:2005/12/18(日) 00:05:24
>>134
じゃあ、どこがおかしいのか指摘しろよ。
業界最底辺を何年も続けてる事だけが自慢の
低脳プログラマさんよ。

マルチプロセッサでも、
ロックを取得している状態で実行権を奪われたら起こりうるのは確かだけどな。
139デフォルトの名無しさん:2005/12/18(日) 00:40:53
>>138
だれか解読頼む。
140デフォルトの名無しさん:2005/12/18(日) 01:43:49
>>138
お前の存在そのものがおかしいことを指摘してやらんでもない。
141デフォルトの名無しさん:2005/12/18(日) 01:46:16
指摘してほしいのに しろよ はないだろ。
せめて、「わたくしは無知なので、できれば、ご指摘いただけないでしょうか?」だろ。
誠心誠意で言葉に気をつけろ。
142デフォルトの名無しさん:2005/12/18(日) 01:51:21
ナニこいつ
143デフォルトの名無しさん:2005/12/18(日) 01:59:03
具体的に指摘しないのは荒らしと同じだから放置汁
144デフォルトの名無しさん:2005/12/18(日) 14:48:34
チョンはすぐにファビョるからやあねえ。
145デフォルトの名無しさん:2005/12/18(日) 18:57:20
Win32(XP)で下のような排他制御を考えないプログラムを書いて
実際にハングするところを確かめたかったのですが、何度実行しても上手くハングしてくれません
たまたま運が良くてハングしなかっただけなのでしょうか?ご教示願います

#include <stdio.h>
#include <windows.h>
#include <process.h>
unsigned __stdcall mythread(LPVOID);
int main(){
unsigned int thID;
HANDLE hTh = (HANDLE)_beginthreadex(NULL, 0, mythread, NULL, 0, &thID);
for (int i = 1; i <= 100; i++) {
FILE *fp = fopen("test.txt", "a");
fprintf(fp, "Main---%d\n", i);
fclose(fp);
}
WaitForSingleObject(hTh, INFINITE);
CloseHandle(hTh);
return 0;
}
unsigned __stdcall mythread(LPVOID lpx)
{
for (int i = 1; i <= 100; i++) {
FILE *fp = fopen("test.txt", "a");
fprintf(fp, "Thread---%d\n", i);
fclose(fp);
}
return 0;
}
146デフォルトの名無しさん:2005/12/18(日) 19:34:13
この程度でハングはしないと思うが、
同期とらない=ファイルの中身はグチャグチャになるの? 
って意味ならば出力されたファイルを読め。
147デフォルトの名無しさん:2005/12/18(日) 19:38:13
>>146
ファイルもぐちゃぐちゃになりません。きちんと出力されます
また、一度に書き込む文字列のサイズを100KB程度と大きくしてもきちんとと出力されます
しかし、どちらかのスレッドにSleep(0)等を入れる程度でぐちゃぐちゃになります

境界はどこに有るのでしょうか?
148デフォルトの名無しさん:2005/12/18(日) 21:36:48
ヒント:ストリーム系はバッファリングされるから混ざりにくい。
149デフォルトの名無しさん:2005/12/19(月) 00:03:34
fprintf-fcloseの間にスレッドが切り替わらなければセーフ。
んで、100回くらいのループではWindowsのタイムスライスに
引っかからなかったりするのでは。
マルチプロセッサなら、カナリヒドい事になりそうな気がするのだけれど。
150デフォルトの名無しさん:2005/12/19(月) 06:15:26
>>149
> fprintf-fcloseの間にスレッドが切り替わらなければセーフ。

そうとは限らない。
151デフォルトの名無しさん:2005/12/19(月) 10:16:27
>>148
「一度に書き込む」っていってんだから、
バファリングの有無は関係ないような気がするんだけど。
152デフォルトの名無しさん:2005/12/19(月) 21:48:15
そもそもハングするのか? ハングはしないだろ
153145:2005/12/20(火) 01:28:57
いろいろ調べてましたが
IO絡みの関数は基本的にスレッドセーフに作られてるから
ってのが答えみたいです
お騒がせしました

>>149
それは違います。たとえfcloseをコメントアウトしてもハングしません

>>152
ハングはしないようですね
このページに「大抵ハングしてしまいます」と書かれていて気になったのです
http://www.kumei.ne.jp/c_lang/intro2/no_106.htm
まあこのページに限らずネット上でマルチスレッドを初心者向けに教えているサイトでは
大抵同じような書かれ方がされてるので、
もしかすると私の検証が不十分なのかもしれませんが・・・

154デフォルトの名無しさん:2005/12/20(火) 04:36:05
同時に書き込んで壊れなくても
後からの書き込みで前の書き込みは上書きされて消える訳だが
155デフォルトの名無しさん:2005/12/24(土) 14:28:30
>>153
ランタイムライブラリがスレッドセーフで無い場合はハングするかもしれないけど、
VS2005からシングルスレッドのランタイムは無くなっているなあ。
156デフォルトの名無しさん:2005/12/24(土) 14:44:54
「ハングする」なんて言い方は止めて、
「動作が未定義」くらいにしてくれないか。
本当にハングアップするかどうかを問題にしているんじゃないだろ?
157デフォルトの名無しさん:2005/12/25(日) 13:24:46
>>156
このマニアめが。
158デフォルトの名無しさん:2005/12/25(日) 13:38:00
/MT ってやってればたいがい大丈夫だろうけど、スレッドセーフでない関数で
gethostbynameとかが未定の動作されるとかなり困る、
無理矢理排他同期とって使ってるけどなんかかっこ悪い。
159デフォルトの名無しさん:2005/12/25(日) 13:45:27
winsockのgethostbynameはスレッドセーフじゃなかったっけ?
160デフォルトの名無しさん:2005/12/25(日) 13:49:25
/MTってことはWindows?
getaddrinfoはMT-Safeでしょ。

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winsock/winsock/getaddrinfo_2.asp
には明記してないけど、gai_strerrorは違うから〜って書いているくらいだから。
161デフォルトの名無しさん:2005/12/25(日) 13:54:49
明記してあるな。

>Remarks
>The gethostbyname function returns a pointer to a hostent structure-a structure allocated by
>Windows Sockets. The hostent structure contains the results of a successful search for the
>host specified in the name parameter.
>The application must never attempt to modify this structure or to free any of its components.
>Furthermore, only one copy of this structure is allocated per thread, so the application should
                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> copy any information it needs before issuing any other Windows Sockets function calls.
162デフォルトの名無しさん:2005/12/25(日) 13:57:38
struct hostent *host;
host = gethostbyname(argv[1]);

ってな形だし、どうみてもスレッドセーフでないと思ってた。
スレッド固有メモリなんてものでも使ってるのかな。
163デフォルトの名無しさん:2005/12/25(日) 14:14:38
>>161
それだけでMT-Safeだとは限らない。
164デフォルトの名無しさん:2005/12/25(日) 14:50:26
getaddrinfo ってのがあるんだ、
参考にしてた本が古っかったので知らなんだ。
該当箇所を書きかえねば orz
165デフォルトの名無しさん:2005/12/25(日) 15:28:14
2ちゃんで書き込みするときの文字2048制限解除方法誰か教えてください。
166デフォルトの名無しさん:2005/12/25(日) 15:29:18
制限解除して書き込んでる人が増えてるんですが
167デフォルトの名無しさん:2005/12/25(日) 15:38:13
>>164
古いWindowsではありませんのでその辺は配慮を。
168デフォルトの名無しさん:2005/12/26(月) 03:11:55
「スレッドできる」と「スレッドでファイル操作しても問題ない」は同義じゃないよなあ。
単一リソース操作は対策しないと普通は競合するよ。
169デフォルトの名無しさん:2005/12/26(月) 19:09:27
マルチスレッドなサーバプログラムを作ってみようかと思ってます
クライアント数が少ない場合1クライアントに1スレッドを割り当てればいいかなと思いますが
クライアント数が多い場合はどういった方法が良いんでしょうか?
1スレッドあたりのクライアント数を決めてスレッドごとにselect()するとか
親スレッドでselect()して処理を別スレッドに任せるとか一応考えてはみていますが
どういった方法がスタンダードなんですかね?
170デフォルトの名無しさん:2005/12/26(月) 20:42:42
ジョブキュー
171デフォルトの名無しさん:2005/12/26(月) 22:37:27
+スレッドプール
172デフォルトの名無しさん:2005/12/26(月) 23:38:08
裏技としてApache
勉強にはならんな・・・
173デフォルトの名無しさん:2005/12/27(火) 13:56:11
apacheって何言ってんの?
ネットワークプログラミング相談室にも沸いたバカだろか。
174デフォルトの名無しさん:2005/12/28(水) 15:39:12
なぜそこで、あと半歩踏み込んで「apache馬鹿よね〜」とか言えないよねぇ
175デフォルトの名無しさん:2005/12/28(水) 16:51:48
おバカSunよね〜
176デフォルトの名無しさん:2006/01/02(月) 08:35:56
くだらない質問ですみませんが
TCPで同じディスクリプタにread()するスレッドとwrite()するスレッドを分けたとき
全二重だから同時にread()とwrite()を実行しても問題ありませんよね?
あと片方が同期無しでclose()するのって問題ありますかね
177デフォルトの名無しさん:2006/01/02(月) 08:40:05
同時にread/writeしても問題なし。
HTTPサーバのようなものを作ってるなら相手が一方的にclosesocketしたくらいでおかしくなっては困る。
178デフォルトの名無しさん:2006/01/02(月) 12:25:53
Solaris2.xではデッドロックしてたなあ(遠い目)
179デフォルトの名無しさん:2006/01/03(火) 03:50:46
x86 とかで int の値を書き込むスレッド(A)と読み込むスレッド(B)がある場合,
更新途中の値が(つまり 32bit 中の 16 bit が新しい値で残りが古いままとか)
B に見えてしまうということはありうるでしょうか?

# long とかだとまずいですよね.
180デフォルトの名無しさん:2006/01/03(火) 04:40:29
>>179
前スレで延々やってたと思う

そこが本題でなければ、排他で済ませて先行った方がいいと思うヨ
181デフォルトの名無しさん:2006/01/03(火) 04:56:02
>>180
レスありがとうございます.前スレの読み方がよく分からないので憶測になっ
てしまいますが,前スレの議論では結局「あり得る」という結論に至ったとの
理解で良いでしょうか?

参考になりそうな資料へのポインタを教えて頂けるとうれしいです.

> そこが本題でなければ、排他で済ませて先行った方がいいと思うヨ

性能的な面から可能な限り B に対する排他処理は避けたいと考えています.
182デフォルトの名無しさん:2006/01/04(水) 15:07:19
>>181
OSに用意されている、Atomicな書き換えAPIを利用すれば宜しかろう。
32ビットバスでアライメントも合っていれば素直にAtomicに書き換わると思うが。
183デフォルトの名無しさん:2006/01/04(水) 16:15:06
レスありがとうございます。調べてみます.
184デフォルトの名無しさん:2006/01/13(金) 02:07:27
マルチスレッドプログラミングで注意することを列挙してくれ。
185デフォルトの名無しさん:2006/01/13(金) 02:19:22
ひとつ!急いで口で吸え!
186デフォルトの名無しさん:2006/01/18(水) 14:53:41
ふたつ! 不埓な悪行三昧!
187デフォルトの名無しさん:2006/01/18(水) 16:18:23
みっつ! 想定の範囲内です。
188デフォルトの名無しさん:2006/01/18(水) 16:55:53
よっつ、読んでも書いちゃダメ
189デフォルトの名無しさん:2006/01/18(水) 16:56:28
いつつ、いつも心に排他処理
190デフォルトの名無しさん:2006/01/18(水) 16:59:48
むっつ、無理せずmutex
191デフォルトの名無しさん:2006/01/18(水) 17:21:48
ななつ、仲良くSemaphoeで共有
192>>46:2006/01/18(水) 23:32:09
やっつ、やっぱりここでも排他処理
193デフォルトの名無しさん:2006/01/19(木) 00:43:25
ここのつ!心を鬼にして排他処理
194デフォルトの名無しさん:2006/01/19(木) 01:03:03
糞スレ立てんな
195デフォルトの名無しさん:2006/01/19(木) 01:39:58
とう、でとうとう割り込まれた。

排他だけじゃなく、割り込み禁止も忘れないでね☆
196デフォルトの名無しさん:2006/01/21(土) 01:53:34
HANDLE hEvent = CreateEvent(NULL, TRUE, FALSE, NULL)で作ったイベントに対して
SetEvent(hEvent);←TRUEがかえる
でも、その次に
WaitForSingleObject(hEvent, 0)とやってもWAIT_OBJECT_TIMEOUTがかえる。
こういうことがおきているのですがどのようなことが考えられますか?


197デフォルトの名無しさん:2006/01/21(土) 07:15:10
>>196
SetEventは成功したけど、イベントオブジェクトがシグナル状態になる前にWaitForSingleObjectがタイムアウトした。
198>>46:2006/01/21(土) 09:16:54
>>196
他のスレッドが一生懸命 ResetEvent(hEvent) を
やってる。
199196:2006/01/21(土) 14:20:25
>>197
SetEventってシグナル状態にした後で戻るわけではないのですか?

>>198
ソースを見る限りほかのスレッドが触ることはなさそうなのですが確信持てないです。
SetEventとWaitForSingleObjectの間で他のスレッドにスイッチしなければそういうことはおきないですよね?
であれば確認のためにはスレッドのスイッチをSetEventとWaitForの間で抑制してあげればいいですよね。
なにか、任意のコードブロックではスレッドスイッチを禁止する方法はないでしょうか
200デフォルトの名無しさん:2006/01/21(土) 14:26:18
ちょっと確認だが、WaitForSingleObject()の第二パラメータの0ってNoWaitだよな?
単に待てば委員で内科医?
201デフォルトの名無しさん:2006/01/21(土) 14:42:02
>196のままのコードを実行してみたけど、ちゃんと0が帰ってきたよ。
202デフォルトの名無しさん:2006/01/21(土) 15:04:56
>>199
>>196の事象が事実であるなら、そういうものだと思って使うべき。
嫌なら別の手段を用いるべき。
203196:2006/01/21(土) 15:47:24
>>200
SetEventしてそれが本当にシグナルになったかを見るためにWaifFor・・したのですが、
それがなぜかシグナルになっていないのです。

>>201
検証ありがとうございます。>>196のままのコードだとそうなると思いますが、実際にはほかのスレッドもいるので
何が起きているかはよくわかっていません。(デバッガでステップ実行したりデバッグライトを入れるだけで動きが変わるため)


とりあえず、月曜にほかのスレッドがResetしていないか確認したいと思います

あとSetEventって非同期に動いたりしませんよね?
SetEvent(hEvent);
ここで誰かがResetEventしない限り下はTRUEにならないですよね?
if(WaitForSingleObject(hEvent,0)==WAIT_OBJECT_TIMEOUT)
{
}
204デフォルトの名無しさん:2006/01/21(土) 17:01:11
>>203
だから、WaitForSingleObject(hEvent, INFINITE)してみたら?
205デフォルトの名無しさん:2006/01/21(土) 21:15:12
そもそも、WAIT_OBJECT_TIMEOUTってなんだ?

成功:WAIT_OBJECT_0 or WAIT_TIMEOUT or WAIT_ABANDONED
失敗:WAIT_FAILED

のいずれかが、WaitForSingleObject()の戻り値なんだが・・・
とりあえず、該当部分のコードを晒せ、晒したくなかったらコピペも満足にできない房は二度とくんな。
206>>46:2006/01/21(土) 23:02:03
>>199
> ソースを見る限りほかのスレッドが触ることはなさそ
> うなのですが確信持てないです。

はぁ? 悪いけど、変数がどっからアクセスされるか自信
が持てないなんて言う奴にはマルチスレッドプログラムは
無理だよ。あきらめたら?

>>203 で、デバッガとか言ってるが君がやることは、デ
バッガでプログラムを追っかけることではなく hEvent
で全ソースに対して findstr することだと思う。
(そこらじゅうで hEvent 使ってるなら、問題のところ
の変数名を変えるべき。)

>>201
うちでも、CreateEvent() 〜 SetEvent() 〜
WaitForSingleObject() 〜 CloseHandle() を
10,000,000 回実行したが、WAIT_OBJECT_0 しか
返らないよ。

>>202
その考え方はおかしいだろ。
>>196 みたいな動きをするイベントなんて使い物にな
らないと思う。
207デフォルトの名無しさん:2006/01/22(日) 08:57:50
>>206
>>196 みたいな動きをするイベントなんて使い物にな
>らないと思う。
eventは許可するまで待たせておくことが目的の物だから、setは少しくらい遅れても良いと思う。
acquireI->releaseする同期モノのreleaseも同じ。
208>>46:2006/01/22(日) 10:13:10
>>207
少しってどれぐらい?
1秒なの? 1ms なの? 1μs なの?

他のスレッドに対して set の伝播が遅れるのは問題ない
けど、自スレッドに対して SetEvent() してからイベン
トがセットされるまでの間に「隙間」があるのは問題。

例えば、

SetEvent(hEvent); // hEvent は、ワーカースレッドか処理終了でセットする。
StartWorkerThread(); // 処理開始指示。
while(WaitForSingleObject(hEvent, 0) == WAIT_TIMEOUT){ // 終了したか?
 // 終了してないなら、他のことしてようっと。
}
(こんなプログラムは組むなと言う意見はまた別の機会に。)

と言うプログラムがうまく動かない。

動かないだけなら、まだしも下手するとうまく動いたり動
かなくなったりすると言う最悪パターンになる。

マルチスレッドプログラムやるなら「隙間」をもっと意識
できないとはまるよ。
209デフォルトの名無しさん:2006/01/22(日) 12:18:00
>>208
「こんなプログラムは組むな」
210デフォルトの名無しさん:2006/01/22(日) 12:45:43
>自スレッドに対して SetEvent() してからイベン
>トがセットされるまでの間に「隙間」があるのは問題。

いやだから、その隙間は無いんだって。
というか、先頭のSetEventはResetEventの間違いだよな、な。
211デフォルトの名無しさん:2006/01/22(日) 16:13:56
スレ違いスマソ

下のスレでマルチコアについて侃侃諤諤の論争してるんですけど、
みなさんはこれからのマルチコア時代についてどう捉えていますか?

Intelの次世代CPUについて語ろう 21
http://pc7.2ch.net/test/read.cgi/jisaku/1136822334/
212デフォルトの名無しさん:2006/01/22(日) 17:12:45
>>208
次にタスクスイッチが起こったときにsetしてくれればいい程度に思って使ってるね、私は。

>while(WaitForSingleObject(hEvent, 0) == WAIT_TIMEOUT){ // 終了したか?
普通スレッド終了の検知はスレッドのハンドルをWaitForSingleObjectの引数にする。
わざわざeventなんて作らない。
スレッドをプールするなんて言い訳は聞かない。

>>211
面倒なことはOSに任せて今まで通りにやる。
213>>46:2006/01/22(日) 20:04:17
>>210
すまん、勘違いだ。
セット側はさすがにちょっと考えにくいな。
(まあ、リセット側も無理矢理だが。)
ただ、セット側とリセット側で挙動が違うのはちょっと気
持ち悪い。

>>211
マルチコアって言ったって、マルチプロセサの一形態だろ。
別に何か変えないといけないのか?
専用のチューニングが必要になったらそのとき勉強するよ。

>>212
> 普通スレッド終了の検知はスレッドのハンドルを
> WaitForSingleObjectの引数にする。

スレッドの終了 ≠ 処理の終了

誰も、スレッドの終了の検知方法なんて聞いてないぞ。
最近知ったので、知ったかしたくなったのか?
214デフォルトの名無しさん:2006/01/22(日) 20:06:09
さーしったかしったかたーこうりんだー
さーしったかしったかたーこうりんだー
みぎあしくんひだりあしくん
215デフォルトの名無しさん:2006/01/22(日) 20:17:49
>>214
気が済んだか?
すっきりしたら、違うスレに行ってくれよな。
216デフォルトの名無しさん:2006/01/22(日) 20:27:26
>>213
>スレッドの終了 ≠ 処理の終了
そういうことを言いたかったのか。
217デフォルトの名無しさん:2006/01/22(日) 21:08:07
VC6.0でスレッドを生成するために、
_beginthreadexを使おうと思っていますが、
1プロセスあたりに生成できるスレッド数って
決まっているのでしょうか?
MSDNのCreateThreadのヘルプには、
2028との数字がありますが・・・
218デフォルトの名無しさん:2006/01/23(月) 00:53:27
スタック用のメモリ領域が1MB確保されるんじゃなかったかな
219デフォルトの名無しさん:2006/01/23(月) 00:57:58
そんなにスレッド作ってどうするの?
220デフォルトの名無しさん:2006/01/23(月) 22:02:30
特殊用途か設計ミスか勘違い
221デフォルトの名無しさん:2006/01/23(月) 22:48:39
>>217-220
まさに、その「設計ミス」(要は、バグ) で、
スレッド作りすぎてアプリケーションエラー
出しまくった俺が来ましたよ。

うちの環境だと、1600個位でおかしくなった。

ただスレッドを生成するのが、メーカー提供の
COM の中なので、生成する時にどんなエラー
が返ってきているかはよくわからん。
222デフォルトの名無しさん:2006/01/24(火) 14:21:13
なんじゃそりゃ(´・ω・`)
223デフォルトの名無しさん:2006/01/24(火) 23:34:23
>>196

例えば

1.CreateEvent の第2引数が FALSE(自動リセットオブジェクト)である
2.スレッドAが WaitForSingleObject(hEvent, INFINITE) している
3.スレッドBが SetEvent(hEvent) を呼び出す
4.スレッドAが待機状態から解放される
5.スレッドBが WaitForSingleObject(hEvent, 0) を呼び出す

こういう場合、他のスレッドが ResetEvent しなくても 5.は WAIT_TIMEOUT
を返すけど、CreateEvent の第2引数が TRUE なら WAIT_TIMEOUT を返すのは
おかしいね。
224デフォルトの名無しさん:2006/01/25(水) 20:29:21
WAIT_OBJECT_TIMEOUT
って書いてたことがばれて逃げてったやつに追い討ちかけんなよ。
225デフォルトの名無しさん:2006/01/27(金) 17:33:55
A.EXE と B.DLL があり、B.DLL が foo() という関数をエクスポートしており、
foo() は内部的に strtok 等の C ランタイム関数を呼ぶとする。

B.DLL 内部で _beginthread(ex) したスレッドの中で foo() を呼ぶのは当然問題
ないはずだけど、A.EXE が内部で CreateThread または _beginthread(ex) した
スレッドの中で B.DLL の foo() 関数を呼び出した場合、メモリリークするの?

B.DLL が DLL_THREAD_ATTACH/DETACH できちんとスレッドごとの初期化・後始末
をしていれば大丈夫そうな気がするんだけど、VC とか BC とかの C ランタイム
ライブラリはこの辺どうなってるんだろう。
226デフォルトの名無しさん:2006/01/27(金) 18:21:34
CreateThreadで作ったスレッドはCランタイムライブラリを使ってはいけない。
スレッド内部でCランタイムライブラリを使いたい場合は、_beginthreadexを使おう。
_beginthreadはVBみたいなもんだと思おう。

詳しくはMSDNライブラリを参照のこと。

ttp://msdn.microsoft.com/library/ja/vclib/html/_crt__beginthread.2c_._beginthreadex.asp
ランタイム ライブラリ リファレンス
_beginthread、_beginthreadex

ttp://www.microsoft.com/japan/msdn/library/default.asp?url=/japan/msdn/library/ja/jpdllpro/html/_win32_createthread.asp
プラットフォーム SDK
CreateThread

ttp://support.microsoft.com/default.aspx?scid=kb;ja;104641
C ランタイム(CRT)関数と CreateThread ()を使用するの、説明
227デフォルトの名無しさん:2006/01/27(金) 20:30:26
>>225
むしろ逆。
B.DLL内部で_beginthread(ex)したスレッドからA.EXE中の関数bar()を呼ぶとリークする。
ただしA.EXEがCRTとスタティックリンクしていて実行環境がWindows Server 2003より前の場合。
ttp://codezine.jp/a/article.aspx?aid=235&p=2#col4
CRTはソース公開されてるから気になるなら読むといいよ。
Express Editionだと付いてるか知らんけど。
228225:2006/01/27(金) 23:32:29
>>227
> B.DLL内部で_beginthread(ex)したスレッドからA.EXE中の関数bar()を呼ぶとリークする。

コールバック関数とかも、そのコールバック関数が自EXE で _beginthread(ex)
したスレッドから呼ばれないなら C ランタイムを使えないことになりますね。

>>227 の質問を繰り返すことになりますが、A.EXE 内部で _beginthread(ex) した
スレッドから B.DLL 中の関数 foo() を呼ぶのは大丈夫なんでしょうか。

DllMain の DLL_THREAD_ATTACH/DETACH はこのへんの問題を解決するための
機構だと思ってるので、きっと大丈夫なんだと自分に言い聞かせるようにし
てるんですが…。
229225:2006/01/27(金) 23:34:18
>>227
> CRTはソース公開されてるから気になるなら読むといいよ。

VC6 のソースを見る限りでは、DLL_THREAD_ATTACH/DETACH でスレッドごとの
初期化/後始末をしているようです。

CRT を使う DLL に関して、VC6 のソースを見た感じでは、その DLL が
C ランタイムをスタティックリンクしている場合は _DllMainCRTStartup 内で
DllMain を呼ぶ前に DisableThreadLibraryCalls を呼ばないようです。

MSVCRT.DLL を使用する場合は、ユーザー定義の DllMain がない場合のみ、
DisableThreadLibraryCalls を呼んでいるようです。DllMain があった場合、
DllMain 内部で DLL_THREAD_ATTACH/DETACH が必要になる可能性があるから
DisableThreadLibraryCalls を呼ばないようにしてるのでしょう。おそらく。

だから、EXE 側で作成したスレッド内で、DLL 側の C ランタイム関数を使う
関数を呼び出しても、DLL_THREAD_DETACH で後始末が行われるのでメモリリーク
は発生しないのではないかと思ってますが、それが明記されているドキュメント
が見当たらないので気になっています。
230225:2006/01/27(金) 23:36:13
EXE 側で作成したスレッド内で、DLL 側の関数(内部的に C ランタイム関数を
使うもの)を使えない(使うとメモリリークする)としたら、まともなマルチ
スレッドアプリケーションなんて開発出来ない気もします。

せめて malloc/free/new/delete くらいは問題なく使えるようでないと…。
でも、

http://support.microsoft.com/default.aspx?scid=kb;ja;104641

を見ると malloc も駄目みたいですよね…。実際のところどうなんでしょ。
231デフォルトの名無しさん:2006/01/28(土) 07:40:26
実際のところってもなあ
hackして怪我するのってあほらしくないか
232デフォルトの名無しさん:2006/01/28(土) 10:30:25
>>230
Cランタイム関数はスレッドなんてのが出来るまえのシロモノだからね。

漏れの知る限りでは、
リンクしてるCランタイムライブラリが同じでマルチスレッド対応なら、
EXEとDLLで相互に呼び合いとかしても別段問題ない。
なぜなら、Cランタイムが使う領域は_beginthread*()でスレッド生成時に
スレッドローカルに確保されて、そちらが使用されるから。
(→see AdvancedWindows)

ただし、_*thread*()はランタイムライブラリに含まれる関数だから、
異なるライブラリを混在すると問題になる場合がある。
MS libcmtとMSVCRTの混在も危険。
(→see MSDNの/MDあたりのオプションのヘルプ)
233デフォルトの名無しさん:2006/01/28(土) 10:43:44
>>230
それ英語版の方読めよ。機械翻訳で日本語として成立してない。
http://support.microsoft.com/?scid=kb%3Ben-us%3B104641&x=11&y=5

> スレッド内部でCランタイムライブラリを使いたい場合は、_beginthreadexを使おう。

> calling malloc(), fopen(), _open(), strtok(), ctime(), or localtime()

も問題なし。_endthreadex() が、CRT per-thread data-block を後始末してくれるから。
234225:2006/01/28(土) 14:56:16
ちょっと試してみました。

B.DLL
void foo(void)
{
  char dummy[256];
  strtok(dummy, "");
}

A.EXE
DWORD WINAPI ThreadProc(void *pvParam)
{
  foo();//B.DLL 内の関数
  return 0;
}

void test(void)
{
  HANDLE hThread;
  DWORD dwThreadId;
  int i;
  for(i = 0; i < 10000; i++){
    hThread = (HANDLE)CreateThread(NULL,
                    0,
                    ThreadProc,
                    0,
                    0,
                    &dwThreadId);
    WaitForSingleObject(hThread, INFINITE);
    CloseHandle(hThread);
}
}
235225:2006/01/28(土) 14:57:27
>>234 の続き
1.A.EXE: BCB5 で作成、B.DLL: VC6 libcmt.lib で作成
2.A.EXE: BCB5 で作成、B.DLL: VC6 msvcrt.lib で作成
3.A.EXE: BCB5 で作成、B.DLL: BCB5 で作成

結果:
1:DllMain で DisableThreadLibraryCalls を呼ぶとメモリリークする
  (test を呼ぶ度にメモリ使用量が増える)
  DllMain で DisableThreadLibraryCalls を呼ばなければメモリリークしない
  (test を何回呼んでもメモリ使用量は変わらない)
2:DllMain で DisableThreadLibraryCalls を呼んでも呼ばなくてもメモリリークしない
3:DllMain で DisableThreadLibraryCalls を呼んでも呼ばなくてもメモリリークする

ちなみに

void foo(void)
{
  char* dummy = (char*)malloc(128);// char *dummy = new char[128];
  free(dummy);// delete[] dummy;
}

の場合、どの場合においてもメモリリークしない
236225:2006/01/28(土) 14:59:56
>>235 の続き
結論:
BCB5/VC6 で作成した B.DLL においては、C ランタイムルーチンのうち、少なくとも
malloc/free/new/delete しか使わない分には、A.EXE で作成したスレッド内で B.DLL
の関数を呼び出してもメモリリークしない。スレッドの作成に _beginthread(ex) を
使う必要もない。

VC6 で MSVCRT.DLL とリンクする B.DLL では、A.EXE で作成したスレッド内で B.DLL
の関数(内部で C ランタイム関数を呼ぶもの)を呼び出してもメモリリークしない。

VC6 で libcmt.lib とスタティックリンクする B.DLL では、DllMain で
DisableThreadLibraryCalls() を呼ばなければ、A.EXE で作成したスレッド内で
B.DLL の関数(内部で C ランタイム関数を呼ぶもの)を呼び出してもメモリリーク
しないが、DisableThreadLibraryCalls()を呼ぶと、B.DLL が内部で呼び出している
C ランタイムルーチンによってはメモリリークする可能性がある。

他にも色んな組み合わせが考えられますが、とりあえず自分が知りたかった
「A.EXE で作成したスレッド内で B.DLL 内の関数を呼び出してもメモリリーク
しないのか」は検証出来ました。この程度の実験で検証出来たと断言して良い
のかはわかりませんが。

BCB5 の C ランタイムルーチンは DLL_THREAD_ATTACH/DETACH をきちんと処理して
いないものと思われます。BCB5 で作った DLL はマルチスレッドアプリケーション
からは使いにくいですね。

VC7 以降とか GCC とかではどうなんでしょうね。

検証の仕方が間違ってたらご指摘下さい。
237デフォルトの名無しさん:2006/01/28(土) 15:25:22
>>236
率直に言えば無意味な検証。
というのは、メモリリークだけが問題ではないから。

仮にメモリリークしていなかったとしても、
複数のスレッドで同時に1つのワークエリアを参照していれば、
各スレッドがお互いに1つのワークエリアをぶっ壊しあう。
喪前さんのやり方では、そのパターンが検出できない。

むしろ、メモリリークしている方が複数のスレッドで異なるワークエリアを作成している、
つまり不完全ながらもマルチスレッド対応しているという見方もできる。
(実際どうかは知らん。メモリだけ確保して1つのワークを壊しまくってる可能性もある)

つか、なんでCreateThread()で試してるんだ?
試すまでもなく駄目なの分かり切ってるだろ。
_beginthread*()ならまだわからんでもないが・・・。
238225:2006/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デフォルトの名無しさん:2006/01/28(土) 18:45:54
>>238
> マルチスレッド対応のランタイムでは、そのような問題は起こらないことが
> 保証されているものだと思ってました。

思うのは勝手だけど、正しい使い方をしないと正しい挙動はしてくれないよ。
この場合、_beginthread*()を呼ばないと、「正しい挙動」はしてくれない。
なぜなら、Cランタイムをスレッドセーフにする肝心の処理を_beginthread*()がやるから。

ついでに言えば、問題はB.DLLだけの話ではなくて、A.EXEのランタイムに
何を使ってるか? というのも重要。にも関わらず、>>235でその点に
一切触れていない点からも、喪前さんの理解が足りないことが伺える。
240225:2006/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デフォルトの名無しさん:2006/01/28(土) 20:54:27
とりあえず消えろ
242225:2006/01/28(土) 21:09:14
>>241

真面目に質問してるつもりなんですが、そういうのが伝わらない
あたりが 2ch のイヤなところですね。

どこかにこの件に関してきちんと解説したウェブサイトなり書籍
があればご紹介頂きたかったですがね。
243デフォルトの名無しさん:2006/01/28(土) 21:19:39
>>242
そういうのにいちいち気にしていたら駄目だよw

2chの使い方からまず学んだほうが有効に使えるかも。
当然俺のレスにもレスは要らないぞw(あってもいいけど
244225:2006/01/28(土) 21:40:13
>>243
やっぱりそうですか。(^^;

>>235 の結果から、(この検証が正しければ)メモリリークに関しては
処理系依存ということになったわけだし、ドキュメント化されてるわけ
でもないようだから、結局のところ結論なんて出ないんだろうな…。

「A.EXE で作成したスレッドから B.DLL の関数を呼び出すとメモリリークする」
のだとすると、Susie プラグインとか、自分ではメンテナンス出来ないプラグイン
方式の DLL を使うアプリをマルチスレッド化するのは非現実的ということになっ
てしまうのか…。ほとんどの DLL は C ランタイムを使用してるだろうから。

一度作成したスレッドはアプリが終了するまで使い回すようにするしかないの
だろうか…。なんか納得行かないな。
245デフォルトの名無しさん:2006/01/28(土) 22:06:40
Susieプラグイン使う様なサイズのアプリなら、
スレッドプール使えば"about 70-80 bytes"のリークなんて気にする必要ないのでは?

>>242
MSDNだろ。
246241:2006/01/28(土) 22:09:50
マルチスレッドプログラミングをしたことのない房でも225のような真面目なやつを馬鹿にできるんだから
2chって憂さ晴らしに最適だよな。
247デフォルトの名無しさん:2006/01/28(土) 23:06:33
248デフォルトの名無しさん:2006/01/29(日) 01:07:13
>>244
真面目におかしなことばっかり言ってるから相手したくなくなるんだよ。
依存するのは処理系自体ではなくライブラリだし、
アンドキュメントな実装に依存したコードを書くのは無謀。

漏れが言えることは、
「EXE・DLLの両方で同じライブラリ使ってれば、相互に呼び合いしても問題ない」
「泥沼に足突っ込みたくなければ推奨されてるやり方を使え」
それだけ。普通にMSVCRT使えばいい。

それ以上のこと知りたいなら、AdvancedWindowsなりMSDNなりCRTのソースなり
自分で読んで勉強してくれ。スレでいちいち書けるほど単純な話でもない。
249225:2006/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デフォルトの名無しさん:2006/01/29(日) 09:28:51
最後のはBorlandのドキュメント読まないと仕方ないでしょ。
使ったことないから、どういう事になっているのか知らないし、
それで仕様通りの利用かどうかもわからない。

いずれにせよ、サードパーティのDLL内で、
CreateThread()を多発してない限り、別に大きな障壁になることじゃないよね。
スレッドを多発する場合、スレッドプール使うのは鉄則だから。
251デフォルトの名無しさん:2006/01/29(日) 18:37:53
>>237>>239
やなやつだなあ。
まじめに答えてる振り装ってるが不快なことこの上ない。
252デフォルトの名無しさん:2006/01/29(日) 19:09:23
まあスレッドプログラミングなんてやってる香具師はそんな香具師ばっかりだから
253デフォルトの名無しさん:2006/01/29(日) 19:30:17
だから日本はだめなんだよな
254デフォルトの名無しさん:2006/01/29(日) 19:57:56
>>252
いっしょにすな!
255デフォルトの名無しさん:2006/01/29(日) 21:20:17
http://support.microsoft.com/?scid=kb%3Ben-us%3B104641&x=11&y=5
の"static"の使い方は違和感あるなあ。
"thread local"ってことだよな。実際は生存期間が"dynamic"だし。
256デフォルトの名無しさん:2006/01/30(月) 17:17:51
マルチスレッドでプログラムを作っているのですが、VisualC++6.0(SP6)でデバッグすると
しばらくするとフリーズしてしまいます。
フリーズというのは、VC++と実行しているEXEがまったく応答しなくなり、
さらにOSの反応がほとんどなくなる感じです。
ほとんどというのは、Alt+Tabぐらいは効くのですが、タスクマネージャーも起動せず
他のアプリも、しばらく動くのですがじきに応答がなくなります。
デバッグではなく、ただEXEを実行した場合は普通です。
OSはWindowsXPHome SP2で、まあ標準的な環境だと思います。
1つ怪しいのといえば、NortonAntiVirusですが、これに関しては
ほぼインストールしたてのWin2000SP4のマシンでやっても同じような現象が
起こったので、他のアプリが邪魔している、というわけでもなさそうです。
それなりに長いソースなので、同様の問題が発生する簡単なソースをコピペします。
257256:2006/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);
}
}
258256:2006/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);
259256:2006/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;
}
260256:2006/01/30(月) 17:30:36
thread_procの、while(1)のところにブレークポイントを設定し
F5を連打し何回かループさせると、いずれ固まります。
ひょっとしてプログラムに何か原因があるのでしょうか?
デバッグがままならないとなると開発が非常に困難です。
261256:2006/01/30(月) 20:19:40
WinXPで、ウィンドウズキー+Lで、ユーザーを切り替ることはできたので
別のユーザーからMSDEV.exeを強制終了すると、一応復帰できることが分かりました。
しかし、依然として非常に困っています。
もし以前こんな現象に見舞われたけど、こうして直したよ、とか
ここをこうしたらいいんじゃないの?っていうのがありましたらぜひ教えていただきたいです。
262デフォルトの名無しさん:2006/01/30(月) 20:32:17
osの再インストールしても直らなかったという、ほろ苦い思い出があるよ。
263256:2006/01/30(月) 21:32:25
>262
その後は結局どうなりました?
ひょっとしてマルチスレッドのデバッグは、VC++6.0でできないっていうのが
「仕様」なんでしょうか?
264デフォルトの名無しさん:2006/01/30(月) 21:52:07
Windowsを2000にするか、VisualStudioをバージョンアップしませう
265256:2006/01/30(月) 22:01:27
>264
Windows2000でもなりました。
VisualStudioをバージョンアップですか.... 高かったんですよね。
266デフォルトの名無しさん:2006/01/30(月) 22:26:40
>>256

私も Windows2000 から XP にアップグレードしてから似たような
現象が発生するようになりました。

VC++6.0 と BCB5 でそうなっていて、どちらもマルチスレッド
アプリケーションでなくても発生します。

なんか Window メッセージの送受信の応答がシステム全体でとてつもなく
遅くなる感じですね。バックグラウンドで音楽とか流していても、音楽は
普通に流れますが、ウィンドウの切り替えとかがものすごく遅くなります。
完全なフリーズじゃないだけに、諦めて電源を落とそうにも、落とすタイ
ミングに困ってしまうというか。

ttp://www.wg7.com/w2ktips/#CTFMON

これと似たような症状なんですが、私は試していません。言語バーが
使えなくなるのも困るので。

結構頻繁に起こるので辛いのですが、起こらないときは起こらないので、
そういうものだと思って諦めています。
267225:2006/01/30(月) 22:43:46
_beginthread(ex) の説明のところに、CreateThread だとメモリリークして
しまう C ランタイム関数の一覧でも書いてあれば良いんですけどね。

ttp://support.microsoft.com/?scid=kb%3Ben-us%3B104641&x=11&y=5

には malloc とか fopen でもメモリリークするようなことが書かれてるけど、
実際に試してみると、VC6/BCB5 どちらの場合もメモリリークしてるようには
思えないです。

ここに書かれてないものでは、rand() を使うとメモリリークしますね。
今回の呼び出しの結果が前回の呼び出しに依存するようなタイプの関数は
全滅なんでしょうね。
268256:2006/01/30(月) 22:55:37
>266
確かに今まで他のプログラムを組んでいるときにそういうことはありました。
しかし、今回はそれとはちょっと違うように思えるのです。
一度固まると、少なくとも20分ぐらいは待ってみたのですが復帰しませんでした。
しかも、ほぼ毎回起こります。

上のソースに何か問題点があるのでしょうか?
ウィンドウメッセージに応じて処理をするスレッド(最初に起動されたときのもの)
別に他の計算をするスレッドを別に作っています。
競合が起こっているのかと思い、上のような簡単な簡単なソースを書いてみたのですが
あれでも必ずといっていいほど起こります。
ちなみにWindowsMeでも起こりました。家のPC全滅です..
269266:2006/01/31(火) 00:34:55
最初は自分が書いたプログラムに原因があると思ってたのですが、
Web 上にある他人が書いたもののいくつかを自分の環境でコンパイル・実行
してもそうなるので、環境によるものだと思って諦めることにしました。

Windows2000 では問題なかったので、256 さんと私とでは状況が
少し異なりますね。マルチスレッドアプリケーションでなくても
発生しますし。お役に立てなくてすみません。
270デフォルトの名無しさん:2006/01/31(火) 01:33:38
オレもよくなる。ステップ実行しているとなんでもないところで固まってCtrl+Alt+Delをやって再起動とかやるが
まったく動かず、次にAlt+Tabで悪あがき。選択した窓から順に固まる。
最後電源長押し、するとmsdev.exeを終了しています、かなんかがでて、msdev.exeが終了するとほかもサクサク終わる。
もちろんまったく終わらないでそのまま固まることもある。
DLLで提供される関数をステップオーバーしたときに出るとか、なんか最初はそんなことを思っていたけど
そうでもないらしい。
271デフォルトの名無しさん:2006/01/31(火) 09:31:42
Windowsのスケジューラ糞馬鹿だから
タスクマネージャでMSDEV.EXEのプライオリティ上げろ。
272256:2006/01/31(火) 21:11:22
VisualStudio .NET 2003を入れてデバッグしてみたところ、簡単なものは
ほとんど固まらなくなりましたが(とはいえ、ごくたまに固まります)
開発しているプログラムは依然として固まるようです。
いまいちすっきりしないのですが、あまりこの問題にかまっている時間的
余裕も無いのでデバッグ時のみシングルスレッドで動くようにして
場当たり的な解決をすることにしました。
幸運にもあまり修正せずにすむに済みました。
依然として自分のプログラムに問題があるのかという不安はのこりますが...
266さんをはじめ、皆様、様々な情報提供ありがとうございます。
よくあることのようなので、少し安心しました。(していいのか!?)
273デフォルトの名無しさん:2006/01/31(火) 21:27:49
>263
imeだか関係の問題だったはず。
ttp://ww1.enjoy.ne.jp/~turikiti/knowledge/program/oboegaki.htm
の、マルチスレッドの注意点の項を参考にしてみては?
私は効果なかったんですが・・・
274デフォルトの名無しさん:2006/02/01(水) 01:56:10
257のコードで何にも問題は出なかったぞ。
F5押しっぱなしでも固まるどころか快調そのもの。
Dual Pentium III 1GHz, NT4.0 VC++ 6.0+Sp5
275デフォルトの名無しさん:2006/02/03(金) 16:12:33
>>256
デバッグモードでなぜかおかしくなるというWin個体は確かにある。
どうしようもない。マシン変えろ
276sage:2006/02/04(土) 00:23:14
VB6.0でActiveX DLLを使用し、マルチスレッドを実現できるという噂を聞いたのですが
本当ですか?

でもイメージが掴めない・・・
VBでActiveXコンポーネント「A」を呼び出し

A作成→A何らかの処理
      ↓
VBの処理←A処理終了

VB次の処理

って感じでマルチスレッドとは違う気がするんですが・・

もし本当であれば、どなたか参考になるサイトをご教授頂けませんでしょうか
277デフォルトの名無しさん:2006/02/04(土) 01:43:21
278デフォルトの名無しさん:2006/02/04(土) 08:38:15
>>276
DLLの中はC++で書けばなんでもやり放題なんじゃね?
DLLの中でクリートスレッド
279デフォルトの名無しさん:2006/02/04(土) 09:02:03
>>278
クリートスレッドってなに?
280デフォルトの名無しさん:2006/02/04(土) 09:39:29
CreateとDeleteの合成語だろ
スレッドを作ったら自分で閉じろってことだ
281デフォルトの名無しさん:2006/02/04(土) 12:14:10
>>276
ActiveX のコンポーネントとして作成した DLL/EXE が
スレッドセーフだ、ってだけじゃね?
282デフォルトの名無しさん:2006/02/04(土) 12:20:51
何をしたいのかしらんが
COMのスレッドは楽しいぞ
283デフォルトの名無しさん:2006/02/06(月) 19:46:27
CreateThreadをクリートスレッドって読んだんだろ。
馬鹿みたいだが。
284デフォルトの名無しさん:2006/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の四つだけ作ればいいんでしょうか?どなたかご教授下さい。
285284:2006/02/11(土) 07:43:18
ちなみにセマフォは「なし」の方向でお願いします。
286デフォルトの名無しさん:2006/02/11(土) 07:47:19
日本語で質問してください
287デフォルトの名無しさん:2006/02/11(土) 08:44:23
>>284
Chain Of Responsibility パターンはもう検討済みなの?
288デフォルトの名無しさん:2006/02/11(土) 10:21:28
>>284
4つじゃないとダメなわけもないし、好きに作ればいい
289デフォルトの名無しさん:2006/02/11(土) 12:09:10
各々理由を書いてね。

> 今度はB自身が消費したことをB自身に知らせなくては
> ならなくて

> ちなみにセマフォは「なし」の方向でお願いします。
290デフォルトの名無しさん:2006/02/11(土) 18:57:50
>>289
正確厨、規格厨、口先厨の予感。現状提示されている情報から
回答が思いつかなければ、その問題に対する類似性や経験則
など思い当たるところが無いっつーことだろ。

全部の情報が分からないとコミュニケーションできないような
応用力無しやつは黙ってろ
291デフォルトの名無しさん:2006/02/11(土) 19:56:02
>>9
Double Checked Lockingに追加

Scott Meyers & Andrei Alexandrescu
"C++ and The Perils of Double-Checked Locking (II)"
http://erdani.org/publications/DDJ_Jul_Aug_2004_revised.pdf

付録に"volatile: Brief History"あり。

Douglas C. Schmidt & Tim Harrison
"Double-Checked Locking
An Optimization Pattern for Efficiently Initializing and Accessing Thread-safe Objects"
http://www.cs.wustl.edu/~schmidt/PDF/DC-Locking.pdf
292デフォルトの名無しさん:2006/02/11(土) 21:48:09
>>290
エスパー以外は黙れと。
293291:2006/02/11(土) 22:33:21
せっかく流れ切ったのに…
294デフォルトの名無しさん:2006/02/11(土) 22:58:43
>>290
やんわりと、「設計がおかしいんじゃないか?」と言われてるんだよ。

まあ、もうまともな回答は期待できないだろうからどうでもいい話だが。
295284:2006/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デフォルトの名無しさん:2006/02/12(日) 05:05:21
ここでは綺麗でも汚くても叩かれますYOW
297デフォルトの名無しさん:2006/02/12(日) 05:06:03
誤爆した スマン...
298デフォルトの名無しさん:2006/02/12(日) 07:55:32
>>294
その「やんわりと」の部分が他人をイラつかせるんだよ。現実でも
相当にいやみな人間だろう
299デフォルトの名無しさん:2006/02/12(日) 08:00:36
>>292
そこまで行間が読めないようだと生きるのに苦労してないか?
300デフォルトの名無しさん:2006/02/12(日) 08:14:33
>>299
292は皮肉で言っただけだから、普段は別段苦労はしてないな。
301デフォルトの名無しさん:2006/02/12(日) 11:03:26
この業界、日本語の喋れない奴ばかりだからエスパー能力は必須だよね
低級エスパーだから日々苦労してるよ
302デフォルトの名無しさん:2006/02/12(日) 11:38:10
エスパーってほどか? そうじゃなくてだな、俺の言いたいことはだ、

類似の問題を経験していたら回答が思い浮かぶだろ。素直に
それ書いてやりゃいいんだ。お前らだって今まで誰かに教えて
もらったり助けてもらったことあるだろうに。

それを忘れてくだらねー皮肉や、重箱の隅をつつくようなまぜっかえしを
親切を装ってやるようないやらしいことすんなよ。ナサケナス
303デフォルトの名無しさん:2006/02/12(日) 11:48:06
別に2chで教えようと混ぜっ返そうとどっちでも構わんと思うのだけど。
まぁ、ヒントだけ貰った方がいい場合と答丸ごと貰った方がいい場合があるのでどっちがいいとも言えないしね。
漏れはここのスレでは教えることも教わることも少ないけど、この板全体では教わることより教えることのほうが多くなるようにしている積もりだがね。
混ぜっ返したり揶揄したり誘導したりも多いけどw
304284:2006/02/12(日) 12:23:35
で、あのー・・・
305デフォルトの名無しさん:2006/02/12(日) 12:28:35
生産者消費者問題くらい、標準的なテキスト読んで自分でやれ
306284:2006/02/12(日) 12:37:41
テキストには生産者消費者が一対一の例しか載ってないんですよ。
こんなに真剣に質問してるのになんでこんな目に遭うんだ…
世の中絶対におかしい。
307284:2006/02/12(日) 12:38:49
丸投げでもなく真剣に書いてるのに…もう馬鹿馬鹿しくて泣けてきた…もういいです。
308デフォルトの名無しさん:2006/02/12(日) 12:57:25
なんで、consumerBとproducerBが別オブジェクトなわけ?
ふつうは入口と出口のある1つのオブジェクトとして考えるでそ?
309デフォルトの名無しさん:2006/02/12(日) 13:03:48
お前らかわいそうだから教えてやれ。おれは良く分からないのでパス。ごめん
310デフォルトの名無しさん:2006/02/12(日) 13:05:39
レベル1エスパーだけど、

>>284
>> ConveyerBelt()バッファーが三つというのは正しいと思うんですけど
>> スレッドはABCDの四つだけ作ればいいんでしょうか?どなたかご教授下さい。

唯一の正解があると思ってるのか?好きにつくれよ


311デフォルトの名無しさん:2006/02/12(日) 13:06:34
>>306
質問する相手を間違えているだけだろう?
世の中がおかしいのではないと思う。
312デフォルトの名無しさん:2006/02/12(日) 13:11:45
普通はレスの付き方を見て、質問の仕方が悪いと思うんだけどね
313デフォルトの名無しさん:2006/02/12(日) 13:17:51
>>284
漏れも>308の言うとおりだと思う。
つか、めっちゃ単純な問題だと思ってたから
まさかconsumerBとproducerBが別だと思ってなかったw
あらためてソース見直してみてビックリした。

> ですから現在はA-B間、B-C間、C-D間のみで同期がされてます。 
それでいいんじゃないの?他に同期取らなきゃいけないの?セマフォもいらんと思うけど。
314デフォルトの名無しさん:2006/02/12(日) 13:30:26
>>313
> 他に同期取らなきゃいけないの?

知りもしないのに、

> セマフォもいらんと思うけど。

云うな(w
315デフォルトの名無しさん:2006/02/12(日) 13:43:39
うん、ごめん。よくわかってなかったわ。
最初ConveyerBeltの作り疑ってたもんな。
危うく恥かくとこだった。
316289:2006/02/12(日) 13:51:11
俺も、>>308 に同意。
だから、
> 今度はB自身が消費したことをB自身に知らせなくては
> ならなくて
は、何か勘違いしてんじゃないかと思って、>>289 を書
いてる。はじめのうちは、(俺も含めて) 結構とんでもな
い勘違いをすることがあるから、別にそれがおかしいとは
思わないけど、何を考えてるかわからんと情報を提供して
あげることもできないから。

あと、>>306-307 が本人かどうか知らんけど、「真剣に
質問」したのにまともな答えが返ってこないと言うが、
匿名掲示板に質問すること自体が既に「真剣に質問」して
いるとは言えない。回答する方は、あくまでも知ったかし
たいか暇つぶしか昔の恩を返したいかなんだから、「真剣
に向き合え」とか言われたら、「なんちゃ、それ。」で無
視されるのがオチ。

この板の人は基本的に親切だから、嘘は余り書いてない。
>>290 みたいな雑音を飛ばしてよく読めば、きちんと
ヒントは書かれているから、自分でググルなりすればいい。

そのものズバリの答えが欲しいなら、本を買うなり学校に
通え。
317デフォルトの名無しさん:2006/02/12(日) 14:14:03
実質何も答えていないのを繰り返してるだけじゃね?
318デフォルトの名無しさん:2006/02/12(日) 14:19:02
答える側が堂々巡りするケースのほとんどは、
質問がいい加減なことに起因する。
319デフォルトの名無しさん:2006/02/12(日) 15:40:49
320289:2006/02/12(日) 15:47:02
>>317
まあ、確かにそのものズバリの回答は無いけど、>>287,
>>308 あたりは、充分ヒントになりうると思うが。

個人的見解として、このヒントを基に自分で勉強するぐら
いでないとマルチスレッドのプログラミングはできないと
思う。
321デフォルトの名無しさん:2006/02/12(日) 19:56:19
変なところで改行するなよ
醜い
322デフォルトの名無しさん:2006/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デフォルトの名無しさん:2006/02/14(火) 23:01:34
>>322
> ConveyerBelt NULL = new ConveyerBelt();
> ConveyerBeltクラスん中ではinとoutの二つのbufferを作ってやれ。

馬鹿ジャネーの。
324デフォルトの名無しさん:2006/02/15(水) 00:03:38
>>323
自分の事を良く解ってるじゃないかw
325デフォルトの名無しさん:2006/02/15(水) 00:15:31
俺も
> ConveyerBeltクラスん中ではinとoutの二つのbufferを作ってやれ。
は意味わかんねえ。ConveyerBeltなのに何か処理でもするの?
326釣りだったのかも...。:2006/02/15(水) 01:13:37
>>325
多分、in と out の buffer を取り持つ ConveyerBeltSub
を作るんだよ。

もちろん、その中には buffer が二ついるから、更に
ConveyerBeltSubSub を作って...。(w

# >>322 = >>324 は、基礎から勉強しなおした方がいいぞ。
327デフォルトの名無しさん:2006/02/15(水) 01:48:57
buffer1個でいいでしょ
328デフォルトの名無しさん:2006/02/15(水) 03:43:24
どうでもいいけどなんで4つとも別スレッドで独立して動かす必要がるわけ?
全体としてどんなことをしたいのか今一想像がつかん。
329デフォルトの名無しさん:2006/02/15(水) 15:13:36
あらあら、もう一人馬鹿↑が来た

お前、流れ作業って言葉聞いたことあるか?
330デフォルトの名無しさん:2006/02/15(水) 15:20:00
>Aが物を作るとBに渡し、Bが物を作るとCに渡し、Cが物を作るとDに渡す、というように
>複数の生産者/消費者のベルトコンベヤーでの流れ作業を想定しています。

>>327
お前の読解力は小学生以下か?
buffer一つで出来るもんならやってみろ、馬鹿。
出来ないんならもう来るなよ、ここではお前は邪魔なだけだから。
331デフォルトの名無しさん:2006/02/15(水) 16:06:16
パイプ1個あたりバッファ1個の意味で言った
言葉足らずというか全然意味が通らないねスマソ
332デフォルトの名無しさん:2006/02/15(水) 18:06:14
Java よく知らんのだが、これは要するに
4つのスレッドを3つのキューで繋ぎたい、って「だけ」の話?
333デフォルトの名無しさん:2006/02/15(水) 18:34:54
YES
334デフォルトの名無しさん:2006/02/15(水) 21:04:57
>>329
いやそうじゃなくてどんな処理で4スレッドの流れ作業なんて必要になるのか
想像がつかんのだ。
335デフォルトの名無しさん:2006/02/15(水) 23:29:55
マルチ商法ですた
336デフォルトの名無しさん:2006/02/15(水) 23:46:26
そんなもの想像つかなくていい。
質問に答えりゃそれでいいんだ
337デフォルトの名無しさん:2006/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デフォルトの名無しさん:2006/02/16(木) 01:58:33
>>333
d楠。
たったそれだけの事で、こんだけ盛り上がれるなんて
なんの病気なんだ…

>>334
それを実現する手段を知るためじゃね?演習問題みたいな。
339デフォルトの名無しさん:2006/02/16(木) 09:57:05
>>332
たぶんそう。それなのにbuffer二つとか言い出す奴もいて…
そもそも質問があれだし。
340デフォルトの名無しさん:2006/02/17(金) 12:51:20
みんなコロンブスの卵って知ってる?

「コロンブスの卵」は、「誰にできることでも、最初にするのが難しい」という意味で使われる。
1492年にアメリカ大陸(西インド諸島のサンサルバドル島といわれている)を発見したことで有名なコロンブス。
その功績を祝う晩餐会で、ある男が言った「西へ西へと航海して陸地に出会っただけではないか」と言った皮肉に
対して、コロンブスは卵を取り上げ、「この卵を卓の上に立ててごらんなさい」と言った
だれも立てられないのを確認するとコロンブスは、卵のおしり(気室のある鈍端部と思われる)を食卓でコツンとた
たいて立てて言った。「人がした後では何事も簡単です」

>>332
で、その「だけ」の話を理解できなかったのはどこの馬鹿だったっけ?( ´,_ゝ`)プッ
341デフォルトの名無しさん:2006/02/17(金) 13:03:35
なにこの馬鹿…
342デフォルトの名無しさん:2006/02/17(金) 13:13:45
ああ!この↑馬鹿か、その「だけ」の話を理解できなかったのは!
343デフォルトの名無しさん:2006/02/18(土) 00:44:40
文章から頭の悪さが滲み出ている。
344デフォルトの名無しさん:2006/02/18(土) 12:29:01
↑「だけ」の話を理解できなかったのが相当悔しかったんだね。( ´,_ゝ`)プッ
345デフォルトの名無しさん:2006/02/18(土) 16:24:11
なんか雰囲気が悪くなってきたな。
元に戻そうぜ。

これって
Aの生産量≦Bの生産量≦Cの生産量
だよね?でないとCとかDとかが結構待たされるんじゃないのかなーと。
346デフォルトの名無しさん:2006/02/18(土) 21:50:29
↑何もわかってない奴の典型だな!
347デフォルトの名無しさん:2006/02/18(土) 22:38:57
と、必死。
348デフォルトの名無しさん:2006/02/18(土) 23:57:11
荒している馬鹿は、>>322の阿呆レスした奴?
349デフォルトの名無しさん:2006/02/19(日) 03:12:23
ここにいるのは馬鹿ばっかだな
350デフォルトの名無しさん:2006/02/19(日) 03:15:52
>>345
ふいんき(←なぜか変換できない)戻そうと必死なのは分かるが
流れ作業なので

Aの生産量=Bの生産量=Cの生産量
351332=338:2006/02/19(日) 03:40:54
荒らしの相手はやめようや。

>>334
今思い出したが、以前C++ on Windowsで似たような構成にしたことあったわ。
その時は通信スレッド×20→データベーススレッド×2→印刷スレッド×1だったが
キューとミューテックス(各1)で小さいクラス作ったような覚えが。
352デフォルトの名無しさん:2006/02/20(月) 04:08:06
>>350
なんで?
極端な話、Aが2つの整数を流してBがそのxorを流したら半分じゃん。

まぁ別にそんなのはどうでも良くて、
単に4つスレッドを作らなくちゃいけない状況を想像して見たかっただけ。
邪魔してすまん。
353デフォルトの名無しさん:2006/02/20(月) 21:16:12
10メガくらいのメモリをコピー(memcpyとか)するときに、
領域を分割してマルチスレッドにしたら速度上がる?

マルチコアとかマルチスレッディングなら上がるかな?
354デフォルトの名無しさん:2006/02/20(月) 22:57:06
memcpy()だったら変わらない希ガス
fread()とかで、あるスレッドでHDDからデータ読み込み中に、
前回読み込んだデータ解析を行うとかだったらスループットはあがると思う。
355デフォルトの名無しさん:2006/02/21(火) 11:30:13
>>353
CPUが速ければ、
キャッシュを含めたバスシステムがボトルネックになるまでは上がる。
システム依存だから自分のターゲットにしているヤツで試してみて。
356353:2006/02/22(水) 08:10:39
ありがとう。
でも本当はそんなメモリコピーしない設計にするのがいいんだよなorz
357デフォルトの名無しさん:2006/02/22(水) 21:31:45
じゃあ、なんでそんな設計にならざるを得なかったのか、説明してみればいいじゃない。
メモリ参照だけで済むアルゴリズムを誰かが教えてくれるんじゃない?
358デフォルトの名無しさん:2006/02/22(水) 22:06:40
writeで例外起こすようにしてcopy-on-writeだ
359デフォルトの名無しさん:2006/02/23(木) 02:58:53
設計したのは赤の他人。
ワタシはメンテ担当(涙)
360デフォルトの名無しさん:2006/02/23(木) 17:25:34
>>359
その赤の他人よりも上手に設計できたとおもう?
361デフォルトの名無しさん:2006/02/24(金) 00:01:14
何このウスラ馬鹿な突っ込み
362デフォルトの名無しさん:2006/02/26(日) 01:05:49
>>359
設計思想もわからん個所を、色々チューニングしようとしてるの?

悪いことは言わないから「やめとき」。
363デフォルトの名無しさん:2006/02/26(日) 01:08:10
仕事じゃしょうがないよな。
364デフォルトの名無しさん:2006/03/03(金) 07:10:31
UNIXでC++なんですが、ttp://d.hatena.ne.jp/yupo5656/20041011/p3 ここに載っている、
スレッドローカルストレージを使ったシングルトンの実装って安全でしょうか?
だいたいこんな感じになってます。

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デフォルトの名無しさん:2006/03/03(金) 12:00:38
ISO C++の範囲内でポータブルな実装はないんだ。
>>291を読め。
366デフォルトの名無しさん:2006/03/03(金) 23:44:47
>>364
安全ですよ。
getInstance_(void) が既に安全なわけで、
tsd_instance の方は覚えとくだけで、
かつ単一スレッドからしか参照されないので。

メモリモデルの問題については、
たぶんscoped_lock の解放でメモリバリアも処理されるんでしょう。
(pthread のドキュメント呼んでないのであてずっぽう)
367デフォルトの名無しさん:2006/03/04(土) 22:28:46
>365
364はDCL関係ないじゃん
368デフォルトの名無しさん:2006/03/04(土) 22:52:17
>>366
POSIXではmutexの開放はメモリバリア。
369デフォルトの名無しさん:2006/03/05(日) 00:20:02
>>364 例の http://www.nwcpp.org/Downloads/2004/DCLP_notes.pdf
の最後のほうに
> 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のようには使ってないのが気になります。

一方、
http://www.cs.umd.edu/~pugh/java/memoryModel/archive/0670.html
でDoug Leaさんが364方式のTLSの使い方に文句を言っていない(条件
付きながら)ので大丈夫な気もします。まぁ、かなり昔のML投稿ですけど
ね・・。

さて真相は?
370デフォルトの名無しさん:2006/03/06(月) 16:07:01
>>340
普通の卵は比較的簡単に立つよな。表面に凹凸があるから。産みたてほど立ち易い。
・・・コロンブスは卵をツルツルに磨き上げていたに違いない。
371デフォルトの名無しさん:2006/03/06(月) 17:35:06
>>370
まあまあ。
コロンブスもギャグで言っただけなんだから許してやってくれ。
372デフォルトの名無しさん:2006/03/06(月) 19:33:03
後世の作り話ですから。
まあ>>340は底抜けの馬鹿だけど。
373デフォルトの名無しさん:2006/03/07(火) 14:35:11
ゆで卵にして高速で回せば立つよ。
まあ>>372は底抜けの馬鹿だけど。
374デフォルトの名無しさん:2006/03/07(火) 14:57:53
盛り上がっているところ、横から突っ込んでスマンけど。

生卵を立てるには塩をごく少量盛って、その上に立てて、横から
息をゆっくり吹きかけて塩を飛ばすといいという話を聞いた。

とかいう本当にどうでもいい話をマルチスレッドスレでする
自分は底抜けの馬鹿ですw
375デフォルトの名無しさん:2006/03/07(火) 19:27:05
つまり塩スレッドに卵スレッドをロックさせれば桶?
376デフォルトの名無しさん:2006/03/08(水) 10:03:12
卵スレッド発見
377デフォルトの名無しさん:2006/03/08(水) 20:55:31
つまらんよ >>369-376
378デフォルトの名無しさん:2006/03/08(水) 21:34:40
君ほどでも
379デフォルトの名無しさん:2006/03/08(水) 23:26:59
ゆで卵の殻を剥かずに塩をかけるなんて、底ぬけの馬鹿ですね
380デフォルトの名無しさん:2006/03/09(木) 03:03:29
観光地のゆで卵は全部そうなってるよ
381デフォルトの名無しさん:2006/03/09(木) 03:09:09
>>379
卵殻はNa+イオンもCl-イオンも透過するのでちゃんと卵に塩味がつきます。
溶けさえすれば。
382デフォルトの名無しさん:2006/03/09(木) 15:12:11
※注意: このスレはこの卵ネタで1000まで引っ張る覚悟です
383デフォルトの名無しさん:2006/03/09(木) 15:22:01
たまごが立つという状態を定義してください。
384デフォルトの名無しさん:2006/03/09(木) 16:21:34
ブスの卵
385デフォルトの名無しさん:2006/03/09(木) 17:20:48
>>383
案1:
水平方向の任意の角度から卵を投影したときに、水平方向のスパンよりも鉛直方向のスパンの方が長い状態。
ただし卵が他の物体と接することができるのは下部のごくせまい部分のみとする(←うまい定義できないなこれ)
386デフォルトの名無しさん:2006/03/09(木) 20:48:52
ポテンシャルの極大点。
387デフォルトの名無しさん:2006/03/09(木) 21:13:15
あ、あんたなんかにたたれてもうれしくないんだからねっ!
388デフォルトの名無しさん:2006/03/10(金) 00:28:56
>>383
おまいはコンピュータか? んなもん定義しないでも分かるだろ
389デフォルトの名無しさん:2006/03/10(金) 03:03:47
クララが立った、と言う状態を定義してください。
390デフォルトの名無しさん:2006/03/10(金) 03:04:39
精神的な自立
391デフォルトの名無しさん:2006/03/10(金) 03:21:15
それで泣ける、という状態を定義してください。
392デフォルトの名無しさん:2006/03/10(金) 08:40:40
クララが勃った、と言う状態を定義してください。
393デフォルトの名無しさん:2006/03/11(土) 18:55:33
クララが勃った
クララは女である
∴よって勃ったのは乳首である
394デフォルトの名無しさん:2006/03/11(土) 19:03:44
class clitoris extends electiliable {
395デフォルトの名無しさん:2006/03/12(日) 11:42:52
>>394
なんだ、選挙にでも出るんか?













…それを言うならerectibleだろ。
396デフォルトの名無しさん:2006/03/12(日) 16:25:47
Win32
Administrator権限で実行されてるプロセスからスレッドを起こすとき、
スレッドそれぞれに異なるユーザー権限を設定することは可能?
プロセスごとならできるんだが。もし可能ならAPI名などヒントを頼む。
397デフォルトの名無しさん:2006/03/12(日) 16:54:30
インパーソネーションとかいうんだっけ?
ImpersonateLoggedOnUserとか。
まー、RevertToSelfとか呼ばれると、元に戻るけどね。
398デフォルトの名無しさん:2006/03/12(日) 21:06:38
>>397
ありがd。
まだ試せてないが、MSDNの説明から目的に適うAPIのよう。
399デフォルトの名無しさん:2006/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デフォルトの名無しさん:2006/03/15(水) 14:42:42
一応ageとく。
401デフォルトの名無しさん:2006/03/15(水) 14:54:45
>>399
1つのスレッドで順番に動かしたいのか?
MyJob.run() と Job.run() を別のスレッドで動かしたいのか?
MyJob と Job のインスタンスをそれぞれ作ったらいけないのか?

402デフォルトの名無しさん:2006/03/15(水) 15:48:21
>>401
ありがと。
二番目の「別のスレッドで動かしたい」かな。
run()直接アクセスするとあかんのよね、.startで始めないと?
どうしようかな?
403デフォルトの名無しさん:2006/03/15(水) 16:35:55
>>402
その手法が可能かどうかの前に、やろうとしていることに対して
もっと単純な方法や、別の解法が無いか検討したらいいんじゃ
ないかな。

ちょっと言語(Java?)の使い方から外れているみたいので、
本当にやりたいことが妥当かどうか見極めた方がいいと思う。
404デフォルトの名無しさん:2006/03/15(水) 22:37:56
>>399
super.run();
405デフォルトの名無しさん:2006/03/16(木) 09:59:17
>>403
確かにそうだったかもしれん。ありがと。

>>404
いや、直接run()にアクセスするのは禁(ry
406デフォルトの名無しさん:2006/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デフォルトの名無しさん:2006/03/16(木) 20:44:16
mutexがすでに死んでるとか?
408デフォルトの名無しさん:2006/03/16(木) 22:30:14
Windows Threadについて質問です。擬似コードですが、
Thread[] threads = getAllThread();
foreach (Thread t; threads) {
t.suspend();
}
このような全てのスレッドを止めるためのループがあるとします。
このループ中では、既に止められているスレッドと、
これから止められる予定のスレッドがあると思うのですが、
これから止められる予定スレッドが、既に止めたスレッドを再開(resume)するため、
このループでは全てのスレッドを止められない、ということは起こりえるのでしょうか?
409デフォルトの名無しさん:2006/03/16(木) 22:36:16
>>408
起こりうるでしょうね。
避けたいのならばまず自分の優先順位をトテモ高くして、
その後ループに入れば良いと思います。

先方のスレッドも優先順位を上げている恐れがあるのならば
完全ではありませんが。
410デフォルトの名無しさん:2006/03/16(木) 22:36:36
知らね。

だって、普通そんな造りにしないもん。
普通は、終了しろ、っていう合図を各スレッドに送って
自主的に終了なり中断なりするのを待つだけだから。
411デフォルトの名無しさん:2006/03/16(木) 22:37:03
起こりえる。
おまけにこれから止めようとするスレッドが新たにスレッドを作るかもしれない。
全スレッドで、「スレッドマネージ用ミューテックス」などを使用すればいいんでない?
412デフォルトの名無しさん:2006/03/16(木) 22:39:04
他のスレッドを suspend するってのはまず間違いなく設計ミス。
C のランタイムとか Windows に用意されているいろんな dll の
内部まで良く知っていて、何か大事なものの所有権を持ったまま
suspend されちゃったりすることはないと確信を持っているなら
別だけど。
413408:2006/03/16(木) 22:46:12
どうも。
実は、これのpause版とresume版がD言語の標準ライブラリの中にあって、
GCを呼ぶ前にそれでスレッド止めて、後に再開ようとしているみたいなのですけど、
それのへんでアプリケーション側で実装しているスレッドの同期が変になるみたいです。
安心できませんが、安心しました。
414408:2006/03/16(木) 22:52:58
スレッドを止める仕様はどうしようもないのですが、
とりあえずは、全てを止めるループ中(pauseAll)に
pause()、resume()とstart()が実行されないように排他とと
全てを再開(resumeAll)中に、resume()が実行されないように
排他したら大丈夫ということでしょうか?
415デフォルトの名無しさん:2006/03/16(木) 23:01:54
>>414
GC 側が単純なメモリ操作などだけで、
他の処理で使っている(かもしれない)セマフォやミューテックスなどの
所有権なしで実行できるとするなら、問題ないはず。

例えば(MSのドキュメントを信用するなら)Windows API の OutputDebugString は、
内部で他のスレッドを全て Suspend した上でデバッグメッセージの送信を行い、
そののち Resume する、と同様の処理を行っているようです。

AP側のスレッドが変になるのはAP(or Dの何か他のライブラリ)のバグではないでしょうか。
416408:2006/03/16(木) 23:28:41
>>415
resumeThreadの戻りを見ながら、他スレッドのsuspend待ちをしている箇所があるので、
それが、排他されていないresumeAll中に走ると、
GCが止めてこれから再開する予定のスレッドを、
"アプリケーションが思っている理由"でsuspendしたのだと
勘違いして変になるのだと思っています。
417デフォルトの名無しさん:2006/03/17(金) 06:51:35
>>407
ありがとうございます。
pthread_mutex_destroy は呼んでいないので生きていると思っていたのですが、どうやら
syslog(3) が関係しているようです。別の core dump に聞いてみたら syslog 関数で死んで
いるケースが見つかり、付近の syslog(3) をはずしたら seg fault することはなくなりました。

syslog(3) と pthread (linuxthread) は混ぜるな危険とかいう話があるんでしょうか。
とりあえず syslog を自前で用意することにしてみます。
418デフォルトの名無しさん:2006/03/17(金) 07:20:23
その環境ではsyslog(3)はMT-Safeじゃないのに、排他してないだけとか
419http://www.vector.co.jp/soft/win95/util/se072729.html:2006/03/18(土) 19:49:50
TextSS のWindowsXP(Professional)64bit化おながいします

もしくは64bitにネイティブ対応したテキスト置換ソフトありますか?

420デフォルトの名無しさん:2006/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デフォルトの名無しさん:2006/03/28(火) 06:09:38
page outないくらいメモリが十分にあると考えると、
(OSによってはI/Oキャッシュがメモリを食い潰してしまいますが)
I/Oバウンドな処理をするプログラムにCPU割り当てる意味ないでしょ。

けど、
> それぞれCPUは85〜95%占有するほど負荷が大きいです。
で「I/Oバウンド」なの?

それからマルチスレッドじゃないw
422デフォルトの名無しさん:2006/03/28(火) 12:47:04
>>420
CPU占有を占有したいなら、邪魔しに来る恐れのあるほかのプロセスは
どれか他のCPUに割り当てるべき。

CPUを占有することの利点は、
・他のCPUでの処理の邪魔をしない
・各CPUが独立した2次キャッシュを持っているとき、キャッシュの汚染に
よるパフォーマンス低下を避けられる(かもしれない)
の2つくらい。

カーネルに任せるべきかどうかはなんともいえない。
プログラムの性格にもよるし、カーネルのスケジューラーの実装にもよる。
423420ではない:2006/03/29(水) 00:15:05
ぶっちゃけ聞きたいんだが、
「cpu_affinityをハードウェア的に割り当てる」
って、現在存在するOSの中でどれよ?
424デフォルトの名無しさん:2006/04/04(火) 15:54:42
C++で質問ぬ
beginthreadexで作ったスレッド
exitthreadexしないで スレッド関数return で終了して
CloseHandleしても問題ないですか?

サンプルで exitthreadをreturn の前に呼んでるのと
呼んでないの
があったので

425デフォルトの名無しさん:2006/04/04(火) 16:29:21
>>424
寧ろ、exitthreadするとC++のデストラクタが走らないので問題になりがち。
極力returnするべき。
426デフォルトの名無しさん:2006/04/06(木) 01:56:06
世はSPEでプログラミングしたいのじゃ
427デフォルトの名無しさん:2006/04/06(木) 13:02:49
>>423
つ z/OS
428デフォルトの名無しさん:2006/04/16(日) 00:01:57
世界で始めてデッドロックを実際に経験した人って誰だろう。
あまりにもの恐ろしさに震え上がったことだろう。
429デフォルトの名無しさん:2006/05/06(土) 21:33:59
430デフォルトの名無しさん:2006/05/06(土) 22:23:42
哲学者よフォークを取れ!!
431デフォルトの名無しさん:2006/05/06(土) 23:33:04
先生、フォークが足りません!!
432デフォルトの名無しさん:2006/05/06(土) 23:41:15
フォークを取ってどうすんだよw
433デフォルトの名無しさん:2006/05/06(土) 23:46:41
通じてないのかさらに深い洞察なのか…
434デフォルトの名無しさん:2006/05/06(土) 23:47:34
そうかパスタを取れか!!
435デフォルトの名無しさん:2006/05/06(土) 23:50:03
>>434
てめー、すました顔してないで早くフォークよこせよ
436デフォルトの名無しさん:2006/05/06(土) 23:54:39
まず全てのフォークをいったんテーブルに戻して、
そして...



















哲学者よフォークを取れ!!
437デフォルトの名無しさん:2006/05/06(土) 23:55:20
すまん、記憶違いだったら悪いんだが。
哲学者よときたら「箸をとれ」じゃなかったか?
438デフォルトの名無しさん:2006/05/06(土) 23:58:02
>>432
哲学者の食事問題を知らない奴キター
439デフォルトの名無しさん:2006/05/06(土) 23:59:11
>>437
ヒント:哲学者は日本人ではない
440デフォルトの名無しさん:2006/05/07(日) 00:00:54
ヒント:ダイクストラ
441デフォルトの名無しさん:2006/05/07(日) 00:10:23
哲学者よ

死ぬくらいなら手づかみで食え
442デフォルトの名無しさん:2006/05/07(日) 00:11:25
哲学者はきわめて明確な論理で行動するため、
臨機応変などという言葉は通用しません。
443デフォルトの名無しさん:2006/05/07(日) 00:17:27
哲学者は、野蛮では無く極めて理知的に出来ております。
444デフォルトの名無しさん:2006/05/07(日) 01:26:53
Dining Philosophers Problem は設定がシュール過ぎて
授業中に笑い出しそうになった
445デフォルトの名無しさん:2006/05/07(日) 04:53:31
シュレディンガーが猫を題材にしたのと通じるものがあるな
446デフォルトの名無しさん:2006/05/07(日) 09:56:09
お前なーやめろよ
話の流れから

シュレディンガーが猫を食材にしたのと通じるものがあるな

と読んじゃったじゃないか
まぁ、たいして違いはないが
447デフォルトの名無しさん:2006/05/07(日) 13:34:52
哲学者よ、明日はパスタにしよう。うん、パスタ。
448デフォルトの名無しさん:2006/05/07(日) 21:18:36
哲学者は手掴みで食べないものなのですか?
449デフォルトの名無しさん:2006/05/07(日) 21:22:19
哲学者はそんなはしたないまねはしません。
しかし決して人に譲ることもしません。
450デフォルトの名無しさん:2006/05/08(月) 00:23:38
哲学者よデスマーチから逃げれ!!
451デフォルトの名無しさん:2006/05/08(月) 09:39:33
age
452デフォルトの名無しさん:2006/05/09(火) 20:31:01
Cでスレッド固有のグローバル変数みたいなものって使えないかな
ほぼ全ての関数でスレッドごとに値の違う変数使ってるんで
毎回引数に加えるのが面倒になってきた
453デフォルトの名無しさん:2006/05/09(火) 20:48:51
処理系固有でTLSなどがあるとは思うが。
454デフォルトの名無しさん:2006/05/09(火) 22:34:47
>>453
サンクス。しらんかった
455デフォルトの名無しさん:2006/05/10(水) 00:58:57
gccだと、

__thread int i;

とか。
456デフォルトの名無しさん:2006/05/10(水) 01:26:42
調べました
pthreadだとpthread_key_create()とかですね
__threadの方が扱いやすいけどポータビリティとしてはどうなんだろう
gcc依存でも別に困りはしないんですけどw
何はともあれありがとうございました〜
457デフォルトの名無しさん:2006/05/10(水) 08:23:30
ポータビリティが気になるなら APR とか使うのは?

http://apr.apache.org/docs/apr/group__apr__thread__proc.html#ga23
458デフォルトの名無しさん:2006/05/14(日) 15:00:46
結城浩のデザインパターン スレッド編って買い?
459デフォルトの名無しさん:2006/05/16(火) 12:59:06
   .  -‐-  .  
__ 〃       ヽ :  
:ヽ\ ノノノ)ヘ)、!〉 :
'. l(0_)!。-‐ ‐〈リ .はわわ〜マルチが459ゲットですぅ…
 ;Vレリ、" (フ/ ; 
    : l´ヾF'Fl :           ∧__∧____ 
   ;. 〉、_,ノ,ノ :          /|・∀・ ┥ ./\
  . /ゝ/´, ヽヽ . .     /| ̄∪∪ ̄ ̄|\/  
  : く/l |_ノト‐'⌒),) .      |  拾って  |/ 


460デフォルトの名無しさん:2006/05/20(土) 17:07:49
>>458
買い。
461デフォルトの名無しさん:2006/05/22(月) 00:45:49
longの読み書きについて質問失礼します。

@マルチスレッドで InterlockedExchange を使用し、longの値を変更しています。
A別スレッドで@で変更しているlong値を参照しています。
(読むだけの Interlocked〜 の関数が見当たらない為)
この処理って大丈夫なんでしょうか?

実際にソースに組み込んでテストしているのですが、今の所大丈夫っぽいです。。。
462デフォルトの名無しさん:2006/05/22(月) 01:19:41
volatile修飾すれば大丈夫という噂
463デフォルトの名無しさん:2006/05/22(月) 01:25:57
共有リソースを元に、あるメモリに書き込みとかをしなければ問題ないよ。
参照だけなら、何の問題もなし。
464デフォルトの名無しさん:2006/05/22(月) 03:01:15
Interlocked.Read
465デフォルトの名無しさん:2006/05/22(月) 03:01:52
てv1か…
Interlocked.Readは2からだったな…
466デフォルトの名無しさん:2006/05/22(月) 06:15:08
>>461
InterlockedExchangeAdd
467デフォルトの名無しさん:2006/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デフォルトの名無しさん:2006/05/23(火) 18:35:25
>>467
何か勘違いしてないか?
469デフォルトの名無しさん:2006/05/23(火) 22:13:13
>>468
何か勘違いしてないか?
470デフォルトの名無しさん:2006/05/26(金) 02:28:01
>>467
それはOSの仕事
471デフォルトの名無しさん:2006/05/26(金) 09:01:15
SetThreadAffinityMask(hThread,0x01);
SetThreadAffinityMask(hThread,0x02);
SetThreadAffinityMask(hThread,0x04);
SetThreadAffinityMask(hThread,0x08);
とした時にどのコアが使用されるか知りたいってことじゃねーの?
472デフォルトの名無しさん:2006/05/26(金) 11:26:01
>>467
http://www.intel.com/cd/ids/developer/asmo-na/eng/269421.htm

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デフォルトの名無しさん:2006/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デフォルトの名無しさん:2006/05/26(金) 16:39:43
>>470
ヴァカ発見
475名無しさん:2006/05/26(金) 19:42:14
>473
関数のセマンティクスとしてはクソだが、特に問題は発生しないだろう。
476467:2006/05/26(金) 20:21:43
>>472
なるほど…スレッドを固定してCPUIDでチェックすれば判別できそうですね。
用語解説は非常に勉強になりました。
ありがとうございますー

良く考えてみればSMT1が軽い負荷ならSMT2に重い負荷を
かけても遅くならないのかな…?
だとすると、同じコアのSMT1とSMT2に割り当てないようにすれば
効率が良さそうですね。
477デフォルトの名無しさん:2006/05/26(金) 23:31:44
時期尚早な最適化は諸悪の根源だ
478473:2006/05/27(土) 00:41:46
>>475どもです。
479デフォルトの名無しさん:2006/05/27(土) 01:31:47
>>476
みんなpthreadのデバッグってどうやってやってますか?

1ソースコードから処理を推測してデバッグ
2とりあえずなんでもいいからprintf仕込んでデバッグ
3gdbを利用する
4ツールを使って調査する。
もしいいツールとか方法あれば教えてください。
480デフォルトの名無しさん:2006/05/27(土) 11:05:19
>>479
つ【5 - pthreadの気持ちになってみる。】
481デフォルトの名無しさん:2006/05/27(土) 12:17:16
>>479
pgdbgはどうよ? (というかプラットフォームは何よ?)

Linuxは、IBMがpthreadを手がけた時に、
libpthdebug.aがAIXから持ち込まれるかと思ったが、
IBM版はlinuxサイドから拒絶されたので実現しなかった…
482デフォルトの名無しさん:2006/05/27(土) 12:30:20
pgdbgですかぁ渋いですね
それでいっちょ今から会社飛んでデバッグしてきますね
483デフォルトの名無しさん:2006/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デフォルトの名無しさん:2006/05/27(土) 23:06:05
それでええで。
examples/libs/thread/example/condition.cpp 見てみ。
485デフォルトの名無しさん:2006/05/27(土) 23:06:55
examples/は余分やな…
486デフォルトの名無しさん:2006/05/27(土) 23:20:41
だめだ、pthreadが周りでどうしても落ちる
セグ落ちでどうしてもダメううーん発見できん
神様助けてくれ
487デフォルトの名無しさん:2006/05/28(日) 23:20:52
>>484
ありがとうございます、スッキリしました。
488デフォルトの名無しさん:2006/05/30(火) 18:30:41
>>486
落ち始める直前の状態にまで戻して何やったのか胸に手を当てて考えてみれ。
489デフォルトの名無しさん:2006/05/31(水) 00:36:18
ふっふっふっふ私はもうスレッドは怖くない
スレッドの挙動を完璧把握する方法を知ってしまった
ふっふっふっふ
490 :2006/06/01(木) 02:46:02
pthread_cond_timedwaitで、指定タイマーを経過しても待ち状態解除されず
停止したままになってしまっているのですが、引数パラメータに問題が
あるのでしょうか。
gdbで確認したところ引数は問題なさげで、pthread_cond_timedwait内の
pthread_sigsuspendで停止してるっぽいのですが…。
491デフォルトの名無しさん:2006/06/01(木) 12:38:26
糞カーネルを使っているに一票
492デフォルトの名無しさん:2006/06/07(水) 01:46:39
まずOSの種類とカーネルの素性晒せ
493デフォルトの名無しさん:2006/06/07(水) 08:46:05
LINUXですよ(^^)
494デフォルトの名無しさん:2006/06/08(木) 01:10:24
それは windows でない。とだけ言ってるに等しい
495デフォルトの名無しさん:2006/06/08(木) 13:42:04
マルチスレッドとマルチプロセスでは一般的にどちらが効率的ですか?
496デフォルトの名無しさん:2006/06/08(木) 18:36:22
タスク間のデータ参照が多いプログラムと少ないプログラムでは、どちらが「一般的」ですか?
497デフォルトの名無しさん:2006/06/10(土) 01:47:28
volatileで回避できますか?
498デフォルトの名無しさん:2006/06/10(土) 04:22:44
volatileとstaticで8割方回避できます!
499デフォルトの名無しさん:2006/06/10(土) 08:47:58
なにをだ。
500デフォルトの名無しさん:2006/06/10(土) 10:14:15
mutexとvolatileでは一般的にどちらが効率的ですか?
501デフォルトの名無しさん:2006/06/10(土) 12:19:02
コーディング効率か
コードの効率か
で回答が変わってくる可能性がある
502デフォルトの名無しさん:2006/06/10(土) 12:24:23
volatileはLockFreeで高速だが、アトミック操作に限定されるので、
一変数ならともかく、全体の整合性がどういう言い出すとプログラムは
とっても面倒だし、バグがあるかないかの検証も面倒くさい
503デフォルトの名無しさん:2006/06/10(土) 12:54:08
( ゚д゚)ポカーン
504デフォルトの名無しさん:2006/06/10(土) 14:14:06
>>501-502 がマジレスである可能性を想像し、背筋が凍った。
505デフォルトの名無しさん:2006/06/10(土) 15:55:27
そのまま風邪引いて肺炎悪化させて死んでくれ
506デフォルトの名無しさん:2006/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デフォルトの名無しさん:2006/06/10(土) 17:01:47
trylockしてみて無理だったら待てばいいんじゃねぇの?
違うってかゴメンね
508デフォルトの名無しさん:2006/06/10(土) 17:27:39
>>506
どういうデッドロックを想定しているの?

th1がaをlockしてbを得ようとして、th2がbをlockしてbを得ようとしているとか?

入れ子セマフォア
多重セマファオ
で解決できませんか?
509デフォルトの名無しさん:2006/06/10(土) 17:47:33
>>508
>入れ子セマフォア
>多重セマファオ
おチツ毛
510506:2006/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デフォルトの名無しさん:2006/06/10(土) 19:54:30
>>510
ttp://ja.wikipedia.org/wiki/%E3%82%BB%E3%83%9E%E3%83%95%E3%82%A9

古典的って言ったら古典的か.
512デフォルトの名無しさん:2006/06/10(土) 19:56:50
>>510
ロックの話だけで頭がいっぱいになってるけど
そのsem1とsem2の間でどんな処理をするのか
教えてよ。
513506:2006/06/10(土) 21:59:59
>>511
ご返信をありがとうございます。
これは「多重セマフォ」の解説(使用例の項)でしょうか?
残念ですが、今回の件は同時参照を全て止める必要があるため、初期値を大きくすることに
よって解決とすることは出来ないと思います。情報をありがとうございました。

>>512
ご返信をありがとうございます。
不要と判断していました。たとえばですが。

共有メモリにある情報をまとめたテーブルがあるとします。
関数 SetData01() はこのテーブルの特定のデータを変更します。
同様に SetData02() など複数の関数があり、それぞれ関数内部でデータを変更するための
(受取手にとってわかりやすい形から格納に適した形への変換などの)処理を実施しています。
これら関数には対応する GetData**() も存在し、変更/参照時には共に排他制御(sem2)を実施します。

更に上記個別の値をまとめて取り扱う関数として SetGroupData() なる関数があり、
先の個別にデータを変更/参照する関数を内部で使用します。
この関数でのデータの変更時には、関連する全てのデータ更新が終了するまではデータ間での
矛盾発生を防ぐために他からのデータ参照を止めたい場合があるため、この関数の実行時にも
排他(sem1)を掛けたいと考えています。

回避策として、SetGroupData() で SetData01() などを呼ばずに自前で個別データの
設定を行う方法もあるのですが、少々煩雑な処理をするところもあるため、可能であれば
SetData01() などを利用する形に出来ればと思っています。

そのままのことは書けないため、説明が足りないところもあるかと思いますがご容赦ください。
514デフォルトの名無しさん:2006/06/10(土) 23:56:28
>>513
そのよくわからんけど、SetDataなんちゃらっていうメソッドをいくつも用意するの?
そんなことするよりもさ
SetData(class data)を用意してこいつが責任もって共有データを単独で更新すればいいんじゃないのか?
じゃあ、みんなで同時に呼べねーべバーカとか思うなら、このSetDataは要求をスタックに貯めて逐次実行する
仕組みだけを排他制御で実装すればいいよね。共有メモリに置く程度のデータならそれぐらいで間に合わないかな?
515506:2006/06/11(日) 15:27:03
>>514
ご返信、ありがとうございます。
初めからそういう方向性を考えていれば...と後悔しているところです。(汗
次こそわ。
516デフォルトの名無しさん:2006/06/11(日) 20:23:12
いや、変えないと今のも終わらないから。
517デフォルトの名無しさん:2006/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デフォルトの名無しさん:2006/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デフォルトの名無しさん:2006/06/12(月) 18:04:20
>>517
それ、WaitForSingleObject で待ってない(即リターンしてる)から。
他のスレッドが所有権を持ってないので、呼び出したスレッドが即座に所有権を得ておしまい。
2度目以降の呼び出しは、呼び出したスレッドがすでに所有権を持っているので即座に完了。

他のスレッドに所有権を持たせておくか、selectとかSleepでも使うべし。
520519:2006/06/12(月) 19:39:57
今思いついたんだけど、とにかくタイムアウトさせたいなら
GetCurrentThread() で得たハンドルを wait してもいいのかもしれない。
521デフォルトの名無しさん:2006/06/12(月) 19:45:59
>>519
アドバイスありがとうございます。
ただ、デバッガで追ってみましたところきちんと毎回Waitしている様子です。
Wait時間を分かりやすく5秒にしてみたところ、私の期待通りの動作をしているようです。

selectについてもこれから試してみたいと思います。
522デフォルトの名無しさん:2006/06/12(月) 19:53:00
Sleep、WaitForSingleObject、いずれも、寝ている時間の精度自体は5msも保証できない
523デフォルトの名無しさん:2006/06/12(月) 19:57:04
>>522
なんと、そうなのですか?
やはりFPS60なんていう精度を望む場合
Waitなんて無しでぶんまわしつづけるしかないのでしょうか?

(そもそも、Windowsで精密ゲームを作ること自体、Windowsの設計理念とは反している気がしますが)


524519:2006/06/12(月) 20:25:43
>>521
そですか・・・ところでメインスレッド側は PeekMessage 無しに戻しましたか?
単純に >>518 から else 以降を取ってしまうと、CPU 100% のビジーループに
なるわけですが。
525デフォルトの名無しさん:2006/06/12(月) 21:08:55
ところで、なんで、NOREMOVEでPEEKしたあと、またGetMessage呼んでるの?
単純に、直接REMOVEでPEEKして、Translate,Dispatchすればいいと思うんだけど
526デフォルトの名無しさん:2006/06/13(火) 14:46:50
pthread_create() で作ったスレッドが終了したかどうかの確認は
どうしたらいいんでしょうか? pthread_join() してしまうとその
スレッドが終わるまで待たされてしまいますよね?

やりたいことは、複数のスレッドを作って、作った側で pthread_t
の配列にスレッド識別子を入れておき、それぞれがバラバラの
時間で終わるんですが、作った側で pthread_t の配列に入っている
値を元にそれぞれが終わったかどうかを確認して、終わっていたら
それに対して pthread_join() をやって資源開放をて、配列の側も
その部分を終了しているという値(たとえば0)にしたいんです。
(つまり UNIX で複数 fork() したあとで waitpid() の WNOHANG
みたいにして何が終わったか、あるいは何も終わっていないのかを
確認するのと同じことです)。こういうのは pthread ではどうやる
んでしょうか?
527デフォルトの名無しさん:2006/06/13(火) 21:33:23
pthreadは詳しくないけど自分でフラグ作っても大して開発効率落ちないと思う。
528デフォルトの名無しさん:2006/06/14(水) 00:10:40
SIG_CHLDシグナルで判断しろよ
529デフォルトの名無しさん:2006/06/14(水) 12:15:21
>>528
pthread で作ったスレッドに対して SIGCHLD は使えないのでは?
子プロセスじゃないんだし。(Linux の実装だと使えるとか?)
530デフォルトの名無しさん:2006/06/14(水) 13:11:53
POSIX P1003.1cにpthread_kill()ってのがあって、
signalを指定する引数に0を指定すると、
pthreadがいれば成功(シグナルは何も送られない)、
いなければESRCHのエラーになる。

processに対するkill(2)と同じ仕様。

> 自分でフラグ作っても大して開発効率落ちないと思う。

ではありますが。

531デフォルトの名無しさん:2006/06/14(水) 13:23:26
>>530
あー! その手があったか。
くっそー。 pthread_kill() の man ページは見ていたのに気が付かなかった。

どうもありがとうございます。
532デフォルトの名無しさん:2006/06/17(土) 17:46:23
スレッドのデバッグって何使ってますか?
Linuxだとgdbだけかな?
533デフォルトの名無しさん:2006/06/19(月) 00:32:10
知恵と勇気
534デフォルトの名無しさん:2006/06/19(月) 01:05:12
>>533
そんなのいらねーよ何か教えねーと食うぞ?
535デフォルトの名無しさん:2006/06/19(月) 10:33:24
「ちびくろ! おまえを たべちゃうぞ!」と、とらは いいました。
536デフォルトの名無しさん:2006/06/19(月) 21:49:53
>>532
かん
537デフォルトの名無しさん:2006/06/20(火) 13:18:17
>>532
おれ、この前 gdb でやってみて大混乱。
使い方調べてから使わないといかんね。
538デフォルトの名無しさん:2006/06/24(土) 17:19:02
無茶しやがって…
539デフォルトの名無しさん:2006/06/24(土) 21:26:39
Windowsで、タスク内の複数スレッド間だけで通用する、高速な同期オブジェクトって無いですかね?
なんか、どれもこれも、重そうで。
540デフォルトの名無しさん:2006/06/24(土) 23:41:41
イベント系はユーザーモードで実行される。
イベント系はプロセス間の動機にも使えるという強みがある。
クリティカルセクションのみカーネルモードで実行される。
クリティカルセクションはプロセス間の動機で使えないがイベント系に比べると
非常に高速だという強みがある
541デフォルトの名無しさん:2006/06/24(土) 23:49:15
>>540
クリティカルセクションって何?
542デフォルトの名無しさん:2006/06/24(土) 23:58:44
ミューテックスとほぼ同じ。
タイムアウト指定ができなかったりする。
543デフォルトの名無しさん:2006/06/25(日) 00:07:28
カーネルモードに移行するものが高速で
ユーザーモードのまま実行できるものの方が遅いって?
544539:2006/06/25(日) 03:10:41
クリティカルセクションだと、スレッド間での排他は楽だけど、同期には使えないよね。
イベント系はカーネルまで落ちるし、プロセス間で使えるから重いよね。

同期に使えて、カーネルまで落ちなくても良いようなヤツが欲しいンだけど、
Windowsでは用意されてない気がするんだ。
それって、正しいのかな?
545デフォルトの名無しさん:2006/06/25(日) 03:29:24
2つのスレッドだけでいいのならクリティカルセクションでも同期は取れる。

最初にどちらかのスレッドが所有権を保持するようにする。
片方のスレッドはEnter.....()で所有権が解放されるまで待機。
所有権を持っていたスレッドが所有権を解放すれば片方のスレッドは
実行が開始されるようになる。

高速性が大事でかつ簡易な同期処理でいいならこんな方法もある。

関数自作するとか。排他制御ができれば後は自分でいろいろできる。
546デフォルトの名無しさん:2006/06/25(日) 06:33:19
Fiberでも使ってみたら?
NT以降専用だが。
547デフォルトの名無しさん:2006/06/25(日) 07:21:53
以前も微妙に話題になったが、MeteredSectionとか、
AdvancedWindowsのOptExとかで楽しちゃうってのもある。

MeteredSection
ttp://msdn.microsoft.com/library/default.asp?url=/library/en-us/dndllpro/html/msdn_metrsect.asp

OptEx
tp://www.microsoft.com/msj/archive/S1DA0.aspx
548539:2006/06/26(月) 17:26:10
>>545
>>546
>>547
とりあえず、情報どうも。Fiberだと排他・同期というより切替に近いので、同期にはならない気がする。

問題は、CriticalSection系は、同一スレッド上では同期しないので、>>545さんの方法、OptExはちょっと難しい感じ。
つーか、それだとどちらか片方の処理が重いときにバグになっちまう。

ということで、MeterdSectionを使うのが良いのかなぁ。でも、こいつ、CriticalSectionの拡張版みたいなもんみたいだから、
排他は出来るけど、同期は難しそう。
探したら日本語のページがあったので貼り付け。
ttp://www.microsoft.com/JAPAN/developer/library/jptech/msdnnews/metrsect.htm

それとも、原始的にロックファイル作るか…うーん、100近いスレッドが立ったとき考えるとやりたくないな…。
とりあえず、Mutexあたりを、最初にまとめて作成することで負担を減らすしかなさそうな感じ。
みなさん、ありがとう。
では。
549デフォルトの名無しさん:2006/06/27(火) 21:28:46
>>548
具体的にどんな処理がしたいの?
単一プロセス内ならCriticalSection で何でも作れるよ
(だからこそOSもCriticalSectionしか提供してないわけで)。

あと「同一スレッド上では同期しないので」ってのはどういうことを
意図してるのかちょっとわからない・・・同一スレッドで非同期に
コードが実行されるのは Unix の signal のケースくらいで、
Windows のユーザモードでは起きないんじゃない?
550デフォルトの名無しさん:2006/06/27(火) 22:11:04
>>549
ありゃ、そういう答えが返ってくると言うことは、
もしかして オレのCriticalSectionについて根本的な使い方や理解が間違ってるのかな…。

スレッドひとつしか無ければ、EnterCritical...をいくつ並べても無視されると思ってたんだけど、違うのかな…。
551デフォルトの名無しさん:2006/06/27(火) 22:13:57
スレッドひとつならマルチスレッドじゃないからな
552デフォルトの名無しさん:2006/06/27(火) 22:21:17
そんなにパフォーマンス気にしてるのに
何でロックファイルとかにいくんだ…
553デフォルトの名無しさん:2006/06/27(火) 22:39:45
英語でプログラミング勉強スレ

http://academy4.2ch.net/test/read.cgi/english/1151414777/l50
554539:2006/06/27(火) 22:53:13
>>551
でも、プログラムは大抵、ひとつのスレッドから開始されるんだよ。最初からふたつってわけじゃない。
まあ、だから、>>545 は使えないんだよな。
555デフォルトの名無しさん:2006/06/27(火) 23:12:31
なにか、壮大な勘違いをしている予感
556デフォルトの名無しさん:2006/06/28(水) 01:48:11
まず、「同期する」をどういう意味で使っているのか説明してもらってからだな
557デフォルトの名無しさん:2006/06/28(水) 01:56:37
同期の人と一緒に仕事をする
同期するじゃね?
558デフォルトの名無しさん:2006/06/28(水) 03:31:41
>>539
そういうのは、ふつーにeventだの何だのをでも使ってみて、重くてやってらんなくなってから考えれば良い。
559539:2006/06/28(水) 14:26:16
>>558
なんだそりゃ。そう言う回答は勘弁して欲しいぞ。
560デフォルトの名無しさん:2006/06/28(水) 16:09:22
なんで>>539は質問してる身分でやたらと偉そうなの?
リアルでもそういう質問の仕方しか出来ない人?
561デフォルトの名無しさん:2006/06/28(水) 16:16:15
>>559
「回答」ではないだろう。
「重そう」と思うだけで実際にやってみることもせず
そのくせ「ロックファイル」なんて単語まで飛び出し
結局何がしたいのか、「同期」が何を指しているのかも
説明してくれない君への
アドバイスじゃまいか。
562デフォルトの名無しさん:2006/06/28(水) 16:45:09
おまえら馬鹿なんじゃね?
563デフォルトの名無しさん:2006/06/28(水) 16:54:40
>>560-561
ウザ
564デフォルトの名無しさん:2006/06/28(水) 17:45:49
つーか、時々デッドロックするようなプログラムしか作ってないのかょ、おまえらは。
565デフォルトの名無しさん:2006/06/28(水) 17:46:52
なにか、壮大な勘違いをしている予感
566デフォルトの名無しさん:2006/06/28(水) 18:17:22
なにかが気に喰わなくて暴れ始めたお母ん
567デフォルトの名無しさん:2006/06/28(水) 18:54:40
予感でプログラムが組めるヤツはニュータイプ。
568デフォルトの名無しさん:2006/06/28(水) 21:21:38
まてまて。
>>539 はWindows のカーネルやAPIを設計した人たちや
普段からマルチスレッドAPなんかさんざ書いてる漏れも
見落としている、何か難しい問題に対処しようとしてるんだよ。

それはたぶんロックファイルと関係のあるなにかなんだろう。
漏れには想像もできないが、頭ごなしに否定しないでだまって
観察してあげるべきじゃないか?
569デフォルトの名無しさん:2006/06/28(水) 22:34:06
なにか、壮大な勘違いをしている予感
570asdlman:2006/06/28(水) 22:40:26
>>569
>>555
lead reth !!!
571asdlman:2006/06/28(水) 22:47:52
>>569
>>555
test
572デフォルトの名無しさん:2006/06/28(水) 23:21:13
Vistaから同期IOのAPIがキャンセル可能になるそうですね!
573デフォルトの名無しさん:2006/06/29(木) 13:12:51
それは、非同期IOのことだろ。
574デフォルトの名無しさん:2006/06/29(木) 15:47:52
>>573
同期IOだよ。非同期IOのキャンセルならWindows98でも出来る。
575デフォルトの名無しさん:2006/06/29(木) 15:54:38
それを非同期というのではないのか?
576デフォルトの名無しさん:2006/06/29(木) 16:11:59
>>575
めんどくさいなーもう。ほらよ↓
今まではCerateFile なんか非同期版がなかったからキャンセルできなかっただろ?

http://www.microsoft.com/japan/msdn/windowsvista/general/win32iocancellationapisv2.aspx
577デフォルトの名無しさん:2006/06/29(木) 16:29:46
>>575
いや、絡んでるつもりは全くなかったんだ、すまん。
つまり、同期I/Oを他のスレッドで実行することによって擬似非同期I/Oの
ような使い方をしたときに、そのAPIの実行をキャンセルすることができる
ようになったということだな。
同期/非同期とはそういうことだったのか。勉強になった。
578デフォルトの名無しさん:2006/06/29(木) 16:30:17
579デフォルトの名無しさん:2006/07/01(土) 17:16:56
Linuxのカーネル層でマルチスレッドのような
設計が必要になっているんですが、
Aという関数が終わったらBの関数で
止めていたところが動き出すような設計って
どうやったら良いもんですか?

セマフォを使った排他処理ってデータに
対する排他処理になると思うんだけど、
そういう形で発想の転換をしないと駄目なのかな?

580デフォルトの名無しさん:2006/07/01(土) 19:10:53
待ちたいところでスピンロックでもasm WAITでもなんでもしておけばいいだろう
581デフォルトの名無しさん:2006/07/01(土) 21:33:47
>>579
condは適当に初期化。

A() {
〜;
pthread_cond_signal(&cond);
return;
}

B () {
pthread_cond_wait(&cond);
〜;
return;
}

582デフォルトの名無しさん:2006/07/01(土) 22:07:31
>>581
参考になります。

これってAのreturnの直前でBが動き出す
ということですよね?
Aが終わってからってのはやっぱり難しいのかな。
583デフォルトの名無しさん:2006/07/01(土) 22:20:08
>>582
AA() {
A();
pthread_cond_signal(&cond);
return;
}
584デフォルトの名無しさん:2006/07/01(土) 22:23:13
>>522
昔の奴へのレスで恐縮なんだがWindowsのSleepってそんな精度悪かったっけ?
::timeBeginPeriodとか使っても駄目?
585デフォルトの名無しさん:2006/07/01(土) 22:49:29
他に忙しく仕事をする連中が居なければ、だいたいは大丈夫かもね。
586デフォルトの名無しさん:2006/07/01(土) 23:26:40
>>585
なるほど
まあそれほど信用できないってことか。
587デフォルトの名無しさん:2006/07/02(日) 00:04:19
スレッドの教科書ってどんなのあるの?
アルゴリズム系に強いやつが欲しい
588デフォルトの名無しさん:2006/07/02(日) 00:14:48
OSによって違うな。
pthreadなら>>1->>9辺り見て。
589デフォルトの名無しさん:2006/07/02(日) 00:18:29
Lamport's bakery algorithmとかさこんな古典的なやつから
今の新しいアルゴリズムまで載ってるのないのか.....
590デフォルトの名無しさん:2006/07/02(日) 00:49:51
>>583
AAは別の人のソースなので手を加えられないのです。
でも参考になりますた。
ありがとうございますた。
591デフォルトの名無しさん:2006/07/03(月) 06:53:31
windows には win32 API で色々なイベントを使えるようになってますが、
UNIXではpthreadのイベントを使う以外にないのでしょうか?
592デフォルトの名無しさん:2006/07/03(月) 07:26:25
>>591
例えばこういう奴?
http://www.monkey.org/~provos/libevent/

どの UNIX を対象にしているかで答えも変わるけど、大抵はググれば色々出て来る。
593デフォルトの名無しさん:2006/07/05(水) 10:16:26
Winsock、_beginthreadで起動して、
グローバル変数で終了要求するような、
簡単なスレッド書いているのですが、、、。

スレッド内でrecv()のような、
ブロックするような関数を呼びたくなりました。
これを終了するにはどうしたらよいでしょう。
594デフォルトの名無しさん:2006/07/05(水) 10:30:57
ソケットオプションでノンブロッキングにすればいいんでない?
595デフォルトの名無しさん:2006/07/05(水) 11:33:24
594>
ありがとう、そうします。

一般的にはどうでしょ?
ブロッキングするような関数をスレッドで呼んではいけない?

596デフォルトの名無しさん:2006/07/05(水) 11:51:06
ブロッキングするべき状況と、そうでない状況がある。
前者ならブロックさせとけばいいし、そうでなければ非同期APIを使うか、
別個にスレッドを作ればいい。
597デフォルトの名無しさん:2006/07/05(水) 11:59:52
>>593
recv()呼ぶ前にMSG_PEEKしておくなりしとかんとあかんよ。
#つーか、TCP受信処理を途中で終わらせると言う仕様そのものが如何なものかと。
598デフォルトの名無しさん:2006/07/05(水) 13:48:39
>>595
一般的かどうかは知らないけど、普通はselect使うんじゃないかな。
599593:2006/07/05(水) 13:49:40
>>596
「強制終了」以外は普通にブロックして、データが届いたときだけ
処理してくれればいいんだけど。って状況でした。
非同期っていうと、WSAEventSelect, WSAAsyncSelectで、通知を待つって
ことでよいですよね?

>>597
ちょっとわかんないのですが、
MSG_PEEKで、受信データが無いときはどうやって次の受信データを待つのが綺麗?
あと、途中で終わらないとしたら、どうやって終わるのがよいですか?
600デフォルトの名無しさん:2006/07/05(水) 18:14:11
>>599
WSAAsyncSelect(s, hwnd, 0, 0);
shutdown(s, 1);
while (recv(s, buf, buflen, 0) != 0) {}
closesocket(s);
601デフォルトの名無しさん:2006/07/05(水) 19:33:20
>>600
それ先方がデータ送ってくれないとCPU100%のビジーループ。
サーバアプリでは非常によろしくないコーディング。
602デフォルトの名無しさん:2006/07/05(水) 19:50:55
recvって、ブロックするんじゃないの?
603デフォルトの名無しさん:2006/07/05(水) 19:54:13
スマソ。ノンブロッキングのソケットと勘違いしてた。
604デフォルトの名無しさん:2006/07/05(水) 20:35:06
WSAAsyncSelectした時点でノンブロックになる
605593:2006/07/06(木) 17:50:25
任意のタイミングで終了させたいスレッド内では、ブロックする関数は呼ぶな。
socketはデフォルト非同期で。
で理解しました。 ありがとう。
606デフォルトの名無しさん:2006/07/06(木) 19:44:58
>>605
そう理解したんならそれでもいいが・・・
607デフォルトの名無しさん:2006/07/06(木) 22:55:34
ソケットを任意のタイミングで終了させると再起動したときにわややがな。
608593:2006/07/06(木) 23:34:44
>>607
どゆこと?
例えばサーバ的なアプリで、その受信用スレッドを、サーバ的なアプリ
のユーザ都合でブチっとしたくなった場合、、、
受信処理を終了させて、クローズなり何なりをしたい。
そんな場合ですが、再起動とは、ここでサーバ的なアプリを再度起動して
受信を始めようとした場合になにかが起こるってことですか?


609デフォルトの名無しさん:2006/07/07(金) 00:34:15
下の層が受信しているのにアプリが落ちたら、次に起動するときにbindErrorになる。
610デフォルトの名無しさん:2006/07/07(金) 00:43:27
つかさ、断片的な情報を積み重ねて信頼性のないアプリ作るよりさ、
ばしっとWinsock Programmer's FAQとか、Winsock関連書籍を読み
とおして、きちっとしたアプリを作ろうとは思わんのかね。
611デフォルトの名無しさん:2006/07/07(金) 01:07:01
>>609
アドバイスするなら、その前にFAQくらい読んどけよ。
知識足りなさ過ぎ。
612593:2006/07/07(金) 10:11:03
>>610
終了するときは、shutdown(sock, 1) をスレッドの外から呼べ、
そうするとrecvが0返すので、スレッドを抜けろ。
で、理解しました。ありがとう。
613デフォルトの名無しさん:2006/07/07(金) 11:42:52
>>609
100%賛成して同意して応援します。
他人のいう事に惑わされたりマニュアルやFAQを読んだりせず、
先方が送信を続けている間は終了できないプログラムを作り続けてください。
614デフォルトの名無しさん:2006/07/07(金) 11:56:22
>>593
fcntl(s, F_SETFL, O_NONBLOCK); って使えない?
(Windowsだとこれはないのかな?)
>>595
select() 使う場合は他のスレッドが同じソケットから読まないように
作る必要がある。recv() ではあまりないかも知れないが、サーバ用に
bind() した一つのソケットに対して複数のスレッドから accept()
する場合にselect()使うとハマる(2つ以上のスレッドがselect()を通過
した場合に一つのスレッド以外がブロックする)。防止するには上に
書いたような fcntl() で O_NONBLOCK セットして accept() で止まら
ないようにする。
>>609
最初に setsockopt() で SO_REUSEADDR をセットしとけばいいんじゃないか?
615デフォルトの名無しさん:2006/07/08(土) 02:08:08
volatile最強
616デフォルトの名無しさん:2006/07/08(土) 10:36:46
メモリモデル勉強しる
617593:2006/07/09(日) 20:09:28
最後にもひとつ。
一般的に、マルチスレッドで使われることを前提にした、受信待ちのような
ブロックする関数を提供しようとした場合は、それと一緒に受信を中断
して安全に返るための、他のスレッドから呼ばれる関数(socketの場合のshutdown)
を提供すればよい。
ですか?
他に綺麗な方法あったら教えてください。
618デフォルトの名無しさん:2006/07/09(日) 20:26:23
一般的には、recvでブロックさせるのではなく
select系でブロックさせて
selectをブレークさせる方法を使うだろ。

つまり「外部から解除できないブロッキング関数ではブロックさせない」と。
619デフォルトの名無しさん:2006/07/09(日) 20:28:20
selectってキャンセル可能だっけ
620デフォルトの名無しさん:2006/07/09(日) 20:36:02
selectで同時にパイプを待ったり
WSAEventSelectで同時にEventを待ったり
というやり方のこと。
621デフォルトの名無しさん:2006/07/09(日) 20:39:08
selectでtimeout設定すればいいと思うけど
それとももっと高度な制御がしたいの?
622デフォルトの名無しさん:2006/07/10(月) 00:20:40
>>621
timeout 値の設定がめんどい。

仕方なく >>620 の WSAEventSelect 使ってるけど、
これはこれでめんどい。
623デフォルトの名無しさん:2006/07/10(月) 03:56:03
pselect
624593:2006/07/10(月) 10:22:26
>> 618
なるほど。
Linuxでは、読み込むものは全部ファイル(ファイルデスクリプタ)で、
中断など例外的な処理は全部シグナル。と思ってpselectで綺麗にい
けていたんだけれど、
Winにいったら、いろんな方法がありそうだけれど、どれもいまいちに見えて。。
WSAEventSelectは、socket以外にも汎用的に使ったりする?


625デフォルトの名無しさん:2006/07/10(月) 11:23:05
>>617
スレッド(タスク)開始、実行状況(実行結果)の取得、完了待ち、中断のための関数を
それぞれ提供するのが一般的だと思います。
あと場合によっては先方のスレッドでコールバックされる実行状況の通知のための
コールバック関数なんかも設定できると UI 作るときには便利(プログレスバーとか)。

>>624
個人的な意見だけど、Windows では(ソケットなら WSAEventSelect等も使って)
(Msg)WaitForMultipleObjectExで待機、何かあれば処理するというのがマルチ
スレッドの場合の定石だと思います。
ソケットだけ相手にするなら単にclosesocketしてしまうというのもアリだと思うけど。

>WSAEventSelectは、socket以外にも汎用的に使ったりする?
ソケットを相手にしないのにWSA〜を使う局面は無いと思う。
626デフォルトの名無しさん:2006/07/11(火) 00:19:53
>>624

Winでも sock をファイルとして扱えるよ。
627デフォルトの名無しさん:2006/07/18(火) 19:03:35
Linux (Kernel 2.6.17) で、pthread_create() で複数スレッドを作り、
そのスレッド全てが同一の bind(), listen() されたソケットに対して
accept() を行うプログラムを作ったのですが(O_NONBLOCKなソケット
ですが)、クライアントプログラムから複数 connect() すると、
accept() が同じ値のファイルディスクリプタを返して来ます。処理を
単純に書くとこんな感じです。

for(;;) {
 int cs = accept(...); // ここで cs が別スレッドと同じ値になる。
 if (cs == -1) {
  if (errno == EAGAIN) {
   usleep(50000);
   continue;
  } else {
   break; // error
  }
 } else {
  proc(cs); // cs を使った処理。
  close(cs);
 }
}

accept() の前後に pthread_mutex_lock(), pthread_mutex_unlock() で
ロック、アンロックをしても同じでした。

これって Linux のバグなんでしょうか?
これを回避するにはやはり accept() をするスレッドを一つにしないと
駄目ですか?
628デフォルトの名無しさん:2006/07/18(火) 19:04:29
すいません。質問なのに age 忘れました。age ておきます。よろしくお願いします。
629デフォルトの名無しさん:2006/07/18(火) 19:32:26
わざわざageんなよ
630デフォルトの名無しさん:2006/07/18(火) 22:10:43
コンパイル・リンク時のコマンドライン見せろ
631デフォルトの名無しさん:2006/07/19(水) 01:14:42
>>627
> accept() の前後に pthread_mutex_lock(), pthread_mutex_unlock() で
> ロック、アンロックをしても同じでした。

この時点でプログラミングの問題じゃないことに気付け。
632デフォルトの名無しさん:2006/07/19(水) 01:56:34
>>627
>これって Linux のバグなんでしょうか?
つかその前に、どこで習ったんだそんな阿呆な手順。
633デフォルトの名無しさん:2006/07/19(水) 02:07:07
acceptしてからthreadおこせ
634デフォルトの名無しさん:2006/07/19(水) 03:17:38
>>627
よく知らんけど、下記のApache のディレクティブの存在なんかを見ると
accept は直列化 (同時に1つのプロセス・スレッドからのみ呼ぶ)するのが
普通なんじゃないかと思うが・・・

http://httpd.apache.org/docs/2.2/ja/mod/mpm_common.html
635デフォルトの名無しさん:2006/07/19(水) 09:14:39
>>630
gcc hoge.c -lpthread

>>631
どういう意味ですか? 同時に複数のスレッドが accept() しないように
しただけですが?

>>632
これは阿呆な手段ですか? 何故? その辺詳しく教えてもらえますか?
どこで習ったかは記憶にありません。ただ昔 Java で似たようなものを
作った時はちゃんと動いたと思いました。

>>633
それはつまり accept() は親(?)スレッド一つでやるということですね。
636デフォルトの名無しさん:2006/07/19(水) 10:02:36
accept()を排他しても、
そのプログラムがまともにうごかん事に疑問はないのか?

他の部分がおかしいだけではないのか?
637デフォルトの名無しさん:2006/07/19(水) 11:14:26
>>636
そこが疑問ですよ。なんで既に取得してオープンされているファイル
ディスクリプタと同じ値のファイルディスクリプタが返って来るのか
という点がね。

気になるのは Linux の場合スレッドは clone() システムコールで作った
特殊な別プロセスであるということです。別プロセスだから複数スレッドで
accept() した時に同一ファイルディスクリプタが取れてしまうんじゃない
かな、とは思ったんですが、確証がなかったので質問したんです。
(Linux板の方で質問した方がよかったかな? でも他のOSではこういうのは
できないのかも少し気になる)。

で、その後、accept() を一つのスレッドでだけやって、他のスレッドは
待機させておいて、accept() 成功後にファイルディスクリプタを待機
スレッドに渡すように作り替えたらちゃんと動くプログラムは作れました。
理由はどうあれこういう風にするか、あるいは accept() 成功後にスレッド
作るように書かないと駄目なようですね。
638デフォルトの名無しさん:2006/07/19(水) 11:25:03
>>627
> int cs = accept(...); // ここで cs が別スレッドと同じ値になる。
本当にこれと同じ書き方だったんだな?
csが大域変数だったってオチがありそうだ。
639デフォルトの名無しさん:2006/07/19(水) 11:30:07
>>638
いいえ。大域ではありません。autoです。
640デフォルトの名無しさん:2006/07/19(水) 12:26:13
生半可な学習しないで、ファイルディスクリプタについてちゃんと勉強したら?
641デフォルトの名無しさん:2006/07/19(水) 13:35:02
>>637
>スレッドは clone() システムコールで作った
ちょwwwwおまwwwww帰れwwwww
642デフォルトの名無しさん:2006/07/19(水) 13:56:58
げ、pthread_createで作ってんじゃないのか・・・!!!
643デフォルトの名無しさん:2006/07/19(水) 14:24:08
>>640
生半可? どの辺がですか?

>>641-642
pthread_create() で作ってますよ。clone() は内部動作の話です。
644デフォルトの名無しさん:2006/07/19(水) 14:29:47
こいつむかつく〜☆
645デフォルトの名無しさん:2006/07/19(水) 14:36:37
>>643
コンパイルオプションとかはどうだろう・・・ -pthread とか付け忘れありませんか?
646デフォルトの名無しさん:2006/07/19(水) 14:42:25
647デフォルトの名無しさん:2006/07/19(水) 14:48:29
>>643
続きは以下で。
ネットワークプログラミング相談室 Port17
http://pc8.2ch.net/test/read.cgi/tech/1148944560/
648デフォルトの名無しさん:2006/07/19(水) 14:59:44
>>646
-lpthread だけ指定して -pthread を指定していないのではないか、といっているのだが。
649デフォルトの名無しさん:2006/07/19(水) 15:38:16
>>648
-pthread は指定していませんでしたが、man ページや info 見ると
Linux では関係ないようですよ。

念のため指定してテストしてみましたが、同じ動作になりました。
650デフォルトの名無しさん:2006/07/19(水) 15:45:45
いい加減、誰かファイルディスクリプタの説明してやれよw
651デフォルトの名無しさん:2006/07/19(水) 15:47:52
>>647
そっちの方がいいですか?
スレッドとネットワークと Linux が混ざった疑問なのでどこがいいのか迷ったんですが。
652デフォルトの名無しさん:2006/07/19(水) 16:00:17
>>640>>650
pthread_createで作ったスレッド間では、ファイルディスクプリタは共有されます。
すなわち、同じ数値=同じソケット端点。
何がいいたのか知らんがこれでいいか?
653デフォルトの名無しさん:2006/07/19(水) 16:06:07
>>651
どっちがいいのかはわからんけど、このスレじゃ解決できなさそうじゃん。
654デフォルトの名無しさん:2006/07/19(水) 16:20:45
Linuxのスレッドが特別なプロセスだったのは、2.4より前の話だよ。
# 例えばpidやsignalの扱いなど。
>>627は、2.6.17だから関係ない。
655デフォルトの名無しさん:2006/07/19(水) 16:21:59
>>637
> accept() 成功後にスレッド作るように書かないと駄目なようですね。

そんなことはない。
656デフォルトの名無しさん:2006/07/19(水) 16:22:13
>>652
それは知ってますよ。だからこそOSがおかしいんじゃないかと思ったんですから。

元々の質問を要約すると、まだ close() されていないファイル
ディスクリプタの値を accept() が返して来るのは何故かです。
一つのスレッドが accept() で 5 を受け取ったとして、それが
close() される前にもう一つのスレッドが行った accept() が
受け取ったファイルディスクリプタの値も 5 だったということです。
これ、accept() を一つのスレッドでしかやらなければ当然 6 などの
違う値が返って来ます。

>>653
今のところそんな感じしますね。
657デフォルトの名無しさん:2006/07/19(水) 16:24:17
>>654-655
そうですか…。じゃあ何でだろう?
658デフォルトの名無しさん:2006/07/19(水) 16:26:01
こっちの方がいいかも。
UNIX板 pthread地獄
http://pc8.2ch.net/test/read.cgi/unix/1010933537/
読んでる人はこの板と重複がかなりあるかもだけど。
659デフォルトの名無しさん:2006/07/19(水) 16:34:42
>>658
そこはたしかに近いこと話し合われてたスレですね。
じゃあそこに移転します。

こちらのスレのみなさまありがとうございました。
660636:2006/07/19(水) 23:13:46
な?
661デフォルトの名無しさん:2006/07/20(木) 01:05:07
うはwww
ボッコボコwww
しかも自分のミスwww
662デフォルトの名無しさん:2006/07/20(木) 12:50:33
>>640>>650
お前等も黙ってないで「ファイルディスクリプタの説明」してくれよw
663デフォルトの名無しさん:2006/07/20(木) 13:12:28
File Disk Riptor 略して FDR である
664デフォルトの名無しさん:2006/07/20(木) 14:35:46
なんか車の駆動方式っぽい略称だな。
665627:2006/07/20(木) 16:04:12
申し訳ありません。私がバグっておりました。

accept() 後の処理を別関数でやっていたのですが、その中で
fdopen() を使って accept() で受け取ったファイルディスク
リプタから FILE * を作って fgets() や fprintf() を使って
いました。それでその関数から返る直前に fclose() をして
いますが、そうすると当然元となったソケットも close()
されます。

このことをすっかり忘れていたためこの別関数から戻って
来ても accept() で取ったファイルディスクリプタは
オープンしたままだと思い込み、別関数から帰って来てから
close() までの間に別スレッドで accept() した時の
ファイルディスクリプタと同じ値になることがあったため、
今回の疑問に繋がっていました。

ということでお騒がせしました。
Linux でも複数スレッドからの accept() は問題無くできます。
666デフォルトの名無しさん:2006/07/20(木) 16:25:36
まあせいぜい地雷原を走り抜けてくれ
667デフォルトの名無しさん:2006/07/21(金) 20:41:07
Javaだと複数のスレッドがacceptでブロックしてても動いたと思う。
ttp://www.amazon.co.jp/gp/product/4274065200/ の例の1つにあったと思う。

個人的にはとても気持ち悪いし、他の人にコードを見せると頭を抱えるし、
特にメリットも思いつかないので、
自分はJavaでもacceptは1つのスレッドで実行してる。
668デフォルトの名無しさん:2006/07/21(金) 20:54:45
この人の場合、さらに non-blocking にしてあって、ブロックしないでポーリングしてるらしいよw
669デフォルトの名無しさん:2006/07/21(金) 21:16:04
>>667
> 特にメリットも思いつかないので、

はあ
670デフォルトの名無しさん:2006/07/22(土) 00:47:01
試したことはないが、
複数のThreadがServerSocket#accept()でブロックされてるとき、
ブロック解除で起こされるThreadはたぶん唯1つなのがメリットじゃないかな。
単一のThreadがaccept()待ち→ブロック解除→Queueに放り込んでWorker Threadを
たたき起こすパターンだと、Queueを監視する複数のWorker Threadがいったん
たたき起こされるから。
671デフォルトの名無しさん:2006/07/23(日) 09:39:44
672デフォルトの名無しさん:2006/07/26(水) 17:24:59
お世話になります。
識者のご意見ください。

以下のような状況です。(環境はVC6のWin32API)

メインスレッドAと、待機スレッドBがあります。
BはSuspend状態です。

あるタイミングでAがBに仕事を投げてResumeしました。
Bは仕事が終わったら自分でSuspend状態になりたいのです。

Bは自分のHANDLEをSuspendThreadしちゃってもいいものでしょうか?
AがBのフラグを見てSuspendしてやるというのはちょっと効率が
悪い気がします。

以前はBを待機スレッドではなく、その都度生成して自殺させていました。
が、この方法だとデバッグウインドウに生成と消滅のメッセージが
出まくるのと、やはりCreateThreadの負荷が気になります。

こういう場合の常套手段など、ご教示ください。
待機スレッドがCPUを食わないようにするために、Suspend状態に
しておく、という風に考えるのは変でしょうか?

よろしくお願い致します。
673デフォルトの名無しさん:2006/07/26(水) 17:36:12
>>672
ただのワーカースレッドでええんちゃうかと
マイクロスレッドのようなものを考えてるなら、ファイバでも使えばいい
674デフォルトの名無しさん:2006/07/26(水) 17:36:23
>>672
自分をSuspendするのは悪くない。というか、それが唯一のSuspendThreadの正しい使い方。
基本的には自スレッド以外をSuspendThreadしてはいけない。

ただし、普通はautoresetのイベントハンドルを用意して WaitForSingleObject で待たせておき、
SetEventで起こす。これはAがBをResumeThreadで起こすのが難しいから。

具体的には、SuspendThread/ResumeThreadで待機を実現しようとすると、
ResumeThreadするときに、ちょうどBが何かの仕事を終えてSuspendThreadする
直前だったりするとResumeしても即Suspendしてしまうので、これを避けるために
クリティカルセクションとフラグが1つ余分に必要になってしまって効率も悪いし
コードもムダに複雑になる。
675デフォルトの名無しさん:2006/07/26(水) 18:07:51
みなさん、レス有難うございます。

>>674
>autoresetのイベントハンドルを用意して WaitForSingleObject で待たせておき

こんな感じでしょうか?

スレッドB{
while(1){
WaitForSingleObject(XXX);
何か仕事(B*)
}
}

スレッドA{
while(1){
何か仕事の準備(実行中のB*の部分を触らない配慮はしている)
SetEvent(XXX);
}
}

>直前だったりするとResumeしても即Suspendしてしまうので
なんとなく現象の心当たりがあります。

676デフォルトの名無しさん:2006/07/26(水) 18:21:59
>>675
Bが待機するところはそんな感じです。

あとまぁよく使うパターンとしては
(1) AがBの仕事の完了を待たずににいくつもの仕事を投げておけるようにQueueに仕事を登録して SetEvent する。Bは起こされたら、Queueにある仕事を全て実行してからWaitする。
(2a) 「仕事終わったよイベント(初期値はON)」ってのも用意して、Bが仕事を終えたらSetEventする。Aは仕事終わったよイベントを待ってからBを起こす
(2b) CreateSemaphoreでMaxCount 1 のセマフォを作って、AはWait,→仕事の準備→ReleaseSemaphore、
  BはWait→仕事を取り出して実行→ReleaseSemaphore とする。

仕事が終わったかどうか知りたくなることも多いので、漏れは2aのパターンを多用します。
殆ど等価な 2b でもいいのかも知れない。
677デフォルトの名無しさん:2006/07/26(水) 19:36:15
>>676
Suspend,Resumeでやってたところを待機オブジェクトにしました。
すっきりした感じがします。
>(2a)
なんとなくこれっぽいことはやっていました。
どうもありがとうございました。
678デフォルトの名無しさん:2006/07/26(水) 21:47:50
lock-freeについて調べている内に
CAS(CompareAndSwap)という概念にたどりついたのですが
ちょっと教えてください。
/* 関数内の処理はatomicに処理されると仮定*/
bool CAS(void*addr,int expval,int newval){
if(*addr == expval){
*addr = newval;return true;
}
return false;
}
*addr=0;
while(!CAS(addr,0,*addr + 1)){
//※ここでコンテキストスイッチ
}
//アトミックにインクリメント成功?
例えば※の部分で別スレッドがaddrの値を5に変更→0に変更
という動きをした場合、*addr == expvalが成り立ってしまい、
インクリメント成功とみなされてしまう気がするのですが・・・
何か回避策等あるんでしょうか。それとも俺の理解不足なんでしょうか
679デフォルトの名無しさん:2006/07/26(水) 23:07:03
>>678
「アトミックなインクリメント」というものを理解していないような気がする。
過去に5だったかどうかはさておき、他のスレッドで0にされたものが1に
なるのだから成功している。
というか5で放置されてて6になってもやはり成功。

*addr=0;
IntgerlockedIncrement(&addr); ←APIによるアトミックなインクリメント
などとしたところで、この2行の間に*addrが5になって0になることもある。

「アトミックなインクリメントに失敗」というのは、2つのスレッドで1度ずつ
アトミックなインクリメント操作が行われたにも関わらず2増えないことを言う。
これは正しい実装では決して起きない。
680デフォルトの名無しさん:2006/07/26(水) 23:07:59
追記:
CASによるアトミックなインクリメントの実装は、正しくは↓

while (!CAS(addr, *addr, *addr+1) {}
681678:2006/07/27(木) 21:49:17
>>679
>>680
ありがとうございます。

addr=&val;
while(!CAS(addr,*addr,*addr + 1)){
//※ここでコンテキストスイッチ
}
でも問題が起きそうな気がするんですが・・

とここまで書いて
http://www-06.ibm.com/jp/developerworks/java/041203/j_j-jtp11234.html
に似たような事が書いてありました
ABA問題というらしいですが

もうちょっと勉強してでなおしてきます・・
682デフォルトの名無しさん:2006/07/27(木) 23:41:31
とりあえず、CAS(xxx, *addr, *addr+1)
なんて書いている奴は氏んでいいよ。

atomic_inc(int *addr)は
do {
 int var = *addr;
} while (!CAS(addr, var, var+1));
にしないと。

まあ、複数のスレッドで勝手に値をセットするような変数を
特定の個所だけatomic_incを使っても意味は無いがね。
683デフォルトの名無しさん:2006/07/28(金) 00:03:12
終わった話題についてなにを得意げに語ってるんだろう…。
684デフォルトの名無しさん:2006/07/28(金) 00:20:12
>>682
それC言語的にやばいやん。
685デフォルトの名無しさん:2006/07/28(金) 00:31:47
つまり、「ほんと、バカしかいないんだね」ってことか。
686デフォルトの名無しさん:2006/07/28(金) 00:43:19
やーい
ばかー
687デフォルトの名無しさん:2006/07/28(金) 07:26:02
volatileですべて解決!
688デフォルトの名無しさん:2006/07/28(金) 12:24:47
>>682
バカは喪前のほうだと思うが・・・
なぜ自分がバカなのかが知りたかったら、
元のコードの問題点を書いてご覧よ。
書いてるうちにわかるだろ。
689デフォルトの名無しさん:2006/07/28(金) 17:51:17
元のコードの問題点は関係なくて
*addrを2度読み出して同じ値が取れると思っているのがバカだって事だろ。
690デフォルトの名無しさん:2006/07/28(金) 17:53:25
しかも、この手のバグは非常に表面化しにくく
再現性が低い(デバッグが難しい)。
691デフォルトの名無しさん:2006/07/29(土) 15:08:13
volatileですべて解決するという忠告がみえないのか?
692デフォルトの名無しさん:2006/07/29(土) 16:14:19
別CPUから発言が見えるようになるまでには時間がかかります
693デフォルトの名無しさん:2006/07/29(土) 18:15:53
VC++とMFCでマルチスレッドなサーバープログラムを書いています。
サーバープログラムを終了する時、ソケットが走ってるスレッドを終了させないといけませんが、
スレッドに終了を通知する手段が分かりません。
どのように終了を通知するのか教えていただけないでしょうか。

よろしくお願いします。
694デフォルトの名無しさん:2006/07/29(土) 19:01:50
ソケットをどういう風に使ってるかによると思うけど、イベントとか単なるフラグとか。
695デフォルトの名無しさん:2006/07/29(土) 19:36:20
>>693
ExitProcessで自殺すればおk
696693:2006/07/29(土) 19:49:37
CAsyncSocketを継承して作ったUDPのソケットです。
クライアントからやってくるパケットをRecvFromで受けて、データに応じてSendToしているだけです。

現在、スレッドを閉じるのにdeleteでデストラクタを呼び、強制的に終了させているのですが
デバッガで追っかけていくとCAsyncSocketの中でエラーが発生します。
詳細は不明ですがおそらくソケットを閉じずに終了したためではないかと思います。

Win32APIでマルチスレッドなプログラムを組んだときはPostThreadMessageで終了メッセージを
送って、WaitForSingleObjectでスレッドが落ちるのを待っていたのですが、MFCで
そのような手順を踏んだ終了の仕方は(強制終了じゃないやり方)ないのでしょうか?
697デフォルトの名無しさん:2006/07/29(土) 20:28:56
CAsyncSocketて使ったことないから知らないけど、
非同期に通信してるなら終わりにするかどうか判断する機会はあるんじゃないの?
698デフォルトの名無しさん:2006/07/29(土) 20:48:34
CAsyncSocketのデストラクタが動けば万事OKみたいなことMSDNには書いてあるけど。
スレッドを強制終了するから、そのスタックにあるCAsyncSocketがリークしてるとか、
そういうこと?
699693:2006/07/29(土) 21:12:35
>>697
複数台の設備との通信をするサーバープログラムなのですが、設備のON/OFFとサーバーのON/OFFは
必ずしもリンクしていません。一応作業標準として順序だてることは可能ですが、予想外のトラブル(瞬停など)を
考えると何かのパケットが来たらソケットを閉じてもいいとはできません。
サーバープログラムを閉じる作業中にソケットが走っているスレッドに終了を通知できればいいのですが
その方法がわからないのです。

>>698
>そのスタックにあるCAsyncSocketがリークしてるとか
そのとおりです。
700デフォルトの名無しさん:2006/07/29(土) 21:18:08
スレッドが終了する時のイベントハンドラで
CAsyncSocketをdeleteじゃダメって事?
701デフォルトの名無しさん:2006/07/29(土) 21:24:23
>>700
今はスレッドのデストラクタでCAsyncSocketをdeleteしていますが、その中でエラーになります。
702デフォルトの名無しさん:2006/07/29(土) 21:38:00
ねぇ。マルチスレッドって何?
703デフォルトの名無しさん:2006/07/29(土) 21:40:39
multi 【名-1】 (複数{ふくすう}の色調{しきちょう}からなる)縞模様{しま もよう} 【名-2】 マルチビタミン(錠剤{じょうざい})
thread 【名-1】 (繊維を束ねた)糸、より糸 【名-2】 糸[繊維]状のもの、細い筋状のもの 【名-3】 (全体をつなぎ止める)筋、(話などの)脈絡{みゃくらく}
704デフォルトの名無しさん:2006/07/29(土) 21:53:15
縞模様の筋ですか?
705デフォルトの名無しさん:2006/07/29(土) 21:55:30
筋肉のことですか?
706デフォルトの名無しさん:2006/07/29(土) 22:29:03
>>691
まさかとは思うけど、本気で言ってるわけじゃないよね?
707デフォルトの名無しさん:2006/07/30(日) 00:24:25
>>689
だって別に同じ値じゃなくても問題ないんだよ。
単にその1度のCAS呼び出しがfalseになるだけ。
708デフォルトの名無しさん:2006/07/30(日) 00:32:23
>>707
第3引数の *addr + 1 を評価した後に別スレッドによって *addr の値が変更され、
その後に第2引数の *addr が評価されるとアウト。
709デフォルトの名無しさん:2006/07/30(日) 09:43:28
>>701
スレッドを強制終了させないで、外部から何かきっかけを与えて自分で終わるようにすればいいだけじゃん。
710デフォルトの名無しさん:2006/07/30(日) 15:36:23
>>691>>707
>>708の言うように、
「CASの第2引数の値」と「CAS呼び出し時に*addrに入っている値」
これが違うのは問題ないが
「CASの第2引数と第3引数の値の差」が1でない場合に誤動作する。

コンパイラの最適化で読み出しが1回になるケースもあるだろうが
最適化オプションで動作が異なるのはデバッグを難しくするだけ。

volatileを使えば、読み出しが2回になることが保証されるだけ。
711デフォルトの名無しさん:2006/07/31(月) 13:37:43
一般的な双方向リストをマルチスレッドで使うとまずいですか?

new -> next = next;
/* ここでスレッドが切り替わるとか? */
new -> prev = next -> prev;

みたいな事が起きるとうまく繋げないような気がします。
WinAPI を使ってオブジェクトかなにか?を作って排他制御する
必要があるのでしょうか?
712デフォルトの名無しさん:2006/07/31(月) 13:41:09
問題ないw
713デフォルトの名無しさん:2006/07/31(月) 15:11:21
>>711
まずい。複数スレッドからappendすると、ノードが行方不明になったりする。
ただ、スレッドセーフな双方向リストにするより、
外部の同期オブジェクトを使ってそのリストへのアクセスを同期化する方が
柔軟。
714デフォルトの名無しさん:2006/08/01(火) 06:53:40
volatileですべて解決!!!
715デフォルトの名無しさん:2006/08/01(火) 10:44:44
この話では無理w
716デフォルトの名無しさん:2006/08/01(火) 11:20:51
>>711
問題ない
関数内ではスレッドの切り替えは起こらない
717デフォルトの名無しさん:2006/08/01(火) 11:51:13
preemption はいつでも起こりうるでしょ
718716:2006/08/01(火) 12:39:23
起こらないでしょ
719デフォルトの名無しさん:2006/08/01(火) 12:43:33
>>716
何を根拠に言ってんの?
720デフォルトの名無しさん:2006/08/01(火) 12:51:51
ようやくWindowsのメッセージディスパッチのことを理解したばかりのヒトが
それをマルチスレッドだと思い込んでるんでしょう。
721デフォルトの名無しさん:2006/08/01(火) 13:19:11
>>716 は、ユーザレベルスレッドしか使った事無い人なんでしょうかね。
722デフォルトの名無しさん:2006/08/01(火) 13:23:44
>>716はWin3.1ユーザー
723デフォルトの名無しさん:2006/08/01(火) 13:24:48
実装がユーザレベルかカーネルレベルかと、プリエンプティブかコ・オペレーティブかは関係ないだろ。
724デフォルトの名無しさん:2006/08/01(火) 13:33:14
関数内では起こらないってのもすごいよな。
普通は全てmainの関数内なんだが。
まあWndProcはまた別だが、それもWinMain内ででGetMessageしてるわけだし。
725716:2006/08/01(火) 14:35:50
反省^^
726デフォルトの名無しさん:2006/08/01(火) 22:51:18
>>723
そこに異論は無いけど、言いたい事は分かるでしょ。
727デフォルトの名無しさん:2006/08/02(水) 08:14:08
まあ、あれだ。がんがりたまえ(笑)
728デフォルトの名無しさん:2006/08/02(水) 12:46:56
一般的なのはミューティックスを作る方法なの?

729デフォルトの名無しさん:2006/08/02(水) 13:49:28
ディスクトップでディスクリプタをミューティックスで保護することを考察
730デフォルトの名無しさん:2006/08/02(水) 14:34:13
むてふ
731デフォルトの名無しさん:2006/08/02(水) 14:47:18
ティキストエデタ
732デフォルトの名無しさん:2006/08/02(水) 15:05:17
www
733デフォルトの名無しさん:2006/08/02(水) 23:11:34
ヴォラタィル
734デフォルトの名無しさん:2006/08/03(木) 08:56:51
コンピゥタァ
735デフォルトの名無しさん:2006/08/03(木) 12:30:55
モシ NO=735 ナラバ トベ >>1000
736デフォルトの名無しさん:2006/08/03(木) 14:38:59
static bool g;

if (!g && g = true) {}

この if ()の中でスレッド切り替えって起こります?
排他処理になりませんか?

737デフォルトの名無しさん:2006/08/03(木) 14:54:43
>>736
その g = true というのは本当に g = grue なのか?
それとも g == true の書き間違い?
738デフォルトの名無しさん:2006/08/03(木) 14:56:56
あ、俺も書き間違えた。すま。
739デフォルトの名無しさん:2006/08/03(木) 15:47:48
>>736
> この if ()の中でスレッド切り替えって起こります?
起こる

> 排他処理になりませんか?
ならん
740デフォルトの名無しさん:2006/08/03(木) 18:52:39
w
741デフォルトの名無しさん:2006/08/03(木) 21:56:53
ちょっと待てよ。C言語だとするとショートサーキットだよな?
!g の結果が false なら g = true は実行されないよな。
true なら実行される。

排他になるんじゃないか?
742デフォルトの名無しさん:2006/08/03(木) 22:01:59
ひょっとしたら
!g
がアトミックじゃない処理系もあるかも
743デフォルトの名無しさん:2006/08/03(木) 22:02:10
ショートサーキットは関係ない。
!gの評価と、g=trueの間にスレッドが切り替わる可能性があれば、排他として役に立たない。
744デフォルトの名無しさん:2006/08/03(木) 22:31:23
アセンブラレベルで考えるんだ
745デフォルトの名無しさん:2006/08/03(木) 22:49:20
なんだろ? 書き込み見てると、CPU命令レベルでの挙動に思い至らないのが居るな。
ソースレベルの字面で捉えてコンパイルというのが何なのかまったく知らないよう
に思える。

こんなんで日本のプログラマーのレベルは大丈夫なのか? 小中学生だったら
知らなくても無理は無いのか。
746デフォルトの名無しさん:2006/08/03(木) 23:05:44
アセンブラまで降りる必要は必ずしも無いとは思うが
メモリの読み込みと書き出しを同時(atomic)に行うことは
(普通は)出来ないということくらいは知っておく必要がある。

もちろん、プロセッサはそのための命令を(普通は)用意しているが
コストがかかるため、普通にソースを書いた場合
コンパイラはその命令を使ったコードは出力しない。
747デフォルトの名無しさん:2006/08/03(木) 23:16:40
えらそうに講釈たれてても

> 同時(atomit)

この一言で台無しだな。
748デフォルトの名無しさん:2006/08/03(木) 23:25:35
>>747
お前いらないから
749デフォルトの名無しさん:2006/08/03(木) 23:36:58
必死な子がいるなぁ。
750デフォルトの名無しさん:2006/08/03(木) 23:39:29
>>747
別のプロセッサに割り込まれないように
lock等で保護してからxchgしたりincしたりnegしたりするけど
それをatomicと言わないとでも?

例えばあるメモリの内容を+1する場合、
「+1する命令をメモリに対して発行する」ではなくて
「プロセッサがメモリを読んで、+1した値をメモリに書き込む」だし。
751デフォルトの名無しさん:2006/08/03(木) 23:58:41
なに一生懸命説明してるの?

これスレでそんなこと知らない奴なんてあまりいないよ。

俺はただ「atomic」と「同時」って全然違うって言いたいだけなんだが。

まあ俺も atomit とか書いてるようじゃ人のことは言えないわな。(w
752デフォルトの名無しさん:2006/08/04(金) 00:03:37
>>751
もう消えてね(^^)
753デフォルトの名無しさん:2006/08/04(金) 00:18:24
>>751
ずいぶん必死ですね。
754デフォルトの名無しさん:2006/08/04(金) 00:20:13
最近なりを潜めてる、某キティと文体が似てる・・・
755デフォルトの名無しさん:2006/08/04(金) 01:02:29
読むのと同時に書かないと壊れるメモリもあるだぜ?
756デフォルトの名無しさん:2006/08/04(金) 01:19:47
「atomic」は日本語で言ったら「不可分」ちうことですわ。
757デフォルトの名無しさん:2006/08/04(金) 01:23:06
原子力って感じかと思ってた
758デフォルトの名無しさん:2006/08/04(金) 03:38:13
分割不可能な最小単位つうことですょ
759デフォルトの名無しさん:2006/08/04(金) 03:51:04
つまり、鉄腕アトムは分割不可能と言うことで宜しいか。
760デフォルトの名無しさん:2006/08/04(金) 04:08:01
「atomic」には他に「原子の」みたいな意味もあるんですわ。
昔は原子(atom)は物質の不可分な最小単位と考えられていたので。
どっちの意味が先か知らんけどね。
761デフォルトの名無しさん:2006/08/04(金) 07:05:02
で、何が言いたいんだ?
762デフォルトの名無しさん:2006/08/04(金) 07:11:33
atomic bomb 分割不可能な爆弾
763デフォルトの名無しさん:2006/08/04(金) 07:12:41
割ったら被爆しちゃうからね
764デフォルトの名無しさん:2006/08/04(金) 07:17:17
>>761
誰でも知ってるような事をちょっと偉そうにしゃべくってみたかっただけですわ。
765デフォルトの名無しさん:2006/08/04(金) 07:18:59
被爆と被曝
766デフォルトの名無しさん:2006/08/04(金) 07:55:02
>>764
何のために?
767デフォルトの名無しさん:2006/08/04(金) 07:57:34
>>760
なに一生懸命説明してるの?

これスレでそんなこと知らない奴なんてあまりいないよ。
768デフォルトの名無しさん:2006/08/04(金) 08:37:02
「同時」って書いちゃうヤツ以外はね。
769デフォルトの名無しさん:2006/08/04(金) 08:45:15
VRAM(昔のやつ)やWRAM(初代Milleniumが採用した奴)を思い出した。
770デフォルトの名無しさん:2006/08/04(金) 09:45:01
>>768
どこが変なのか未だにわからんのだが?

「読み込みと書き込みが同時に出来ない」
だから
「読み込みと書き込みをatomicに出来ない」(バスロックしなければ)
という意味なんだけど?
771デフォルトの名無しさん:2006/08/04(金) 09:48:31
>>764
俺は知らなかったからタメになりましたよ
一応ありがとう
772デフォルトの名無しさん:2006/08/04(金) 09:53:42
この流れ見て、コンカレントとパラレルの違いが理解出来なかった当時を思い出した
773デフォルトの名無しさん:2006/08/04(金) 10:49:55
既に「atom」という言葉があるからこそ、物質の探求の過程で原子にその言葉を当て嵌めたってことくらい
>758を理解していたら考えるまでもないだろ。
774デフォルトの名無しさん:2006/08/04(金) 11:02:32
>>770
同時(simultaneous)と、不可分(atomic)の違い。
775デフォルトの名無しさん:2006/08/04(金) 11:03:28
意味が分からねえ・・・
776デフォルトの名無しさん:2006/08/04(金) 11:10:09
>>770
恥の上塗り
777デフォルトの名無しさん:2006/08/04(金) 12:38:57
ガキ共の言葉遊びここまで
778デフォルトの名無しさん:2006/08/04(金) 12:49:23
じゃあ今から大人の言葉遊びか・・・エロス
779736:2006/08/04(金) 13:14:37
if (g = g ? false : true)

この場合でも排他にならない??
アホですまん
780デフォルトの名無しさん:2006/08/04(金) 13:19:58
C言語のレベルでどの式がアトミックになるかという事に依存するのが間違いだと思う。
現存する全ての環境でアトミックに実行されるような式でも、それは処理系依存。
781デフォルトの名無しさん:2006/08/04(金) 13:21:37
その後、原子は分割可能であることが判明してしまいました。
782デフォルトの名無しさん:2006/08/04(金) 13:25:55
陽子と電子に分割できるんだっけ?
783デフォルトの名無しさん:2006/08/04(金) 13:27:46
あと中間子
784デフォルトの名無しさん:2006/08/04(金) 13:40:08
それらの素粒子も実は更に……
つーのはやめておこうか。
785デフォルトの名無しさん:2006/08/04(金) 14:05:25
>>779
そもそもどう排他したいの?
786デフォルトの名無しさん:2006/08/04(金) 14:21:49
mkdir() は atomic らしい
787779:2006/08/04(金) 14:38:19
リスト処理でつなげるときに排他したいけど
WinAPI使うしかないみたいですね
788デフォルトの名無しさん:2006/08/04(金) 14:39:02
デッドロックになってしまった場合に
一定時間後に解除するような作りにしたいとき

mkdir() だと unlink() すると atomic では
なくなってしまう危険があるので

rename() の方が良いそうです

http://www.din.or.jp/~ohzaki/perl.htm
789デフォルトの名無しさん:2006/08/04(金) 15:16:39
>>779
もう諦めて、素直に同期オブジェクト使いなさい。
790デフォルトの名無しさん:2006/08/04(金) 15:28:11
mutex使わないのはなぜですか
791デフォルトの名無しさん:2006/08/04(金) 17:00:56
Windowsでプロセス内だけでいいならCriticalSectionのほうが速いんじゃなかったっけ
792デフォルトの名無しさん:2006/08/04(金) 18:32:01
>>787
それならCriticalSectionで十分
793デフォルトの名無しさん:2006/08/04(金) 18:35:59
>>787
これもAPIになるけど、InterlockedCompareExchangeとかでも自分でロックを作れる。
ただ、CriticalSection使うほうが簡単でおすすめ
794デフォルトの名無しさん:2006/08/04(金) 22:35:03
>>755
> 読むのと同時に書かないと壊れるメモリもあるだぜ?

kwsk
795デフォルトの名無しさん:2006/08/04(金) 22:42:15
それはリフレッシュのことかね。
796デフォルトの名無しさん:2006/08/04(金) 22:56:05
「メモリなどの外部デバイスに対して複数の入出力をatomicに行うには同時にやるしかない。ロックしないならば」
という文章があったとします。

この文章の最後を無視して
『メモリなどの外部デバイスに対して複数の入出力をatomicに行うには同時にやるしかない』
だけを引用して
「ロックすればいいじゃん。バカじゃねーの?」
と書き込むのは、とても恥ずかしいですね。


では、前半部も無視して
『atomicに行うには同時にやるしかない』
だけを引用し、
「同時とatomicは違うだろ。バカじゃねーの?」
と書き込むのは、どのくらい恥ずかしいことなんでしょうかね。

まあ夏休みだから、「こくご」の能力がちょっと不足している人が現れるのも
仕方ないかもしれませんが。
797デフォルトの名無しさん:2006/08/04(金) 23:29:16
746 名前:デフォルトの名無しさん:2006/08/03(木) 23:05:44
アセンブラまで降りる必要は必ずしも無いとは思うが
メモリの読み込みと書き出しを同時(atomic)に行うことは
(普通は)出来ないということくらいは知っておく必要がある。
798デフォルトの名無しさん:2006/08/04(金) 23:34:11
>>797
ロックすれば、読み込みと書き出しを同時に行わなくてもatomicに実行できるよ
799デフォルトの名無しさん:2006/08/04(金) 23:43:27
>>795
D-RAM は、読んだらデータが壊れるから再書き込みするけど、
あれは読んだデータを後から書き込んでるから同時じゃない。

正解を教えてくれ >>755

>>796
> という文章があったとします。

どこに? 君の脳内?

ちょっと頭冷やせよ。
800デフォルトの名無しさん:2006/08/04(金) 23:45:22
そんなの基礎知識でしょ
801デフォルトの名無しさん:2006/08/04(金) 23:47:39
文脈や前提を無視して言葉尻をとらえるのが大好きな方がいらっしゃるようで。
802デフォルトの名無しさん:2006/08/04(金) 23:48:16
で、そういう人には揶揄や皮肉は通用しませんね。
803デフォルトの名無しさん:2006/08/05(土) 00:15:01
746 名前:デフォルトの名無しさん:2006/08/03(木) 23:05:44
アセンブラまで降りる必要は必ずしも無いとは思うが
メモリの読み込みと書き出しを同時(atomic)に行うことは
(普通は)出来ないということくらいは知っておく必要がある。
804デフォルトの名無しさん:2006/08/05(土) 00:28:38
>>787
排他だけなら、アセンブラとか、asm文とか使えばいいけど、
CPUを離すのは、API使わないと無理。
# というか使った方がいい。
# ユーザランドだけで実装されたマルチスレッドライブラリもあるけどさ。
805デフォルトの名無しさん:2006/08/05(土) 00:31:32
破壊読み出しなのは、コアメモリもそう
806デフォルトの名無しさん:2006/08/05(土) 01:45:45
>>803

もちろん、プロセッサはそのための命令を(普通は)用意しているが
コストがかかるため、普通にソースを書いた場合
コンパイラはその命令を使ったコードは出力しない。
807デフォルトの名無しさん:2006/08/05(土) 02:10:07
( ゚д゚)ポカーン
808デフォルトの名無しさん:2006/08/05(土) 02:18:37
急に暑くなったからな。

そっとしておいてやれ。
809デフォルトの名無しさん:2006/08/05(土) 02:23:40
最近近くに引っ越してきたvolatile asmというものですが何か?
810デフォルトの名無しさん:2006/08/05(土) 02:31:33
811デフォルトの名無しさん:2006/08/05(土) 09:44:05
volatile最高!!!

無駄にmutexしてる奴、馬鹿杉www

sizeof(int)以下ならlockなんて不要www
812デフォルトの名無しさん:2006/08/05(土) 09:54:47
本気で言ってんの?

だからvolatileと排他のロック概念は関係ないっつーの。

volatileは他のコンテキストや割り込みで変更される可能性
があることをコンパイラに知らせて最適化を抑制するだけ。

>sizeof(int)以下ならlockなんて不要www
大抵はうまく行くだろうが、時たま失敗するだろう。

以下を沢山のスレッドつくって呼び出しまくってみな。

volatile int a,b;
void foo(){
a++;
InterlockedIncrement(&b);
}

しばらく走らせていたらaとbが一緒になるか?
813デフォルトの名無しさん:2006/08/05(土) 10:14:01
>>811

本気で言っているとしたら
知らない人が知らないところで働いていることを理解できないようですね
814デフォルトの名無しさん:2006/08/05(土) 10:18:41
>>812
この人なんかずれてる…
815デフォルトの名無しさん:2006/08/05(土) 10:30:47
どの辺がすれてるのかkwsk
816デフォルトの名無しさん:2006/08/05(土) 10:33:19
字下げが
817デフォルトの名無しさん:2006/08/05(土) 12:49:28
オチがよろしいようで
818デフォルトの名無しさん:2006/08/05(土) 14:56:34
>>815
>>811は書き込みの話はしていない、ってことじゃ?
データバスサイズのリードの話に限定するなら、
普通はバスレベルでも割り込まれることはないから
わざわざバスロックする必要はないと。

「無駄にmutex」がツボだと思うんだけど、ちとエスパーすぎるかな。
819デフォルトの名無しさん:2006/08/05(土) 15:16:29
やさしすぎだと思う。
820デフォルトの名無しさん:2006/08/05(土) 16:42:27
そもそもCではvolatile参照の意味は処理系定義だ。
参照時にlock/unlockする処理系もありうるし、volatile参照を最適化で
削除してしまう処理系もある(マニュアルに書かれている)。

Javaのvolatileはまた違う意味を持っているし。
821デフォルトの名無しさん:2006/08/05(土) 19:31:21
ここ読め。
1.8 Program execution [intro.execution]
822デフォルトの名無しさん:2006/08/05(土) 21:02:19
>820でFA?
823デフォルトの名無しさん:2006/08/05(土) 22:17:01
>>820
volatile 参照の削除はできないだろ。
824デフォルトの名無しさん:2006/08/05(土) 22:25:56
>>823
820が言うとおりvolatile参照は処理系定義。
某組み込み向けコンパイラでは、マニュアルに「sequence pointを含まない
式中のvolatile参照は削除されうる」と定義されていたりする。
825デフォルトの名無しさん:2006/08/05(土) 22:47:47
>>824
それって、ふたつのシーケンスポイントの間で同じ volatile オブジェクトを複数回
参照する場合、1回にまとめられることがある、ってことだよね?
826デフォルトの名無しさん:2006/08/05(土) 23:07:40
>>825
yes
827デフォルトの名無しさん:2006/08/06(日) 10:53:58
sequence pointウンヌンが書いてないから、

>820でFA?

はありえない。>>821の示しているものには詳しく書いてある。
そこのところをそのまま理解するのがFA。
828デフォルトの名無しさん:2006/08/06(日) 11:14:29
要はvolatileでokかngかは言語及び処理系依存ってこと。

それを無視して擁護する奴も批判する奴も間違っている。
829デフォルトの名無しさん:2006/08/06(日) 11:17:05
処理系定義の範囲は?
volatile参照に対してハードディスクをフォーマットするコードを出すのもありなのか?
830デフォルトの名無しさん:2006/08/06(日) 11:23:23
>>828
「volatileでokかngか」

こういういい加減な設問の立て方はやめれ
831デフォルトの名無しさん:2006/08/06(日) 11:24:07
>>829
それを処理系定義動作として明記していれば、それはANSI準拠なコンパイラとして正しい。

そんなコンパイラは売れないだろうが。
832デフォルトの名無しさん:2006/08/06(日) 11:30:01
じゃあvolatile参照の前後でlock/unlockするANSI Cコンパイラ作ったら売れるかな?
833デフォルトの名無しさん:2006/08/06(日) 11:56:47
>>832
自分で lock/unlock すればいい。そんな奇怪な動作をするコンパイラは要らない。
834デフォルトの名無しさん:2006/08/06(日) 16:58:08
じゃあvolatile参照の前後でミサイル発射するANSI Cコンパイラ作ったら売れるかな?
835デフォルトの名無しさん:2006/08/06(日) 17:09:29
自分で面白いと思って書いてるんだったら相当やばい。
836デフォルトの名無しさん:2006/08/06(日) 17:11:32
>>834
自分で発射すればいい。そんな奇怪な動作をするコンパイラは要らない。
837デフォルトの名無しさん:2006/08/06(日) 17:15:21
ていうかコンパイラだけでミサイル発射できるならしてみろw
838デフォルトの名無しさん:2006/08/06(日) 17:23:34
はいはい
続きはここでやれな
http://pc8.2ch.net/test/read.cgi/tech/1147746792/
839デフォルトの名無しさん:2006/08/09(水) 00:24:50
突然ですが非同期をするメリットって何でしょうか?
840デフォルトの名無しさん:2006/08/09(水) 00:38:57
シャンプー
841デフォルトの名無しさん:2006/08/09(水) 00:51:16
いや、メリットは同期してると思うが
842デフォルトの名無しさん:2006/08/09(水) 01:07:53
>>839
スレッド、プロセス、タスクはただ待たせとくには、
もったいなさ過ぎるリソースなんじゃ!

スレッドプールでぐぐれ!
843デフォルトの名無しさん:2006/08/09(水) 01:08:25
リンスも利いてるし?
844デフォルトの名無しさん:2006/08/09(水) 07:28:17
ZPt
845デフォルトの名無しさん:2006/08/09(水) 10:19:08
ちゃん・りん・しゃん、という選択肢
846デフォルトの名無しさん:2006/08/09(水) 10:23:33
>>842
スレッドプールの中のスレッドはほとんど待ってるだけだぞw
847842:2006/08/09(水) 11:11:59
>>846
プールとか書いたんは、俺なりの「サプライズ」や。
色んな意見があるのはわかっとるし、好きに言うたらええ。
俺はまた覚えたての言葉使って、レスしていくだけや。
848デフォルトの名無しさん:2006/08/09(水) 11:54:36
んまあ、I/Oとか凍り付いて待ってる間に他の仕事が出来るのがメリットだわね。
多くの場合、他の仕事っていうのは、ユーザに対して「やってますよ、生きてますよ」っていう
アピールをすることだったりするけどw
849デフォルトの名無しさん:2006/08/09(水) 12:49:31
>>846
馬鹿?
850デフォルトの名無しさん:2006/08/09(水) 13:14:16
だっておまい、単純なスレッドプールなら、
例えばプールにスレッドが10個あってタスクが2個だったら8つは待ってるだけじゃんか。
まあ、忙しさに合わせてスレッド数を適当に増減させるような実装も可能だけど。
851デフォルトの名無しさん:2006/08/09(水) 13:17:55
スレッドプールの利点
・タスクが200個あるけど、同時に動くのは最大10個
・スレッド生成が頻発な場合、生成のボトルネックを消す
852デフォルトの名無しさん:2006/08/09(水) 13:24:35
スレッド数の上限を制御したいときも使うわね

ていうかすみませんでしたよ。
軽い気持ちで書いただけなんですよごめんなさい。
853デフォルトの名無しさん:2006/08/09(水) 15:55:01
大したテクニックじゃない気がするんだが…。
854デフォルトの名無しさん:2006/08/09(水) 19:20:00
大したテクニックじゃないといけないのか?
855デフォルトの名無しさん:2006/08/09(水) 20:09:24
>>850
そんなの実装に依存。
議論するだけ無駄だなw

pool状態のthreadはqueueに入れないから、待つことはないって場合もあるだろうし。
856デフォルトの名無しさん:2006/08/09(水) 22:11:11
>>855
スレッド、プロセス、タスクはただ待たせとくには、
もったいなさ過ぎるリソースなんじゃ!

スレッドプールでぐぐれ!
857デフォルトの名無しさん:2006/08/09(水) 22:46:54
非同期のメリットは何かと聞かれてスレッドプールでググれって言われてもアレだな
858デフォルトの名無しさん:2006/08/10(木) 00:56:12
このエディタは非同期でテキスト入力してるっていわれたんだけど
じゃあ入力以外に何か処理やってるのかな?
859デフォルトの名無しさん:2006/08/10(木) 00:57:44
個人情報の流出
860デフォルトの名無しさん:2006/08/10(木) 07:40:47
仁義無きエディタ
861デフォルトの名無しさん:2006/08/10(木) 08:46:31
キー入力拾うのと、バッファに突っ込むのが非同期なんじゃね?
862デフォルトの名無しさん:2006/08/10(木) 09:39:08
>>858
GUIのエディタだと、
ウィンドウサイズ変えられるのに対応したり、
マウスで指定された範囲を反転表示したり。
863デフォルトの名無しさん:2006/08/10(木) 10:35:09
しながら同時にテキスト入力できるのか!
864デフォルトの名無しさん:2006/08/10(木) 10:39:46
>>858
画面出力とか。
865デフォルトの名無しさん:2006/08/11(金) 22:57:19
どこまでがマジレスなのか…
866デフォルトの名無しさん:2006/08/14(月) 21:40:21
みんなスレッドプールって最大数超えた場合どうしてる?
867デフォルトの名無しさん:2006/08/16(水) 01:06:17
再起動
868デフォルトの名無しさん:2006/08/16(水) 08:42:10
海に行く
869デフォルトの名無しさん:2006/08/16(水) 18:56:59
オレは泳がないから
870デフォルトの名無しさん:2006/08/18(金) 00:26:11
眺めてるだけでも心和むじゃまいか
871デフォルトの名無しさん:2006/08/18(金) 07:41:37
潜りてー
あの不要な音が聞こえない感覚が良いんじゃー
872デフォルトの名無しさん:2006/08/18(金) 14:51:42
>>866
@IT:連載:.NETマルチスレッド・プログラミング入門 第4回
www.atmarkit.co.jp/fdotnet/mthread/mthread04/mthread04_01.html - 53k - キャッシュ - 関連ページ


スレッドプールのカスタマイズ
www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=27266&forum=12&3 - 26k - キャッシュ - 関連ページ
[ 他、www.atmarkit.co.jp内のページ ]



スレッドプール 最大数 の検索結果 約 1,440 件中 1 - 50 件目 (0.59 秒)
873デフォルトの名無しさん:2006/08/18(金) 19:28:16
大阪には株式会社モータープールがあり、東京には株式会社月極がある。
874デフォルトの名無しさん:2006/08/26(土) 09:06:17
MFCでマルチスレッドのプログラムを作成していますが、引数の受け渡しのところで悩んでいます

struct ThreadParams{
  int a;
  int b;
  int c;
};

BOOL MyApplicationDlg::OnInitDialog()
{
  …
  struct ThreadParams tParams;
  tParams.a = 1; tParams.b = 2; tParams.c = 3;
  AfxBeginThread(MyThread, (LPVOID)&tParams, THREAD_PRIORITY_NORMAL);
  return TRUE;
}

UINT MyApplicationDlg::MyThread(void * param)
{
  struct ThreadParams tParams = (struct ThreadParams)(*param); ←ここで既に呼び出し元のtParamsが消えているかも?
  /* tParamsを使っていろいろ処理 */
  return 0;
}

上のようなコードを書いたのですが、OnInitDialog中のtParams変数のスコープは関数内だけなので
MyThread関数でtParamsを受け取ろうとしたときには既に消えている可能性があるのではないかと思いました。
こういう場合には呼び出し元で new してスレッドの方で delete するとかで対処するのでしょうか?
他に何かよい方法があればアドバイスをお願いします。
875デフォルトの名無しさん:2006/08/26(土) 09:33:15
MyThread()とダイアログクラスの結びつきが強いのなら、クラスメンバにしておけばいいんでない?
要は、スレッドよりも長寿命ならいいわけだから。
#ダイアログクラスよりもスレッドの方が長寿ならこの手は使えないのは当然だけど。
876874:2006/08/26(土) 10:20:36
そうですね。ぐぐって探してみましたがクラスメンバにしているサンプルがありました
とりあえずこの方法でやってみます。ありがとうございました
877デフォルトの名無しさん:2006/08/26(土) 10:26:12
>>874
あんたの心配は正しい。

領域を渡して後はスレッド側でよろしことする以外にも...

・スレッド側で (コピーしておくとして) そのパラメータを
 使わなくなるまで親を待たせる。

・領域を静的に確保する。

・スレッドが起動してからパイプとかでパラメータをもらう。

等等。個人的には new / delete を使うことが多い。
878デフォルトの名無しさん:2006/08/26(土) 19:08:33
volatileですべて解決します。

グローバル変数にvolatile属性を付けて置く。

これ最強。
879デフォルトの名無しさん:2006/08/26(土) 19:17:49
>>878
 >>877
 >・領域を静的に確保する。
880デフォルトの名無しさん:2006/08/26(土) 20:26:54
何でvolatileネタって流行ってるの?
とくに引っ張って面白いネタとも思えないけど
881デフォルトの名無しさん:2006/08/26(土) 21:25:02
sizeof(int)以下ならvolatileでいいですよね?
排他は重いからやりたくないんですが・・・

という馬鹿が一時期沸いた
882デフォルトの名無しさん:2006/08/26(土) 21:28:54
すごいな
全く意味のわからん質問だ
883デフォルトの名無しさん:2006/08/27(日) 16:59:50
マルチスレッドなんか使わなければ解決
884デフォルトの名無しさん:2006/08/27(日) 19:58:38
>>877
スレッドを越えてのnew / deleteは止めとけ。
つーか、調べると分かるが、状況によって手痛いしっぺ返しを喰らうぞ。
885デフォルトの名無しさん:2006/08/27(日) 21:05:30
アホ発見 >>884

状況を具体的に説明してみろよ
886デフォルトの名無しさん:2006/08/27(日) 21:34:42
>>884
それは874に宛てるべき内容だ。

呼ぶ側がdeleteするか、呼ばれた側がdeleteするかは統一するべきだとは思う。
呼ばれた側がdeleteする場合は、浅いコピーをして使い回す場合に対応できないからオススメできない。
887デフォルトの名無しさん:2006/08/27(日) 23:06:55
>>886
> 呼ばれた側がdeleteする場合は、浅いコピーをして使い回す場合に
> 対応できないからオススメできない。

kwsk
888デフォルトの名無しさん:2006/08/28(月) 00:21:30
シャローコピーで参照を共用してる場合
データレースが起きるよヤバイよって事じゃないの?

そんなもん別スレッドに渡すなよと思うけど
889888:2006/08/28(月) 00:23:33
なんか違うな
忘れてくれ
890デフォルトの名無しさん:2006/08/28(月) 00:41:46
しったかぶりっこ
891デフォルトの名無しさん:2006/08/28(月) 01:49:18
参照ってもスレッドに渡す前に参照カウント1アゲるだろ
892デフォルトの名無しさん:2006/08/28(月) 01:50:45
ぶるぶるぶりっこ
893デフォルトの名無しさん:2006/08/28(月) 02:58:49
一体何の話をしてるのだろう?
894デフォルトの名無しさん:2006/08/28(月) 05:08:03
ぶりっ子ロックンロール / 紅麗威甦
895デフォルトの名無しさん:2006/08/28(月) 20:39:11
環境はWindowsです。
メインスレッドで生成されたWindowから、別スレッドを起動します。
このスレッドは、ファイルを1行づつ読み、
vector<string>に50件溜まったら、Windowへ通知します。
とりあえず下のような感じで組んだのですが、
Windowsが閉じられた場合、このスレッドを破棄しないといけません。
もしスレッドを破棄したらNetFileReaderのオブジェクトって、
解放されないのですよね。
こういうプログラムって、どうやって組むのが良いでしょう?

static vector<string> text;

void NetwordThread::execute(void* pData) {
 MyWindow* win = (MyWindow*)pData;

 NetFileReader* reader = new NetFileReader("hoge.txt");
 string* line;
 while ((line = reader->readLine()) != NULL) {
  text.push_back(*line);
  if (text.size() > 50) {
   SendMessage(win->m_hWnd, WM_MY_MESSAGE, NULL, (LPARAM)&text);
   text.clear();
   Sleep(10);
 }
 SendMessage(win->m_hWnd, WM_MY_MESSAGE, NULL, (LPARAM)&text);
text.clear();

 _endthread();
}
896デフォルトの名無しさん:2006/08/28(月) 21:25:26
中断フラグを作って、メイン側で Window を閉じる時に
フラグを On にする。

スレッド側は中断フラグを一行毎にチェックしてて、
On になったら、速やかに終了する。

通常のディスクファイル相手ならこれでいいと思う。

ネットワークファイルとかで一行の読み出しにすごく時
間がかかる場合があるならその読み出し処理自体を中断
する必要があると思う。
897デフォルトの名無しさん:2006/08/28(月) 21:52:15
ていうか、「Windowが閉じられたら」とか「スレッドを破棄」とか書いてるけど
普通は、閉じるボタンが押されたら、フラグなりイベントなりでスレッドに対して終了を通知して
ワーカースレッドは自分で後始末をしてから終了する、
GUIスレッドはワーカースレッドが終了するまで待機する
っていうふうに作るのが普通だろ。
898895:2006/08/28(月) 21:54:13
どもです。
中断フラグをONするメソッド作って、中はMutexで排他処理、
スレッドのexecute()の方はSendMessage()をMutexで排他処理
しておけば、1行ごとにチェックまではしなくてよいかな?
あと、スレッドの中でSleep()呼ばないと、このスレッドに完全に制御が移ってしまい、
スレッドが終了するまでWindowが固まってしまいます。
これはそういうもんでしょうか?
マルチスレッドって、どこで処理が割り込むかわからないものだと思っていたのですが。
899895:2006/08/28(月) 21:55:29
>>897
書き込み中にレスが。
ええ、その「普通はこうだ」ってのが聞きたかったんです。
なにぶん素人なのもので・・・
900デフォルトの名無しさん:2006/08/28(月) 22:05:09
固まらなねーよ。
プライオリティとかいじってなきゃな。
901895:2006/08/28(月) 22:25:55
_beginthread()呼んでるだけで、プライオリティはいじってないですね。
ActiveX内で、やってるからかなぁ。
902デフォルトの名無しさん:2006/08/28(月) 23:06:40
>>895
>解放されないのですよね。
そもそも、なんで new で割り当ててんの?
903デフォルトの名無しさん:2006/08/29(火) 04:29:53
>>898
> あと、スレッドの中でSleep()呼ばないと、このスレッドに完全に制御が移ってしまい、
> スレッドが終了するまでWindowが固まってしまいます。

SendMessage()のせいじゃね?
904895:2006/08/29(火) 14:19:52
>>903
その通りでした。SendMessageは使わない方がよさそうですね。
スレッドがデータ格納するバッファは、Window側でタイマーで定期的に監視。
スレッドがバッファに格納するときと、Windowがバッファから取得するときは、
mutexで排他処理かましておくと良いかな。
905デフォルトの名無しさん:2006/08/29(火) 16:46:22
PostMessage()使ってみたら?
906デフォルトの名無しさん:2006/08/29(火) 20:26:56
タイマーで監視しなくても、PostMessage()で合図送ればいんじゃね?
907895:2006/08/29(火) 21:41:10
PostMessageだと、ちょっと不安があってやめたんです。
たとえば、スレッドからPostMessageを呼んだ直後に、
Windowのスレッドがアクティブになって、Windowを閉じる処理をした場合、
Windowのハンドルが無効になった後に、メッセージを飛んできて、
死亡したりしませんかね?
908デフォルトの名無しさん:2006/08/29(火) 21:42:23
誰が死亡するの?
909895:2006/08/29(火) 21:50:03
オサーンのプログラム。無効なウィンドウハンドルに投げようとして
ハングしたりしないかなと。
910デフォルトの名無しさん:2006/08/29(火) 21:51:47
       ,、‐ " ̄:::゙:丶、
    ,r::::l3゙::::::::/ハヽ:ヽ::::、:ヽ
    {::://:::::::// ヽ\ト、:::::::!
    ヾ l:::::::/ 丶   `ヾ ィ、:::|
     |;:r::|  O`  'O ゙ハ|   < ないない
      ヽハ :.:.    :.: レ
        ´\ r‐--‐、,ノ
 r、     r、/ヾ ̄下ヘ
 ヽヾ 三 |:l1、_ヽ/__ .ィヽ
  \>ヽ/ |` }    n_n| |
   ヘ lノ `'ソ     l゚ω゚| |
    /´  /      ̄|. |
    \. ィ   ___ |  |
        | ノ     l |  |
      | |      i:|  |
911デフォルトの名無しさん:2006/08/29(火) 22:29:31
>>907
> メッセージを飛んできて、
> 死亡したりしませんかね?

メッセージを割り込みみたいなもんと勘違いしてないか?
912895:2006/08/29(火) 22:58:03
いや、それはないです。
PostMessageも当然、中でいろいろやってますよね。
PostMessageで実際にキューにメッセージ入れる直前に、
Windowのスレッドに切り替わることってないんですかね?
913デフォルトの名無しさん:2006/08/29(火) 23:09:22
そろそろスレ違い
914デフォルトの名無しさん:2006/08/30(水) 00:04:27
>>909
無効なハンドル次第では、デスクトップの再描画とか起こるかも。
915デフォルトの名無しさん:2006/08/30(水) 00:26:29
>>914
909じゃないけど詳しく教えてください
916デフォルトの名無しさん:2006/09/05(火) 22:30:07
そりゃロックしたままSendMessageしたらデッドロックだろうよ
917デフォルトの名無しさん :2006/09/06(水) 21:28:12
居なくなった人のプログラムを押し付けられたんだけど、
CreateThread()した後、即CloseHandle()している。
どうして即CloseHandle()するのか、
Thread関数内のExitThread()直前に呼べばいいんじゃないのか、
そもそもCloseHandle()しなくてもExitThread()するんだから要らないんじゃないのか
と思うんですが、誰も(??)
そのままにしておけばいいんでしょうか。
918デフォルトの名無しさん:2006/09/06(水) 21:53:38
>>917
MSDN の CreateThread あたりに理由は書いてあると思ったけど、
調べてみた? 推測はほどほどにして、ちゃんと確認したほうがいいよ。
919デフォルトの名無しさん:2006/09/07(木) 01:04:39
>>917
> Thread関数内のExitThread()直前に呼べばいいんじゃないのか、

ハンドルの話じゃないけど…

マルチスレッドプログラミングにおいて、「〜の直前だから大丈夫」
なんてこと考えてたらはまるよ。
920デフォルトの名無しさん:2006/09/07(木) 13:24:51
>>917
CreateThread - ExitThread - CloseHandleするのがここでのならわし。
盲目的にこうしてればいいよ。
921デフォルトの名無しさん:2006/09/07(木) 15:03:17
ぉぃぉぃ
922デフォルトの名無しさん:2006/09/08(金) 00:47:23
いやmmapしないとダメ
923デフォルトの名無しさん:2006/09/08(金) 12:38:24
ロックしないでグローバル変数に(intなど機械語1命令で読み書き可能な
サイズという条件で)アクセスするケースを考えます。

int a;
void thread1(){
 while(1)a=0x0000ffff;
}
void thread2(){
 while(1)a=0xffff0000;
}
void thread3(){
 while(1)printf("%08x\n",a);
}

このとき、thread3で0x0000ffffか0xffff0000以外の数字が
表示される可能性はありますか?
924923:2006/09/08(金) 12:40:49
補足ですが、シングルプロセッサとマルチプロセッサ両方の
ケースでどうなのか知りたいです。環境はWindows2000以降の
x86アーキテクチャを想定しています。
925デフォルトの名無しさん:2006/09/08(金) 13:17:47
aの初期値が延々と表示される可能性すらあるな
926デフォルトの名無しさん:2006/09/08(金) 22:28:47
volatile厨臭いな
釣りか?
釣られたのか?
927デフォルトの名無しさん:2006/09/08(金) 23:08:48
>>923
メモリーバスが CPU のバストランザクションをソフトの都合に会わせて
実行する保証はどこにもないんだから

バスサイズ 8 bit のシステムで
1 on cpu0
2 on cpu1
3 on cpu2
ってシチュエーション考えれば何でもありじゃん
928デフォルトの名無しさん:2006/09/08(金) 23:34:45
あっそう
929923:2006/09/09(土) 02:25:04
>>925>>926
すみません。初期値の部分は、

volatile int a = 0xffff0000;

とさせてください。後付申し訳ないです。この辺はあまり捻らないで(^^;)

>>927
>ってシチュエーション考えれば何でもありじゃん

実際問題として、Windowsのマルチプロセッサ環境で失敗する
例を容易に確認できますでしょうか? ハード環境を簡単に
用意するわけにも行かないので、いろんな人が見ているここに
尋ねてみました。

シングルプロセッサでは失敗するケースはこれまでの経験上無い
ものと思われますが…(こちらは失敗するケースを見たことないです)
930デフォルトの名無しさん:2006/09/09(土) 04:21:21
前スレでまったく同じ議論があったよ
保証されるかどうかはアーキテクチャに強く依存する
それこそIntelとAMD、Intel内でもその世代により異なる

>シングルプロセッサ

マルチコア時代にそういう括りはやめたがいい
HTもキャッシュ絡みでerattaがあった

ひとつ聞いとこう、趣味?仕事?
931デフォルトの名無しさん:2006/09/09(土) 05:04:16
386SX以外の32bitx86は
メモリバス(システムバスでもHTバスでも)は32bit同時に読み書きするだろ。
キャッシュが反映されないとか関係ない。
全部(全bit)書き込まれるか、全部書き込まれないかどちらか。
932デフォルトの名無しさん:2006/09/09(土) 05:06:02
あ、ちゃんとアラインされている場合の話ね。
933仕様書無しさん:2006/09/09(土) 08:41:48
>931-932
マルチプロセッサ環境で、あるCPUが内部キャッシュ内に保持しているDWORD
値の一部バイトを書き換えて、ライトバックする前に、ほかのCPUがDWORDの
一部バイトを書き換えるという状態になったらどう動作すんの?
934923:2006/09/09(土) 09:07:35
>>932
Interlock系のAPIがマルチプロセッサ環境では32bitアラインを要求しますね。
関連があるのでしょうかね?

>>933
こちらへのレスではありませんが、おっしゃるケース
(一部書き換え)は考えてません。問題にしたいのは
全ビット書き換えた時読み出し時に一部しか書き変わ
っていない状況があるかどうか、なので。

ちょっと動作検証と、ロック有り無しの場合で性能的に
どれほど差が出るのかプログラムを作って試してみたいと思います。
935デフォルトの名無しさん:2006/09/09(土) 09:21:18
volatile最強!!!
936デフォルトの名無しさん:2006/09/09(土) 09:41:14
Interlockとか_MemoryBarrier使わない必要性あるの?
速度が必要ならアルゴリズムとか排他制御の範囲とか無待機アルゴリズムとか
から高速化できないの?
スレッドの優先順位とか、他のプロセスの稼動状況とかでも状況変わるから
動作検証を完全にやることは無理でしょ。
CPUやMBの仕様書をNDA結んで手に入れて調べるぐらいしないと。
937デフォルトの名無しさん:2006/09/09(土) 09:45:06
>>933
それは「起こらない」でしょ。
なぜならば、キャッシュ間のコヒーレンシを保つための仕組みを持っているのが
マルチプロセッサシステムだから。
938デフォルトの名無しさん:2006/09/09(土) 09:51:15
>>934
特定少数の chip setに限定するとかなら話は別だろうけど,
C コンパイラが LOCK prefix つけて load/store するコードを
吐き出すわけではないし, ハードウェアの作り次第だと思われ...
939デフォルトの名無しさん:2006/09/09(土) 09:53:31
>>937の仕組みが外部バス接続のために遅くなり、糞CPUと呼ばれたのがPenD。
940デフォルトの名無しさん:2006/09/09(土) 10:30:49
ついにvolatileの最強さが証明されるわけだ

>>811

おめでとう
941デフォルトの名無しさん:2006/09/09(土) 12:02:27
>>937
何が「起こらない」っと言ってるのか...。
942923:2006/09/09(土) 12:45:41
>>936>>938
ロックしないと明らかにまずい状況はもちろんロックしますが、
単純な場合はロック無しでできたらいいという場面もありそうです。

皆さん、スレッド間で共有されるグローバル変数全て、万一の場合に
備えてくまなくロック系API使ってアクセスしてますか?

「書いて」「読んで」その状況において不都合がない場合は、
API通さずに普通のCの文法で書ければ言うことはないじゃないですか。

スレッド系の解説してる本にも、単純なカウンターとかロック系の
API無しでアクセスしてます。ここで問題にしているのはそういう
ごく単純なプリミティブなアクセスの話です。

NDAや「ハードウェアの作り次第」とか、そういう話まで持ち出されるのは
個人や小さい事業所でどうこうするのは不可能ですし、現実的なアクション
とは到底言えないと思います。

要は世に出回っている大抵のWindowsマシンでおかしくならない線を
探せばいいのだと思います。パッケージには全てのマシンで動作保障
するものではありませんとか書いてるソフトもありますし、試せる
範囲でおかしくならなければ(試して失敗が一つも無ければ)、
完全な厳密性までは得られなくても、こちらのスタンスとしてはOKです。
943923:2006/09/09(土) 12:46:30

厳密性を完璧にするなら世の中のマシン全部で試さないといけない
じゃないという話にもなりますし、それはやはり現実味の無い話と
しては上に書いてあることと大差ありません。理論にも実装にも
ミスが無くてもおかしくなる環境は必ずあります。

一応持ってるマシンで検証プログラムを走らせましたがエラーする
ケースは一度も起きませんでした。

性能に関しては、ロック無しを1とした場合、Interlocked系で読み書き
すると5倍、CriticalSectionで排他すると200倍近い速度低下が起きます。
(テストプログラムは極端な例でしょう)

実際の使用状況は置いておき、5倍の負荷は精神的に嫌な感じです。
この辺気にしない人もいるでしょうが、気にしない人は他の場合でも
気にしないでしょうし、積み重なるともっさりしたソフトが出来そう
なので、検証不可能な厳密性よりもこういうほうに労力や気を払いた
いですね。

一応ソース貼っときますので、もし失敗例が実際に観測された人が居たら
教えてください。Windowsシステム上で一つでも反例があれば納得せざる
を得ません。逆にある程度のサンプルで試して一度もエラーが無ければ
それはOKというのが世の中というものでしょう。

944923:2006/09/09(土) 12:50:44
#include "stdafx.h"
#include "windows.h"
#include "winbase.h"
#include "process.h"
#include "mmsystem.h"
#pragma comment(lib, "winmm.lib")

#if 1 //ロック無し
#define set_a(n) a = n
#define get_a(v) v = a
#elif 0 //Interlocked系で読み書き
#define set_a(n) InterlockedExchange((long*)&a,n)
#define get_a(v) v = InterlockedExchangeAdd((long*)&a,0)
#else //CRITICAL_SECTION排他
#define _CS
CRITICAL_SECTION cs;
#define set_a(n) {EnterCriticalSection(&cs); a=n; LeaveCriticalSection(&cs);}
#define get_a(v) {EnterCriticalSection(&cs); v=a; LeaveCriticalSection(&cs);}
#endif
続く
945923:2006/09/09(土) 12:51:29
volatile int a = 0x00001111;
volatile int t1_ct,t2_ct;
void __cdecl thread1(void *param){
while(1){
set_a(0x00001111);
t1_ct++;
}
}
void __cdecl thread2(void *param){
while(1){
set_a(0x22220000);
t2_ct++;
}
}
続く
946923:2006/09/09(土) 12:52:50
int main(int argc, char* argv[])
{
#ifdef _CS
InitializeCriticalSection(&cs);
#endif
unsigned int id1;
HANDLE h1 = (HANDLE)_beginthread(thread1, 0, &id1);
unsigned int id2;
HANDLE h2 = (HANDLE)_beginthread(thread2, 0, &id2);
#if 0
while(1)printf("%08x\n",a);
#else
printf("実行中……\n");
int loop = 0;
int false_ct = 0;
DWORD time = timeGetTime();
while(loop++ < 100000000){
int t; get_a(t);
if(t != 0x00001111 && t != 0x22220000)
printf("不整合発見(%d):%08x\n",++false_ct,t);
if((loop & 0x7fffff) == 0)
printf("loop:%d……\n",loop);
}
続く
947923:2006/09/09(土) 12:53:28
time = timeGetTime() - time;
TerminateThread(h1,0);
TerminateThread(h2,0);
printf("ループ%d回、失敗%d回、実行時間%.3f秒\n",loop-1,false_ct,(double)time / 1000);
printf("スレッド1実行回数%d回\n",t1_ct);
printf("スレッド2実行回数%d回\n",t2_ct);
#ifdef _CS
DeleteCriticalSection(&cs);
#endif
#endif
return 0;
}

948デフォルトの名無しさん:2006/09/09(土) 12:55:06
どうせなら、レスの最後を
/* 続く
として、次のレスの頭を
>xxxから */
とでもしてくれたらコピペの(後処理の)手間が減るのだが。
949923:2006/09/09(土) 12:58:46
済みません。あと、TerminateThreadしてるのはご愛嬌ということで。
950デフォルトの名無しさん:2006/09/09(土) 13:31:06
>>943
> 一応持ってるマシンで検証プログラムを走らせましたがエラーする
> ケースは一度も起きませんでした。

じゃ、あなた的には、それでいいんじゃないでしょうか?

> 実際の使用状況は置いておき、5倍の負荷は精神的に嫌な感じです。
> この辺気にしない人もいるでしょうが、気にしない人は他の場合でも
> 気にしないでしょうし、積み重なるともっさりしたソフトが出来そう
> なので、検証不可能な厳密性よりもこういうほうに労力や気を払いた
> いですね。

「いかにして、ロックするべき部分を局所化して、ロックコンディションの
テストする回数を減らすか」
を考えるべきであって、
「ここで動くんだから大丈夫じゃないか、きっとよそでも動く!」
ってな発想はしてはならないと思いますけど。

じっさいに、4CPU程度のマシンで動いていたけど、16CPU程度の NUMA
アーキテクチャのターゲットマシンの持っていった場合、動作しなかった
って前例は何度もみてます。
951923:2006/09/09(土) 13:50:37
>>950
ソースを出してるので、失敗した出力を貼って
いただけないでしょうか? 動作させた環境も
出来たらお願いします。
952デフォルトの名無しさん:2006/09/09(土) 13:52:15
もちろん、手持ちのマシンで動けば問題ないし、
たまにクラッシュしてもビジネス上問題ないならそれでいいんじゃ?

950も言ってるが、スレッドで共有する情報の塊に対してロックをかけるべきであって、
1足すとか状態を読んでそれに対する処理を行いさらに書くことはできないと思っておいたほうがいい。

それとソースだが、何でintrinsic命令使わないの?関数呼び出しコスト余計にかかってるよ。
printfのコストが多すぎだと思うが、計測間違ってない?
あと、そこまで考えるならtimeGetTimeはつかえないでしょ。
精度の設定もしてないし、明らかに少しかじった初心者がやりそうなソースだ。
953デフォルトの名無しさん:2006/09/09(土) 14:02:55
だからホビーなんじゃないの?と
954923:2006/09/09(土) 14:05:31
>>952
>1足すとか状態を読んでそれに対する処理を行いさらに書くことはできないと思っておいたほうがいい。
もちろんです。

>printfのコストが多すぎだと思うが


全て成功するケースでは、1億回のうちprintfは11回だけです。
無視しても問題ないと思いますが。
(途中経過のprintfが無しでも、ストップウオッチ計測で
十分優位な差が得られるほど負荷が変化するのはわかりますし、
なんなら途中経過のprintfは取ってください)

計測ループの中ではロック系のAPI以外の呼び出しは上記の
途中経過表示の微々たるprintf以外無いですよ。

>timeGetTimeはつかえないでしょ。
動作が秒単位に対してtimeGetTimeは10msオーダーです。
精度としては十分じゃないのですか? もし不足だと感じたら、
パフォーマンスカウンターでも使って書きなおしてください。
955923:2006/09/09(土) 14:07:51
補足、
>十分優位な差が得られるほど負荷が変化する
ロックするしないを切り替えたときの負荷の変化です。
956923:2006/09/09(土) 14:13:30
後、今回の趣旨は、読み出し失敗があるかどうかなので、
そちらに関してお話ください。

レスを見ていると相当な環境の方もいるようですし、
ロック無しでの書き込みや読み出しがそれほど使用に
耐えないほどの不具合があるものなら、簡単に失敗の
ケースが出ると思います。

失敗した状況が貼られれば何より説得力がありますので、
よろしくお願い致します。
957923:2006/09/09(土) 14:15:05
あと、失敗しない限り発言しないでください。

失敗しなければ問題ありませんので。
958デフォルトの名無しさん:2006/09/09(土) 14:19:42
>>942
> 要は世に出回っている大抵のWindowsマシンでおかしくならない線を
> 探せばいいのだと思います。

最近の風潮か?
製品事故が多くなった理由が垣間見えるようだ...。

>>943
> 理論にも実装にもミスが無くてもおかしくなる環境は必ずあります。

技術屋として見過ごせないんだけど、「ある」と言い切れる理由は?

>>957
> あと、失敗しない限り発言しないでください。

ここは、お前の検証スレじゃない。
そういう発言したいなら、自前の掲示板でも作れ。
959デフォルトの名無しさん:2006/09/09(土) 14:23:05
intrinsicはスルーか。ソースまともに読むわけ無いだろ金ももらってないのに。
失敗する環境探したいなら、自分でマシン買ってやってろ。
960923:2006/09/09(土) 14:27:21
>>958
>製品事故が多くなった理由が垣間見えるようだ...。
どうもすみません(^^;)

>技術屋として見過ごせないんだけど、「ある」と言い切れる理由は?
話がそれたかもしれません。済みません。ユーザー環境の
不具合などです。完全な検証が出来ない以上、分る範囲で
調べることしか出来ないと思うので、完全完全を言われると
身動き取れなくなってしまうといいたかったのです。

後、>>957は悪戯じゃないですか?
961デフォルトの名無しさん:2006/09/09(土) 14:30:24
>>923
うぜえ、消えろ('A`)
962デフォルトの名無しさん:2006/09/09(土) 15:23:18
>>960
> ユーザー環境の不具合などです。

そのユーザー環境に「理論か実装」の不具合があるんでしょ。

「全ての環境で試験なんかやってられねー」と言うのは当然至極なんだけど、
理論的な裏づけもなく1万回やったから大丈夫と言うのはちょっと違う気が
する。

もちろん現実的には取りきれないバグをタイミングとかで逃げて1万回テス
トしたから多分大丈夫だよねーと言って出すケースはないわけじゃないけど、
技術屋としてはもやもやが残ってる。

そもそもこの話は「検証不可能な厳密性」じゃないよ。いくつもの論文があ
るし、このスレでも議論されてる。 (まともな意見のみを取り出すのは難しい
が)

> 後、>>957は悪戯じゃないですか?
いたずらなら、2行目は >>957 へのレスだ。
でも、いたずらかどうかにかかわらず1行目はあんたへのレスだよ。
963デフォルトの名無しさん:2006/09/09(土) 15:34:23
>>923
提示されたソース読んでないけどさ、
同じ環境で何度ループしようがあまり意味ないんじゃね?

ゲーム開発では、3日3晩デモループさせて検証することだってあるんだよ?
それくらいのレアケースだって見逃せないっていうのは
技術者の自己満足じゃなくて、正しい姿勢なんじゃないか?

少なくとも「オレのマシンで動いてるからOKでしょ」って言う人とは
一緒に仕事したくないね。
964923:2006/09/09(土) 17:02:17
うざいとか言われつつ書き込んで済みません。

>>963
>同じ環境で何度ループしようがあまり意味ないんじゃね?
集中的に問題が起きるようなサンプルになってるとは思いますが。

たとえば似たようなケースで、あのサンプルの変数を代入じゃなくて
a++ とかにすれば値が順次増加せずに書き戻されたりするケースは
すぐに出ますので、検証手法としてあながち外れてるとも思えないです。

話はそれますがゲームの検証に関しては良く存じてます。
リリース前は2週間電源入れっぱなしで落ちないかどうか
とかやりますよね。(昔の話です)

>オレのマシンで動いてるからOKでしょ
オレのマシンだけというより、動かせる限りにおいてエラーに
ならなければ、というふうに考えてます。それ以上はやりよう
が無いですし。

こちらも手持ちの環境で複数台のマシンでチェックしても
エラーになるケースは無いので、もし他の方でエラーが実際
出るなら教えてもらえるとありがたいなと思ったしだいです。

965923:2006/09/09(土) 17:20:22
>>962
>このスレでも議論されてる
結論はどうだったのでしょう? 以下、各行が別スレッドで動くとして、

a=0x00001111;
a=0x22220000;
b=a;

で、bが0x22221111になるケースがあったのでしょうか?あまり対象を
広げても大変ですし、身近なWindows環境で。

たとえば68000CPUとかでアライメントを知らない人が、奇数アドレスに
byteより大きな単位でアクセスして落ちたりすると面食らうじゃ
ないですか。

PC互換機上で0x22221111のケースって、アライメント違反ほどに顕著な
現象じゃないですよね? で、実際のアプリでも、検証プログラムでも
不具合を(少なくとも当方は)見たことが無いとなると、Windowsアプリでは
「汎用レジスタから奇数アドレスへのアクセスが(遅いけど)許可されて」
いるように0x22221111のようなことは起こりえないものとしてプログラムを書いて
もいいんじゃないかと思ったのです。Windows依存だといわれればその通りです。

PC互換機の設計図やWindowsアプリの構築方法にやったらイカン
と明示してあれば従うのにやぶさかじゃないですけどそういうソースって
このスレで議論されたという中で、もし出てきたのならお教えください。

もしくは、現象が簡単に再現するプログラムの書き方があれば反例
として文句をつける余地はありません。

>理論的な裏づけもなく
もし検証プログラムに理論的なミスがあれば指摘してください。
966デフォルトの名無しさん:2006/09/09(土) 17:29:33
>>923
>int a;
>void thread1(){
> while(1)a=0x0000ffff;
>}
>void thread2(){
> while(1)a=0xffff0000;
>}
>void thread3(){
> while(1)printf("%08x\n",a);
>}
>
>このとき、thread3で0x0000ffffか0xffff0000以外の数字が
>表示される可能性はありますか?

概出だと思いますが
CPU/ハードウェア(メモリの実装方法とか)/OSによって違うでしょう。
それ以上でもそれ以下でもありません。
967923:2006/09/09(土) 17:29:41
>>959
>intrinsicはスルーか。
済みません、仰りたいことの意味が良く分りませんでした。
このプログラムの要点は、

volatile long a = 0x00001111;
void thread1(){
 while(1)a=0x00001111;
}
void thread2(){
 while(1)a=0x22220000;
}
void main(){
_beginthread(thread1);
_beginthread(thread2);
 while(1)if(a != 0x00001111 && a != 0x22220000)エラー;
}

です。組み込み命令云々の余地があるのでしょうか?
968923:2006/09/09(土) 17:41:20
>>966
>CPU/ハードウェア(メモリの実装方法とか)/OSによって違うでしょう。
どうも。

Windowsでどうなのかが知りたいのです。
こちらとしてはWindowsアプリで問題ないという裏が取れればOKです。

このマザーボードだと駄目だ、とか言うのがあれば使えないですよね。
969デフォルトの名無しさん:2006/09/09(土) 17:50:27
>>965
> 結論はどうだったのでしょう?

自分で読もうと言う気はないのか?

> もしくは、現象が簡単に再現するプログラムの書き方があれば反例
> として文句をつける余地はありません。

そんなもんがあったら苦労はしない。

> もし検証プログラムに理論的なミスがあれば指摘してください。

検証プログラムで現象が出ないからと言ってプログラムが正しいと考える
お前の思考。
970デフォルトの名無しさん:2006/09/09(土) 18:15:35
>>923
とりあえず4CPUのマシンでも異常なしで動きましたのでご報告します。
971デフォルトの名無しさん:2006/09/09(土) 18:29:14
>>969
>検証プログラムで現象が出ないからと言ってプログラムが正しいと考える

>>923 さんはそんなこと言ってないと思いますよ。

少なくとも検証プログラムですぐに問題が出るなら使い物にならない
と考えてるだけでは?
972923:2006/09/09(土) 18:57:46
>>970
ありがとうございます。
こちらは1億回を10億回にしても問題出ませんでした。
Pen4の1CPU-HT環境と、Pen3の1CPUです。

ちなみに、類似のプログラムとしてaに加算するケースを
動作させてしっかりエラーになりました。マルチスレッド
でのコンテキスト切り替えとアクセスを検証するプログラム
として動作がある程度的を得ているからだと思います。

また、加算だとPen3ではぜんぜんエラーにならないのも面白いですね。
1CPUなのである程度予想してましたが、コンテキスト切り替えの状況
がHTと違うようです。

>>971
擁護どうもです。970の人?

↓ちなみに加算テストへの変更点ですが、
973デフォルトの名無しさん:2006/09/09(土) 18:59:32
 *     +    巛 ヽ
            〒 !   +    。     +    。     *     。
      +    。  |  |
   *     +   / /   イヤッッホォォォオオォオウ!
       ∧_∧ / /
      (´∀` / / +    。     +    。   *     。
      ,-     f
      / ュヘ    | *     +    。     +   。 +
     〈_} )   |                        
        /    ! +    。     +    +     * 
       ./  ,ヘ  |
 ガタン ||| j  / |  | |||
――――――――――――
974923:2006/09/09(土) 18:59:57
#elif 1 //インクリメントテスト
#define _INC
#define set_a(n) a++
#define get_a(v) v = a
int max = 0; //これはmain内のローカル変数でも良い
#elif 0 //Interlockedでインクリメントテスト
#define _INC
#define set_a(n) InterlockedExchangeAdd((long*)&a,1)
#define get_a(v) v = InterlockedExchangeAdd((long*)&a,0)
int max = 0;
:
:
と、以下がループ内抜粋
int t; get_a(t);
#ifndef _INC
if(t != 0x00001111 && t != 0x22220000)
printf("不整合発見(%d):%08x\n",++false_ct,t);
#else
if(max < t){
max = t;
}
if(max > t){
printf("不整合発見(%d)%d,max:%d\n",++false_ct,t,max);
}
#endif

です。HTマシンではInterlockedしないと一瞬でエラー続発です。
975デフォルトの名無しさん:2006/09/09(土) 19:25:16
面倒なので代入と加算とそれぞれのロックありなしの場合を
すべて同時にテストできるプログラムにしていただけませんか?
あと、レポートも不具合ありなしだけじゃなくて、使用CPU構成や
OSバージョンなども表示されると素敵ですね。
それから、ソースはここの数レス消費する貼り方せずに
ttp://kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/joyful.htm
あたりのうpろだを使っていただくのが
協力者以外のひとに迷惑かからなくてよろしいかと思います。
976デフォルトの名無しさん:2006/09/09(土) 19:27:00
お前用の検証スレじゃないんだけど。

もう言いたいことは言ったろ

うざいからwikiでも立ててそっちでやってくんね?
977デフォルトの名無しさん:2006/09/09(土) 19:39:54
どうしても書き込みたいならコテハンかトリップたのむ。
978デフォルトの名無しさん:2006/09/09(土) 19:49:57
>>976 みたいな馬鹿はおいといて
2chの住民に検証協力してくれというなら
>>975 くらいの準備はしても良いと思う
979デフォルトの名無しさん:2006/09/09(土) 20:15:39
結果報告なんかをここでやらないならいいよ
正直つまんないのでウンザリしてる
980デフォルトの名無しさん:2006/09/09(土) 20:27:34
>978

>975 は遠回しに断ってるんじゃないかな。
981デフォルトの名無しさん:2006/09/09(土) 22:33:50
>>943
根本的なところが馬鹿っぽいのに、
とても流暢に(内容的に脱力な)文章を書ける才能に感嘆する。
982デフォルトの名無しさん:2006/09/09(土) 22:49:03
>>975
どうせならワームとして世界中のPCにばら撒いて
宿主PC上の実行結果を自分宛てにレポートさせるように
実行させれば良いのでは?
983デフォルトの名無しさん:2006/09/09(土) 22:56:43
前々スレくらいでvolatile厨を繁殖させた者です。

この話題って、あの時のフラグ変化の検出の話題と凄く似ていると思う。
あの時は単なるフラグで、1ビットでも変化している事を検出できれば
良かったから、不必要にややこしくしそうで触れなかったんだけど。

前の時のポイントは、

1. メモリから読み込んだ値を利用(計算)した結果を書き込むのではなく、
  完全に新規な値をメモリに書き込む。
2. 更新前の古い値を他のプロセッサがキャッシュの関係で読み込んでも、
  伝搬されて更新された値を近いうちに読み込めればよい。

という前提において、

必ずしも同期を取らなくても動作に支障はないが、最適化による
レジスタへの張り付きを防止するためにvolatileは必要となる。

今回も似たようなもので、更新前のメモリの内容に依存しないので、
ワード境界に整列されたワード単位のメモリ転送命令がアトミックに
行われるかどうかを確認するだけで解決できるんじゃないの?
984983:2006/09/09(土) 22:57:37
ついでに、OS依存、アーキテクチャ依存だって言う必要もないのでは?
C言語から見たら、スレッドの存在そのものが環境依存なわけだし。

>IA-32 Intel® Architecture Software Developer's Manual,
>Volume 3A: System Programming Guide
>7.1.1 Guaranteed Atomic Operations

これを見ると、
>basic memory operations will always be carried out atomically
なわけで、少なくともワード境界に整列されたワード転送なら
アトミックに行われる事が保証されているように読めるのだが。
985デフォルトの名無しさん:2006/09/09(土) 23:17:13
次スレ立ってる?
986デフォルトの名無しさん:2006/09/10(日) 00:10:02
立てるわ
987デフォルトの名無しさん:2006/09/10(日) 00:20:09
988デフォルトの名無しさん:2006/09/10(日) 00:29:26
>>983
> という前提において、

そういう前提かどうかは明らかにされていない

>>984
> ついでに、OS依存、アーキテクチャ依存だって言う必要もないのでは?

「世に出回っている大抵のWindowsマシンでおかしくならない線」
というあいまいな線引きしかなされていない

つーかさ、
spec等から確認できることもせずに、いきなり検証コード持ち出して
「ホラ、動いてるから問題ないじゃん」
なんて言われてもさ、そのコード・やり方を信用する人っているのかね。

仮に確認できても、前提を考えれば、いかに狭い範囲でしか使えないかが
すぐに分かると思うんだが、それをしない理由はなんだろうね。

もう少しアタマ使えないかな。
989デフォルトの名無しさん:2006/09/10(日) 00:36:28
>>988
>spec等から確認できることもせずに、いきなり検証コード持ち出して
>「ホラ、動いてるから問題ないじゃん」
>なんて言われてもさ、そのコード・やり方を信用する人っているのかね。

悲しいけど現実にはかなり沢山いると思う
実際事故は多発してるでしょ?
990983:2006/09/10(日) 01:08:03
>>988

>「世に出回っている大抵のWindowsマシンでおかしくならない線」
>というあいまいな線引きしかなされていない

これが微妙な線引きだと言いたいのもわかるけど、
世の中のPC〜WSクラスでSMP/Multi Coreが可能なCPUの
大半はIA-32なアーキテクチャなんじゃないの?

>そういう前提かどうかは明らかにされていない

まず、>>923のコードではaから読み出した結果を利用して
aに再代入しているわけではないので、1.の前提は成り立つ。

で、「0x0000ffffか0xffff0000以外の数字が表示されるか」から、
aの更新が他のプロセッサに即時に伝搬される必要もないし、
どちらかの値になれば良くて、読み出し結果が0xffffffffの
ように混ざり合わなければいいだけなので、2.も成り立つ。

#とりあえず、初期値が延々表示される、、ってのは置いといて…。

少なくとも、今のところはこの考え方がまずい、
って証拠も誰も示していないんだよね。
991983:2006/09/10(日) 01:23:24
この辺のところはDCLみたいに覆されることもあるかもしれない。

で、DCLにも気になっているところがあって、

Singletonを保証するためのDCLは危険なのは解るんだけど、
100%のSingletonであることに依存しているわけではなくて、
運悪く初期化時に複数インスタンスが生成されてしまっても
許容できる状況でもDCLは使っちゃいけないのかな?

生成にそれなりに時間かかるからキャッシュ目的でSingletonに
してるけど、複数回生成されて違うオブジェクトを返そうが、
単なるキャッシュだから実害はないっていうような場合とかで。
992デフォルトの名無しさん:2006/09/10(日) 01:26:06
マルチスレッドを扱い続けて30年の漏れが断言するが、
>>923 のコードでは絶対に「0x0000ffff か 0xffff0000 以外の数字」は表示されない!












これで勘弁してもらえないか?
993デフォルトの名無しさん:2006/09/10(日) 02:50:37
CPUによる
994デフォルトの名無しさん:2006/09/10(日) 03:03:58
俺なんかマルチスレッドと暮らし始めて60年だぜ

995デフォルトの名無しさん:2006/09/10(日) 03:56:28
うめようよ
996デフォルトの名無しさん:2006/09/10(日) 09:01:19
2chを見続けて10年の俺が断言するが、
>>992の言うことに間違いはない!
997デフォルトの名無しさん:2006/09/10(日) 09:06:40
>>988
>なんて言われてもさ、そのコード・やり方を信用する人っているのかね。
顔が見えないのをいいことに、著しく礼儀を欠いた発言をする人間も信用できないが
998デフォルトの名無しさん:2006/09/10(日) 09:16:58
ヒント:2ch
999デフォルトの名無しさん:2006/09/10(日) 09:57:14
>>997
いるよ。
うちの新人はWebで調べたコードは絶対間違いないって言い張る。
そういえば、去年までいた中国人も同じ事いってたよ。
1000デフォルトの名無しさん:2006/09/10(日) 10:14:33
10011001
このスレッドは1000を超えました。
もう書けないので、新しいスレッドを立ててくださいです。。。