2012-03-30 6 views
3

Ich arbeite an einem serverseitigen Projekt, das mehr als 100 Client-Verbindungen akzeptieren soll.pthread_mutex_lock __pthread_mutex_lock_full: Assertion fehlgeschlagen mit robust und 0x4000000

Es ist Multithread-Programm mit boost :: thread. An einigen Stellen verwende ich boost::lock_guard<boost::mutex>, um die freigegebenen Mitgliedsdaten zu sperren. Es gibt auch eine BlockingQueue<ConnectionPtr>, die die Eingangsverbindungen enthält. Die Umsetzung der BlockingQueue:

template <typename DataType> 
class BlockingQueue : private boost::noncopyable 
{ 
public: 
    BlockingQueue() 
     : nblocked(0), stopped(false) 
    { 

    } 

    ~BlockingQueue() 
    { 
     Stop(true); 
    } 

    void Push(const DataType& item) 
    { 
     boost::mutex::scoped_lock lock(mutex); 
     queue.push(item); 
     lock.unlock(); 
     cond.notify_one(); // cond.notify_all(); 
    } 

    bool Empty() const 
    { 
     boost::mutex::scoped_lock lock(mutex); 
     return queue.empty(); 
    } 

    std::size_t Count() const 
    { 
     boost::mutex::scoped_lock lock(mutex); 
     return queue.size(); 
    } 

    bool TryPop(DataType& poppedItem) 
    { 
     boost::mutex::scoped_lock lock(mutex); 
     if (queue.empty()) 
      return false; 

     poppedItem = queue.front(); 
     queue.pop(); 

     return true; 
    } 

    DataType WaitPop() 
    { 
     boost::mutex::scoped_lock lock(mutex); 

     ++nblocked; 
     while (!stopped && queue.empty()) // Or: if (queue.empty()) 
      cond.wait(lock); 
     --nblocked; 

     if (stopped) 
     { 
      cond.notify_all(); // Tell Stop() that this thread has left 
      BOOST_THROW_EXCEPTION(BlockingQueueTerminatedException()); 
     } 

     DataType tmp(queue.front()); 
     queue.pop(); 

     return tmp; 
    } 

    void Stop(bool wait) 
    { 
     boost::mutex::scoped_lock lock(mutex); 
     stopped = true; 
     cond.notify_all(); 

     if (wait) // Wait till all blocked threads on the waiting queue to leave BlockingQueue::WaitPop() 
     { 
      while (nblocked) 
       cond.wait(lock); 
     } 
    } 

private: 
    std::queue<DataType>   queue; 
    mutable boost::mutex   mutex; 
    boost::condition_variable_any cond; 
    unsigned int     nblocked; 
    bool       stopped; 
}; 

Für jede Connection, gibt es eine ConcurrentQueue<StreamPtr>, die die Eingangsströme enthält. Die Umsetzung des ConcurrentQueue:

template <typename DataType> 
class ConcurrentQueue : private boost::noncopyable 
{ 
public: 
    void Push(const DataType& item) 
    { 
     boost::mutex::scoped_lock lock(mutex); 
     queue.push(item); 
    } 

    bool Empty() const 
    { 
     boost::mutex::scoped_lock lock(mutex); 
     return queue.empty(); 
    } 

    bool TryPop(DataType& poppedItem) 
    { 
     boost::mutex::scoped_lock lock(mutex); 
     if (queue.empty()) 
      return false; 

     poppedItem = queue.front(); 
     queue.pop(); 

     return true; 
    } 
private: 
    std::queue<DataType> queue; 
    mutable boost::mutex mutex; 
}; 

Wenn das Programm debuggen, es ist okay. Aber in einem Lasttest mit 50 oder 100 oder mehr Client-Verbindungen, manchmal abgebrochen es mit

pthread_mutex_lock.c:321: __pthread_mutex_lock_full: Assertion `robust || (oldval & 0x40000000) == 0' failed. 

Ich habe keine Ahnung, was passiert ist, und es kann nicht jedes Mal reproduziert werden.

Ich googelte viel, aber kein Glück. Bitte beraten.

Danke.

Peter

+1

Was ist der Stack-Trace beim Abbruch? –

+0

Hallo David, danke für deine Kommentare. Ich habe versucht, GDB zu verwenden, um den Stack-Trace zu erhalten, aber ein anderes Problem [http://stackoverflow.com/questions/9948113/boostweak-prt-lock-crashes-with-a-sigsegv-segmention-fault] passiert. Also muss ich das zuerst beheben. Die Schwierigkeit, die ich jetzt habe, ist, dass all diese Probleme von den Belastungstests mit 50 oder 100 oder mehr Verbindungen herrühren und nicht jedes Mal reproduziert werden können. Ich werde mehr Infos posten, sobald ich es habe. –

Antwort

5

0x40000000 ist FUTEX_OWNER_DIED -, welches die folgenden Dokumente in der futex.h Header hat:

/* 
* The kernel signals via this bit that a thread holding a futex 
* has exited without unlocking the futex. The kernel also does 
* a FUTEX_WAKE on such futexes, after setting the bit, to wake 
* up any possible waiters: 
*/ 
#define FUTEX_OWNER_DIED  0x40000000 

So ist die Behauptung, ein Hinweis darauf zu sein scheint, dass ein Thread, der die Sperre hält aus irgendeinem Grund verlässt - Gibt es eine Möglichkeit, dass ein Fadenobjekt zerstört wird, während es ein Schloss hält?

Eine andere Sache zu überprüfen ist, wenn Sie irgendwo eine Art von Speicherbeschädigung haben. Valgrind könnte ein Werkzeug sein, das dir dabei helfen kann.

Verwandte Themen