1

(編集) 環境:

plee@sos-build:/usr/local/include/boost$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 11.10
Release:        11.10
Codename:       oneiric

plee@sos-build:/usr/local/include/boost$ uname -a
Linux sos-build 3.0.0-12-generic #20-Ubuntu SMP Fri Oct 7 14:56:25 UTC 2011 x86_64 x86_64 x86_64 GNU/Linux
plee@sos-build:/usr/local/include/boost$

plee@sos-build:/usr/local/include/boost$ cat version.hpp
//  BOOST_LIB_VERSION must be defined to be the same as BOOST_VERSION
#define BOOST_LIB_VERSION "1_47"

私はサーバー側のプロジェクトに取り組んでいます。boost::asio、 、boost::shared_ptr、などのブースト ライブラリを使用しboost::weak_ptrます。

Boost のドキュメント ( http://www.boost.org/doc/libs/1_47_0/libs/smart_ptr/weak_ptr.htm#lock ) には、weak_ptr<T>.lock決してスローしないと書かれています。

ロック

shared_ptr lock() const; 戻り値: 期限切れ()? shared_ptr(): shared_ptr(*this).

スロー: なし。

ただし、私のアプリケーションでは、クラッシュさえしました。

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7fffeffff700 (LWP 5102)]
0x000000000066fe08 in boost::detail::atomic_conditional_increment (pw=0x800000000007)
    at /usr/local/include/boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp:92
92      );
(gdb) 
(gdb) bt
#0  0x000000000066fe08 in boost::detail::atomic_conditional_increment (pw=0x800000000007)
    at /usr/local/include/boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp:92
#1  0x000000000066fe5c in boost::detail::sp_counted_base::add_ref_lock (this=0x7fffffffffff)
    at /usr/local/include/boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp:138
#2  0x000000000068009b in boost::detail::shared_count::shared_count (this=0x7fffefffe658, r=...)
    at /usr/local/include/boost/smart_ptr/detail/shared_count.hpp:518
#3  0x0000000000691599 in boost::shared_ptr<RtmpConnection>::shared_ptr<RtmpConnection> (
    this=0x7fffefffe650, r=...) at /usr/local/include/boost/smart_ptr/shared_ptr.hpp:216
#4  0x000000000068db48 in boost::weak_ptr<RtmpConnection>::lock (this=0x7fffe0e87e68)
    at /usr/local/include/boost/smart_ptr/weak_ptr.hpp:157

回線がクラッシュしたことを確認しました/usr/local/include/boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp

 69 inline int atomic_conditional_increment( int * pw )
 70 {
 71     // int rv = *pw;
 72     // if( rv != 0 ) ++*pw;
 73     // return rv;
 74
 75     int rv, tmp;
 76
 77     __asm__
 78     (
 79         "movl %0, %%eax\n\t"
 80         "0:\n\t"
 81         "test %%eax, %%eax\n\t"
 82         "je 1f\n\t"
 83         "movl %%eax, %2\n\t"
 84         "incl %2\n\t"
 85         "lock\n\t"
 86         "cmpxchgl %2, %0\n\t"
 87         "jne 0b\n\t"
 88         "1:":
 89         "=m"( *pw ), "=&a"( rv ), "=&r"( tmp ): // outputs (%0, %1, %2)
 90         "m"( *pw ): // input (%3)
 91         "cc" // clobbers
 92     );
 93
 94     return rv;
 95 }

92行目はアセンブリコードです。私は本当にそれが何を意味するのか分かりません。

boost::weakptr<RtmpConnection>.lock()使用する前に、返された(type ofboost::shared_ptr<RtmpConnection>が空であるかどうかを常に確認します。

だから私はグーグルで、これを見ましたhttp://wiki.inkscape.org/wiki/index.php/Boost_shared_pointers

スレッド セーフの理由から、ウィーク ポインターを逆参照することはできません。ウィーク ポインターの有効期限を確認した後、それを使用する前に他のスレッドがオブジェクトを破棄した場合、クラッシュが発生します。

  1. それで、私はそれに対処するために何をすべきですか、なぜクラッシュするのですか(クラッシュすることはないようboost::weakptr<RtmpConnection>.lock()です)?
  2. 私のプログラムはマルチスレッドなので。の戻り値を取得して確認した後boost::weakptr<RtmpConnection>.lock()RtmpConnection他のスレッドによって破棄される可能性がありますが、Boost ライブラリは、戻り値の型が であるため、破棄されないことを保証しboost::shared_ptr<RtmpConnection>ますか?
4

1 に答える 1

1

最も可能性が高いのは、スマート ポインターの適切な使用に関する規則の 1 つに違反しているということです。最も一般的なスマート ポインター ルール違反は次のとおりです。

  1. オブジェクトは、スマート ポインターの単一チェーンを介してのみ参照する必要があります。理想的には、オブジェクトを使用してスマート ポインターを作成しmake_shared、未加工のポインターを使用しないようにします。それ以外の場合は、通常のポインターからスマート ポインターを 1 回だけ作成します。

  2. オブジェクトのストロング ポインターからのみウィーク ポインターを作成します。(またはshared_from_this、オブジェクトがサポートしている場合は使用できます。)

  3. deleteスマート ポインターがオブジェクトを参照しているときに、呼び出しによってオブジェクトを破棄してはなりません。delete理想的には、何らかの種類のスマート ポインターが参照したことがあるオブジェクトを呼び出すことは決してありません。

このような問題には、他に 2 つの典型的な原因があります。1 つは、配列境界の上書き、二重解放、解放後のアクセスなどのメモリ破損を引き起こすバグがあることです。のようなツールを使用して、メモリ破損のバグをチェックできますvalgrind

最後に、コードを正しくコンパイルしていないか、Boost を正しくコンパイルしていない可能性があります。たとえば、プラットフォームには、スレッドセーフ コードをコンパイルするために有効にする必要があるコンパイラ オプションがある場合があります。(あなたはあなたのプラットフォームについて言及していないので、詳細をお伝えすることはできません.)

于 2012-03-30T18:24:12.537 に答える