2012-03-30 174 views
3

我正在處理服務器端項目,該項目應該接受超過100個客戶端連接。pthread_mutex_lock __pthread_mutex_lock_full:強健的斷言失敗0x4000000

它是使用boost :: thread的多線程程序。我正在使用boost::lock_guard<boost::mutex>來鎖定共享成員數據。還有一個BlockingQueue<ConnectionPtr>包含輸入連接。所述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; 
}; 

對於每個Connection,有一個ConcurrentQueue<StreamPtr>,其中包含了輸入流。該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; 
}; 

在調試程序時,它的好。但是,在與50所或100個以上的客戶端連接的負載測試,有時它

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

中止我不知道發生了什麼,每次都不能再現。

我GOOGLE了很多,但沒有運氣。請指教。

謝謝。

彼得

+1

中止時的堆棧跟蹤是什麼? – 2012-04-02 18:12:35

+0

嗨大衛,謝謝你的意見。我試圖使用GDB來獲取堆棧跟蹤,但另一個問題[http://stackoverflow.com/questions/9948113/boostweak-ptrt-lock-crashes-with-a-sigsegv-segmentation-fault]發生。所以我需要先解決這個問題。我現在遇到的困難是,所有這些問題都來自50或100或更多連接的負載測試,並且不能每次都重現。我有一次會發布更多信息。 – 2012-04-02 18:59:32

回答

5

0x40000000FUTEX_OWNER_DIED - 這已在futex.h頭以下文檔:

/* 
* 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 

因此斷言似乎是一個跡象,多數民衆贊成持有鎖的線程正在退出由於某種原因 - 有一種方法可以在線程對象持有鎖的時候被銷燬嗎?

另一件要檢查的是,如果你有某種地方的內存損壞。 Valgrind可能是一個可以幫助你的工具。