あるスレッドでHDDを初期化しまんた
スレッドをリセットしたので初期化したHDDが元に戻りまんた
こんなのにも万能に対応しろってことかい?
なんという参照透過性による副作用の排除
タイムマシン型スレッドを作って、スレッド消したら時間が戻る…
データベースのロールバックみたいなもんかな
PCIバスに差すやつで、リセットなり電源オフなりすると
HDDの内容元に戻るのがあったな。
ループしてしまう
なにそのデジタル版三途の川
>>848 > しないよ。それは規格(ISO/IEC 9899:1999, ISO/IEC 14882:2003)で決まってる。
どうしてそんな嘘つくかなぁ…
ISO/IEC 9899:1999は隅々まで読んだが、そんなこと書いてないぞ。
規格中はこれだから(ry
C++の規格の関係ありそうなところだけ読んでみたが、
>>837はPOD型だから
関数に入る前から初期化することが許されているな。
>>848の場合は「その宣言に初めて制御が渡った時点で行われる」と書いてある。
でもCだと確かローカルなstaticは定数でしか初期化ができなくてそれもmainの実行前だよな。
C99の6.2.4と6.7.8確認したが、定数式による初期化のみで、プログラム
実行前に初期化だな。
確かに「関数内で作った」と言われるとすごい違和感ある。
読み込み専用ロックしてる最中に
別スレッドで書き込みが発生すると、データが強制的に書き換わるのですが
どうやって防止すればいいのですか?
加齢にスルー
>>914 それは俺の国の言葉では「ロックできてない」と言う。
>>914 書き込みロックを取得せずに書き込む奴が悪い
先に読んでおいてスタックにでも置いとけ。
>どうやって防止すればいいのですか?
バグを治す
mutexでロックしてるのに書き換わるよなんで?
mutexをロックしただけなら、そのmutexを見ないやつには関係ないべ。
mutexは他のデータをロックをしない。mutexデータだけがロックされる。
mutexと他のデーターの関連は自分でプログラムする。
ロックしたのにロックされてねえ、
こりゃロックだ
そんな症状が断言できるほど長時間のロックをする設計は間違っている。
_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インクルード, [コード生成]→使用するランタイムライブラリ→マルチスレッドに指定しています。
ちなみに、(unsigned int *)&ThreadID ……の部分をNULLにしても同様のエラーが出ます。
まず、MainThreadProcがキャスト無しで渡せなければ話にならないのだけれど、
例えば__stdcallで良いのか、とか。
VC9でそのコード丸ごとコピペしたら通ったけどな…。
ほんとにエラーそれだけ?
>>930 3番目の引数をキャストなしで書くと以下のエラーがでます。
『3 番目の引数を 'unsigned long (void *)' から 'unsigned int (__stdcall *)(void *)' に変換できません。』
>>931 >>928のコードではエラーはこれ一つだけです。
>>932 そこはキャストを使うべきではない。関数の宣言が違ってないか?
よく見たらスレッド関数が
DWORD WINAPI MainThreadProc(LPVOID Param){〜略〜};
……になってました。
unsigned __stdcall MainThreadProc(void * Param){〜略〜};
に変更すると第3引数はキャストなしでもいけました。
しかし、第6引数を起因とするエラーは変わらずでます。
ちょっと落ちます。
とりあえず、別にテスト用のプロジェクト作って
最小限のコードで問題が再現されるか試してみたらどうかな。
pthreadで各スレッドローカル変数ってアクセス遅い?
pthreadをなんだと思っているのだろう……
スレッド作るやつ?
名前の通りスレッドのポインタ
>>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引数をキャストする必要がなく簡潔に書けるので―――どうなんでしょう。
CreateThreadが返すスレッド識別子と同じ物だろうし
どっちの型も(たぶん)32ビットだから、
キャストによる値の変化はないだろうという前提で……
一般的にはキャストしない記述が望ましいが、
理解して意図的にキャストするなら別に文句は言わない。
あとでThreadIDを使うときにみっともないキャストを連発するぐらいなら
最初からDWORD ThreadID;で定義したほうがマシかもね。
>>DWORD ThreadID……でいいのでしょうか?
お前の使用している開発環境のヘルプにunsignedと書いてあるんだろ?
DWORDと書く理由が思いつかないのだが。仕様をみてプログラム書け。
>>941 サンプルだけじゃなくWin32APIリファレンスやヘッダをよく読むのだ。
longとintは“区別”しとけよボクぅ?
>一般的にはキャストしない記述が望ましいが、
これはこの通りなんだが、戻り値はキャスト必須な時点でどうでもいいわなw
実質CreateThreadなんでCreateThreadと同じ変数を用意しておくのが無難ってもんだ。
てかこの程度でつまづくようなら大人しくboost他のラッパークラス使っておいた方がマシな気がしないでもない。
longとintってなにが違うの?
両方とも32ビットの整数でしょ?
64ビット環境でもあるまいし。
ここにも危険思想の持ち主がひとり…
>>947 Unix界隈だと long 64bbit, int 32bit だったりするんだな
64ビット環境でも LLP64 ならlongは32bitだけど・・・
環境によってはintは16bitだな
longって略さずにlong intって書こうぜ?
だったらsignedもつけようぜ
もちろんdouble floatもだよな?
>>955 SPARC/SolarisとかLP64(longとポインタが64bit)って呼ばれる環境がある。
旧DECのAlpha/Digital UNIXのようにILP64(int、long、ポインタが64bit)もある。
Win64のポインタが64bitでint、longが32bitってのは変態すぐる。
>>955 Linuxだと long のサイズとポインタのサイズが同じという前提でプログラムが
書かれてることが結構ある(カーネルの時点ですでにそうだし)
64bit環境で普通にコンパイルすれば long が64ビットになる
x64は64bitレジスタをいじる命令が32bitレジスタをいじる命令より1バイト長い
という食わせ物だから。intまで64bitにしたくないのはわかる。
Win16のときのlong=32bitのまま引きずってるから、longを64bitに
できなかったんだろうな。
Win32ではintでいいところでlongを多用してるし。
まぁ、16bit時代から互換性を重視しながら続いているのが原因で、
しょうがないとは思う。生まれたときから32bitのOSとは事情が違うでしょ。
どうせtypedefされた型名しか使わないから、どこかの時点でlongを
使っている部分をintに変えてもよかった気はするけどね。
long long
どっかの南の島の爺さんが語る昔話の話し出しみたいな
ろぉんぐ、ろぉんぐ、あるところに・・
API自体が使うのはLONGとかDWORDとかINT_PTRとかなんだから、
別にCのlongが64bitだろうが行けなくはないはずなんだがなー
Linux(笑)
964 :
955:2008/07/02(水) 07:26:01
>>956 32ビット環境でlongが64ビットの例が欲しかったのだが・・・。JavaとかC#みたいな。
>>957 Alphaは大昔に使ったけどintは32では?
初心者ですが、32bit Windows環境だと
単なる "unsigned宣言" は "unsigned long宣言" と同義ということですか?
言語的には unsigned は unsigned int と同義。
で long がたまたま int と同じ長さだと、そうなる。
SGIのにILP64なのがあったはず。AlphaはLP64でしょ。
同義じゃないだろ。
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
同じ働きをすると言ってるだけで、誰も同じ型だとは言ってないよ。
整数の型を省略したらsigned, intが勝手に着くとかあったなぁ
main(c, char **s){
}
最近は省略してもintと解釈しなくなったんじゃなかったっけ
974 :
969:2008/07/03(木) 07:28:22
>>970 その「同じ働き」ってのが曖昧じゃないか。typeid比較する
コードがあったら違う挙動になるのは同じ働きとはいえないだろ。
サイズが同じだけで別の型だって念を押しておかないと
>>965は
unsignedとunsigned longの入り交じったソース量産するぞ。
975 :
デフォルトの名無しさん:2008/07/03(木) 07:46:53
posixのスレッドローカルデータって
上限値って決まってるのでしょうか
データの個数?総サイズ?
サイズなら上限は当然あるだろ
数値は実装に依存するが
>>974 int a;
int b;
a と b のアドレスを比較するコードがあったら違う挙動になるんですが、
a と b は違う働きをするんですか?
>>977 スタックサイズが64kbか128kbなので
個別スレッドで4Mのデータを扱えません
>>980 なんで全てのデータをスタックに入れようとするんだよ。
>>979 違うとえば違うような。変数と型を一緒にしてない?
>>980 回避方法はあるけど、TLSを使わない方針で設計を見直すべき。
>>984 じゃあ使わないからどうやればいいのか教えてください
スレッドごとにメモリを動的確保すればよい。メモリの解放には注意して。
>>985 使わなくてもいい方法を一度考えてから質問しようぜ
>>987 mutexしたくないので使わないと無理です
まさか、グローバル変数だけで作ってるのか?
うん
>>990 NT系列のコーディング規約でそうなってるの
どうすればいいの?
グローバル変数の使用が強制されたコーディング規則だと・・・
もちろん釣りだよな。
今人気急上昇中の組み込み系かもしれない
>>992 いやまじなんですよ本当に
コーディングルールの
項4.5.1に、共有データはグローバル変数として
定義し他者が利用しやすいように記述すること
って載ってるんですよ
本当に助けてくださいまじで困ってます。
もう吊ろうかな3日も寝てなくて頭おかしくなってきたし
>>994 TLSにデータを置いたら、他のスレッドからアクセスできなくなるから共有にならないけどいいの?
>994
共有データって書いてあるじゃん。
共有データじゃないものには適用するな。
>>994 今やってるところは個別のスレッドで
データ作って処理するところなんですよ
規約でグローバル変数は共有する場合だけ
だから使うなって言われたけどどうすればいいか
わからないし
>>997 使うなっていわれたんだから使わないでOK
グローバル変数は使わないのが正道
>>997 個別のスレッドでデータ造って処理するんだから、他のスレッドと
共有なんかしなくていいんだろ。
だから、グローバルを使わなくていいんだし、素直に
>>986 でい
いだろ。
スレッドローカルデータがどうのこうのの前に、日本語理解力と
コミュニケーション能力を何とかした方がいいと思うよ。
時間切れとなりました
1001 :
1001:
このスレッドは1000を超えました。
もう書けないので、新しいスレッドを立ててくださいです。。。