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

このエントリーをはてなブックマークに追加
902デフォルトの名無しさん:2008/06/25(水) 12:51:00
あるスレッドでHDDを初期化しまんた
スレッドをリセットしたので初期化したHDDが元に戻りまんた

こんなのにも万能に対応しろってことかい?
903デフォルトの名無しさん:2008/06/25(水) 12:55:32
なんという参照透過性による副作用の排除
904デフォルトの名無しさん:2008/06/25(水) 13:05:19
タイムマシン型スレッドを作って、スレッド消したら時間が戻る…
905デフォルトの名無しさん:2008/06/25(水) 13:55:02
データベースのロールバックみたいなもんかな
906デフォルトの名無しさん:2008/06/25(水) 13:56:19
PCIバスに差すやつで、リセットなり電源オフなりすると
HDDの内容元に戻るのがあったな。
907デフォルトの名無しさん:2008/06/25(水) 14:14:33
ループしてしまう
908デフォルトの名無しさん:2008/06/25(水) 20:08:59
なにそのデジタル版三途の川
909デフォルトの名無しさん:2008/06/25(水) 20:10:30
>>848
> しないよ。それは規格(ISO/IEC 9899:1999, ISO/IEC 14882:2003)で決まってる。

どうしてそんな嘘つくかなぁ…
ISO/IEC 9899:1999は隅々まで読んだが、そんなこと書いてないぞ。
910デフォルトの名無しさん:2008/06/25(水) 20:24:19
規格中はこれだから(ry
911デフォルトの名無しさん:2008/06/25(水) 21:14:42
C++の規格の関係ありそうなところだけ読んでみたが、>>837はPOD型だから
関数に入る前から初期化することが許されているな。
>>848の場合は「その宣言に初めて制御が渡った時点で行われる」と書いてある。
912デフォルトの名無しさん:2008/06/25(水) 21:32:23
でもCだと確かローカルなstaticは定数でしか初期化ができなくてそれもmainの実行前だよな。
913デフォルトの名無しさん:2008/06/25(水) 21:56:30
C99の6.2.4と6.7.8確認したが、定数式による初期化のみで、プログラム
実行前に初期化だな。
確かに「関数内で作った」と言われるとすごい違和感ある。

914デフォルトの名無しさん:2008/06/27(金) 07:19:15
読み込み専用ロックしてる最中に
別スレッドで書き込みが発生すると、データが強制的に書き換わるのですが
どうやって防止すればいいのですか?
915デフォルトの名無しさん:2008/06/27(金) 08:27:19
加齢にスルー
916デフォルトの名無しさん:2008/06/27(金) 08:51:25
>>914
読み込んだ値をTLSにコピー
917デフォルトの名無しさん:2008/06/27(金) 09:34:19
>>914
それは俺の国の言葉では「ロックできてない」と言う。
918デフォルトの名無しさん:2008/06/27(金) 12:24:31
>>914
書き込みロックを取得せずに書き込む奴が悪い
919デフォルトの名無しさん:2008/06/27(金) 12:56:38
先に読んでおいてスタックにでも置いとけ。
920デフォルトの名無しさん:2008/06/27(金) 13:06:38
>どうやって防止すればいいのですか?
バグを治す
921デフォルトの名無しさん:2008/06/27(金) 14:11:06
>>914
他スレッドに書込み許可を与えない
922デフォルトの名無しさん:2008/06/27(金) 18:08:17
mutexでロックしてるのに書き換わるよなんで?
923デフォルトの名無しさん:2008/06/27(金) 18:12:01
mutexをロックしただけなら、そのmutexを見ないやつには関係ないべ。
924デフォルトの名無しさん:2008/06/27(金) 20:30:11
>>914
ソースも貼らずに質問とな?
925デフォルトの名無しさん:2008/06/27(金) 22:08:59
mutexは他のデータをロックをしない。mutexデータだけがロックされる。
mutexと他のデーターの関連は自分でプログラムする。
926デフォルトの名無しさん:2008/06/27(金) 22:09:46
ロックしたのにロックされてねえ、
こりゃロックだ
927デフォルトの名無しさん:2008/06/27(金) 23:21:15
そんな症状が断言できるほど長時間のロックをする設計は間違っている。
928デフォルトの名無しさん:2008/06/30(月) 04:33:10
_beginthreadex()関数の第6引数が引っかかってなぜかコンパイルが通りません。
「'unsigned long' から 'void *' に変換することはできません。」と出ます。

DWORD ThreadID;
_beginthreadex(NULL, 0, (unsigned int (__stdcall *)(void *))MainThreadProc, NULL, CREATE_SUSPENDED, (unsigned int *)&ThreadID);

……と書いてるのですが、何が問題なのでしょうか?
環境はWindows2000, Visual C++ 6.0 SP5
process.hインクルード, [コード生成]→使用するランタイムライブラリ→マルチスレッドに指定しています。
929デフォルトの名無しさん:2008/06/30(月) 04:38:29
ちなみに、(unsigned int *)&ThreadID ……の部分をNULLにしても同様のエラーが出ます。
930デフォルトの名無しさん:2008/06/30(月) 05:31:47
まず、MainThreadProcがキャスト無しで渡せなければ話にならないのだけれど、
例えば__stdcallで良いのか、とか。
931デフォルトの名無しさん:2008/06/30(月) 05:32:59
VC9でそのコード丸ごとコピペしたら通ったけどな…。
ほんとにエラーそれだけ?
932デフォルトの名無しさん:2008/06/30(月) 06:38:40
>>930
3番目の引数をキャストなしで書くと以下のエラーがでます。
『3 番目の引数を 'unsigned long (void *)' から 'unsigned int (__stdcall *)(void *)' に変換できません。』

>>931
>>928のコードではエラーはこれ一つだけです。
933デフォルトの名無しさん:2008/06/30(月) 06:44:57
>>932
そこはキャストを使うべきではない。関数の宣言が違ってないか?
934デフォルトの名無しさん:2008/06/30(月) 06:59:12
よく見たらスレッド関数が
DWORD WINAPI MainThreadProc(LPVOID Param){〜略〜};
……になってました。
unsigned __stdcall MainThreadProc(void * Param){〜略〜};
に変更すると第3引数はキャストなしでもいけました。
しかし、第6引数を起因とするエラーは変わらずでます。

ちょっと落ちます。
935デフォルトの名無しさん:2008/06/30(月) 07:13:28
とりあえず、別にテスト用のプロジェクト作って
最小限のコードで問題が再現されるか試してみたらどうかな。
936デフォルトの名無しさん:2008/06/30(月) 21:12:21
つーか、MSのサンプルは通るのかい?
http://msdn.microsoft.com/ja-jp/library/kdzttdcb(VS.80).aspx
937デフォルトの名無しさん:2008/06/30(月) 23:29:53
pthreadで各スレッドローカル変数ってアクセス遅い?
938デフォルトの名無しさん:2008/07/01(火) 00:05:10
pthreadをなんだと思っているのだろう……
939デフォルトの名無しさん:2008/07/01(火) 00:11:26
スレッド作るやつ?
940デフォルトの名無しさん:2008/07/01(火) 04:52:09
名前の通りスレッドのポインタ
941デフォルトの名無しさん:2008/07/01(火) 05:39:47
>>928ですが、解決しました。
結果からいいますと、_beginthreadex()の返り値を"(HANDLE)"でキャストすることでコンパイルがとおりました。

HANDLE hThread=NULL;
DWORD ThreadID;
hThread=(HANDLE)_beginthreadex(NULL, 0, MainThreadProc, NULL, CREATE_SUSPENDED, (unsigned int *)&ThreadID);

なんともお騒がせしました。
ちなみにスレッド識別子ですが、宣言としてはCreateThreadの場合のように
DWORD ThreadID……でいいのでしょうか?
それともmsdnのサンプルのように、
unsigned ThreadID……の方がいいのでしょうか?
前者のように明示的に宣言する方が分かりやすくていいのですが、
後者だと第6引数をキャストする必要がなく簡潔に書けるので―――どうなんでしょう。
942デフォルトの名無しさん:2008/07/01(火) 06:25:58
CreateThreadが返すスレッド識別子と同じ物だろうし
どっちの型も(たぶん)32ビットだから、
キャストによる値の変化はないだろうという前提で……
一般的にはキャストしない記述が望ましいが、
理解して意図的にキャストするなら別に文句は言わない。
あとでThreadIDを使うときにみっともないキャストを連発するぐらいなら
最初からDWORD ThreadID;で定義したほうがマシかもね。
943デフォルトの名無しさん:2008/07/01(火) 07:18:23
>>DWORD ThreadID……でいいのでしょうか?
お前の使用している開発環境のヘルプにunsignedと書いてあるんだろ?
DWORDと書く理由が思いつかないのだが。仕様をみてプログラム書け。
944デフォルトの名無しさん:2008/07/01(火) 08:14:59
>>941
サンプルだけじゃなくWin32APIリファレンスやヘッダをよく読むのだ。
945デフォルトの名無しさん:2008/07/01(火) 08:33:15
longとintは“区別”しとけよボクぅ?
946デフォルトの名無しさん:2008/07/01(火) 08:59:03
>一般的にはキャストしない記述が望ましいが、
これはこの通りなんだが、戻り値はキャスト必須な時点でどうでもいいわなw
実質CreateThreadなんでCreateThreadと同じ変数を用意しておくのが無難ってもんだ。
てかこの程度でつまづくようなら大人しくboost他のラッパークラス使っておいた方がマシな気がしないでもない。
947デフォルトの名無しさん:2008/07/01(火) 09:00:11
longとintってなにが違うの?
両方とも32ビットの整数でしょ?
64ビット環境でもあるまいし。
948デフォルトの名無しさん:2008/07/01(火) 09:37:25
ここにも危険思想の持ち主がひとり…
949デフォルトの名無しさん:2008/07/01(火) 09:50:18
>>947 Unix界隈だと long 64bbit, int 32bit だったりするんだな
950デフォルトの名無しさん:2008/07/01(火) 09:51:42
64ビット環境でも LLP64 ならlongは32bitだけど・・・
951デフォルトの名無しさん:2008/07/01(火) 09:57:19
環境によってはintは16bitだな
952デフォルトの名無しさん:2008/07/01(火) 11:03:56
longって略さずにlong intって書こうぜ?
953デフォルトの名無しさん:2008/07/01(火) 21:14:51
だったらsignedもつけようぜ
954デフォルトの名無しさん:2008/07/01(火) 21:37:24
もちろんdouble floatもだよな?
955デフォルトの名無しさん:2008/07/01(火) 22:17:15
>>949
んな環境みたことねーぞ。例をあげてくれ。

>>954
イミフ
956デフォルトの名無しさん:2008/07/01(火) 23:14:48
>>955
Unix界隈
957デフォルトの名無しさん:2008/07/02(水) 00:04:43
>>955
SPARC/SolarisとかLP64(longとポインタが64bit)って呼ばれる環境がある。
旧DECのAlpha/Digital UNIXのようにILP64(int、long、ポインタが64bit)もある。
Win64のポインタが64bitでint、longが32bitってのは変態すぐる。
958デフォルトの名無しさん:2008/07/02(水) 00:10:34
>>955
Linuxだと long のサイズとポインタのサイズが同じという前提でプログラムが
書かれてることが結構ある(カーネルの時点ですでにそうだし)
64bit環境で普通にコンパイルすれば long が64ビットになる
959デフォルトの名無しさん:2008/07/02(水) 00:43:43
x64は64bitレジスタをいじる命令が32bitレジスタをいじる命令より1バイト長い
という食わせ物だから。intまで64bitにしたくないのはわかる。
960デフォルトの名無しさん:2008/07/02(水) 01:41:41
Win16のときのlong=32bitのまま引きずってるから、longを64bitに
できなかったんだろうな。
Win32ではintでいいところでlongを多用してるし。

まぁ、16bit時代から互換性を重視しながら続いているのが原因で、
しょうがないとは思う。生まれたときから32bitのOSとは事情が違うでしょ。

どうせtypedefされた型名しか使わないから、どこかの時点でlongを
使っている部分をintに変えてもよかった気はするけどね。
961デフォルトの名無しさん:2008/07/02(水) 01:50:54
long long
どっかの南の島の爺さんが語る昔話の話し出しみたいな
ろぉんぐ、ろぉんぐ、あるところに・・
962デフォルトの名無しさん:2008/07/02(水) 02:07:32
API自体が使うのはLONGとかDWORDとかINT_PTRとかなんだから、
別にCのlongが64bitだろうが行けなくはないはずなんだがなー
963デフォルトの名無しさん:2008/07/02(水) 05:03:19
Linux(笑)
964955:2008/07/02(水) 07:26:01
>>956
32ビット環境でlongが64ビットの例が欲しかったのだが・・・。JavaとかC#みたいな。
>>957
Alphaは大昔に使ったけどintは32では?
965デフォルトの名無しさん:2008/07/02(水) 09:56:17
初心者ですが、32bit Windows環境だと
単なる "unsigned宣言" は "unsigned long宣言" と同義ということですか?
966デフォルトの名無しさん:2008/07/02(水) 10:06:25
言語的には unsigned は unsigned int と同義。

で long がたまたま int と同じ長さだと、そうなる。
967デフォルトの名無しさん:2008/07/02(水) 13:06:30
SGIのにILP64なのがあったはず。AlphaはLP64でしょ。
968デフォルトの名無しさん:2008/07/02(水) 14:00:58
>>962
API自体のインターフェースが変わっている罠。
DWORDを受けていたのにULONG_PTRに変わったこれとか。
http://msdn.microsoft.com/ja-jp/library/cc429342.aspx
969デフォルトの名無しさん:2008/07/02(水) 20:49:14
同義じゃないだろ。
unsigned i1;
unsigned long i2;
std::printf("%s\n", typeid(i1).name());
std::printf("%s\n", typeid(i2).name());
i1とi2は「サイズが同じ」だけで同義じゃない。

あと『単なる "unsigned宣言"』という前提から少し外れるが、ポインタの互換性はない。
typedef unsigned long t1;
typedef unsigned t2;
t2 *p = (t1 *)0; // compile error
970デフォルトの名無しさん:2008/07/02(水) 22:39:04
同じ働きをすると言ってるだけで、誰も同じ型だとは言ってないよ。
971デフォルトの名無しさん:2008/07/02(水) 23:27:20
整数の型を省略したらsigned, intが勝手に着くとかあったなぁ
972デフォルトの名無しさん:2008/07/02(水) 23:28:02
main(c, char **s){
}
973デフォルトの名無しさん:2008/07/02(水) 23:35:36
最近は省略してもintと解釈しなくなったんじゃなかったっけ
974969:2008/07/03(木) 07:28:22
>>970
その「同じ働き」ってのが曖昧じゃないか。typeid比較する
コードがあったら違う挙動になるのは同じ働きとはいえないだろ。
サイズが同じだけで別の型だって念を押しておかないと>>965
unsignedとunsigned longの入り交じったソース量産するぞ。
975デフォルトの名無しさん:2008/07/03(木) 07:46:53
976デフォルトの名無しさん:2008/07/04(金) 07:35:27
posixのスレッドローカルデータって
上限値って決まってるのでしょうか
977デフォルトの名無しさん:2008/07/04(金) 08:44:28
データの個数?総サイズ?
978デフォルトの名無しさん:2008/07/04(金) 11:28:41
サイズなら上限は当然あるだろ
数値は実装に依存するが
979デフォルトの名無しさん:2008/07/04(金) 23:44:41
>>974
int a;
int b;

a と b のアドレスを比較するコードがあったら違う挙動になるんですが、
a と b は違う働きをするんですか?
980デフォルトの名無しさん:2008/07/04(金) 23:46:48
>>977
スタックサイズが64kbか128kbなので
個別スレッドで4Mのデータを扱えません
981デフォルトの名無しさん:2008/07/05(土) 01:02:35
>>980
なんで全てのデータをスタックに入れようとするんだよ。
982デフォルトの名無しさん:2008/07/05(土) 01:04:57
>>981
入れたいの
983デフォルトの名無しさん:2008/07/05(土) 06:46:06
>>979
違うとえば違うような。変数と型を一緒にしてない?
984デフォルトの名無しさん:2008/07/05(土) 07:06:39
>>980
回避方法はあるけど、TLSを使わない方針で設計を見直すべき。
985デフォルトの名無しさん:2008/07/05(土) 07:14:18
>>984
じゃあ使わないからどうやればいいのか教えてください
986デフォルトの名無しさん:2008/07/05(土) 09:13:34
スレッドごとにメモリを動的確保すればよい。メモリの解放には注意して。
987デフォルトの名無しさん:2008/07/05(土) 09:53:45
>>985
使わなくてもいい方法を一度考えてから質問しようぜ
988デフォルトの名無しさん:2008/07/05(土) 10:06:30
>>987
mutexしたくないので使わないと無理です
989デフォルトの名無しさん:2008/07/05(土) 10:30:30
まさか、グローバル変数だけで作ってるのか?
990デフォルトの名無しさん:2008/07/05(土) 10:43:59
うん
991デフォルトの名無しさん:2008/07/05(土) 10:44:54
>>990
NT系列のコーディング規約でそうなってるの
どうすればいいの?
992デフォルトの名無しさん:2008/07/05(土) 11:44:32
グローバル変数の使用が強制されたコーディング規則だと・・・

もちろん釣りだよな。
993デフォルトの名無しさん:2008/07/05(土) 11:46:05
今人気急上昇中の組み込み系かもしれない
994デフォルトの名無しさん:2008/07/05(土) 11:54:24
>>992
いやまじなんですよ本当に
コーディングルールの
項4.5.1に、共有データはグローバル変数として
定義し他者が利用しやすいように記述すること
って載ってるんですよ

本当に助けてくださいまじで困ってます。
もう吊ろうかな3日も寝てなくて頭おかしくなってきたし
995デフォルトの名無しさん:2008/07/05(土) 12:11:23
>>994
TLSにデータを置いたら、他のスレッドからアクセスできなくなるから共有にならないけどいいの?
996デフォルトの名無しさん:2008/07/05(土) 12:14:24
>994
共有データって書いてあるじゃん。
共有データじゃないものには適用するな。
997デフォルトの名無しさん:2008/07/05(土) 12:23:00
>>994
今やってるところは個別のスレッドで
データ作って処理するところなんですよ
規約でグローバル変数は共有する場合だけ
だから使うなって言われたけどどうすればいいか
わからないし

998デフォルトの名無しさん:2008/07/05(土) 12:30:35
>>997
使うなっていわれたんだから使わないでOK
グローバル変数は使わないのが正道
999デフォルトの名無しさん:2008/07/05(土) 12:37:26
>>997
個別のスレッドでデータ造って処理するんだから、他のスレッドと
共有なんかしなくていいんだろ。

だから、グローバルを使わなくていいんだし、素直に >>986 でい
いだろ。

スレッドローカルデータがどうのこうのの前に、日本語理解力と
コミュニケーション能力を何とかした方がいいと思うよ。
1000デフォルトの名無しさん:2008/07/05(土) 12:40:07
時間切れとなりました
10011001
このスレッドは1000を超えました。
もう書けないので、新しいスレッドを立ててくださいです。。。