簡體   English   中英

pthread_mutex_lock __pthread_mutex_lock_full: 斷言失敗,帶有 robust 和 0x4000000

[英]pthread_mutex_lock __pthread_mutex_lock_full: Assertion failed with robust and 0x4000000

我正在做一個服務器端項目,它應該接受超過 100 個客戶端連接。

它是使用 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.

我不知道發生了什么,也不能每次都重現。

我用谷歌搜索了很多,但沒有運氣。 請指教。

謝謝。

彼得

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可能是一個可以幫助你的工具。

我遇到了類似的問題並找到了這篇文章。 它可能對你們中的一些人有用:在我的例子中,我只是缺少 init.

pthread_mutex_init(&_mutexChangeMapEvent, NULL);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM