2009年11月20日 21時18分 |
マルチスレッドのプログラムがsocket(),recv()まわりで突然abortしていたが、glibcをupdateしたら直った |
メールアドレスクリーニング機能付きのスマートメール配信ソフト (コードネーム:プリーズミスター)を開発している。 開発も終盤に差し掛かったところで大きなバグに出くわしてこの2 週間死闘を繰り広げていた。 現象は ?2時間程度するとアプリケーションが落ちる。 ?2時間程度するとDBなどへの外部接続ができなくなる。 |
![]() |
[続きを読む] |
![]() |
[カテゴリ:C++] [コメント (0)] [トラックバック (0)] |
2009年7月24日 9時51分 |
スレッドIDとポインタは似た感じなので、pthread_exitで変なことしてても気づかない。 |
スレッド分岐する際にpthread_create()を使う。 ---------------------------------------------------- pthread_t thread pthread_create( &thread, NULL, func, (void*) NULL ) ---------------------------------------------------- スレッドIDはthreadに格納されるが、その値をprintfで整数として出力してみると「-129344850」とかの大きな整数だった。 プログラムはとまることなく動作しているのだが、ループで生成・終了を繰り返すはずのスレッドが2回目以降走らない。。。 よくよく確認してみると、スレッド終了の際にpthread_exit()にスレッドIDではなく、スレッドID格納のポインタを渡していた! -------------------------------------------------- pthread_exit( &thread ); //本当はpthread_exit( thread ) -------------------------------------------------- threadは値(スレッドID)も、ポインタも負の大きな整数なので、print文ではぱっとみわからなかった。(複数できる子スレッドのpthread_exitで全部同じ引数でexitしようとしているのでわかった。) なんでコンパイルできるんだろう。 なんでセグメンテーションフォルトにならないんだろう。 ん〜やっかい。 |
![]() |
[コメント (0)] [トラックバック (0)] |
2009年7月23日 9時55分 |
シングルトンをマルチスレッドから使う際の注意 |
DB接続するオブジェクトはシングルトンとして扱うことがよくあるが、このDBオブジェクトが検索結果も保持するような構造になっている場合、マルチスレッドから使うとうまくいかないことがある。 それまでの処理では問題なく動作していたのに、マルチスレッド化した後からセグメンテーションフォールトを発生する という事態に陥っていないだろうか。 私の場合、DBへのコネクションを保持するクラスをシングルトンにしていたが、そのクラスでDB検索後の結果も保持する構造になっていた。そのDBシングルトンオブジェクトをスレッド分岐後すぐのところで呼び出していたので、初めのスレッドが検索し、結果にアクセスするまでに次のスレッドが再入し、結果をクリア・メモリ開放してしまっていたようだ。 参照するだけのクラスならシングルトンでマルチスレッドから呼び出してもこういうことは起こらないだろう。 結局、シングルスレッド部分では、シングルトンを呼び出すようにし、マルチスレッド部分では個別にインスタンスを作成できるようにした。DBクラスは半シングルトンというとても半端な形になった。これが原因で別の問題がおこらなければよいが。。。 |
![]() |
[カテゴリ:C++] [コメント (0)] [トラックバック (0)] |
2009年7月17日 10時6分 |
C++ シングルトンのgetInstance()の間違いでセグメンテーションんフォルト |
あるクラス、A(シングルトン)のインスタンスのメンバにアクセスするタイミングでセグメンテーションフォールトになっていた。そのメンバがたまたま自作のクラスを要素にしたlistだったので宣言が悪いのかと見直していたがまずそうなところはない。いろいろ見てみたところ、AクラスのgetInstance()が下記のようになっていた。 A* A::getInstance() { if( a ) // ←本当は if( !a ) { a = new A(); } return a; } 冒頭のifの ! がぬけていてもコンパイルは通る。しかしインスタンスが作成されないため、staticな挙動のみできる。スタティックでないメンバーにアクセスした時点でセグメンテーションフォルトになる。以外に気づかなかった。。。。 セグメンテーションフォルトの際にもうちょいヒントがでるといいんだが。 |
![]() |
[カテゴリ:C++] [コメント (0)] [トラックバック (0)] |