【问题标题】:pthread_mutex_lock __pthread_mutex_lock_full: Assertion failed with robust and 0x4000000pthread_mutex_lock __pthread_mutex_lock_full:断言失败,鲁棒性和 0x4000000
【发布时间】:2012-03-30 00:52:54
【问题描述】:

我正在做一个服务器端项目,它应该接受超过 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&lt;StreamPtr&gt;,其中包含输入流。 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.

我不知道发生了什么,而且每次都无法重现。

我搜索了很多,但没有运气。请指教。

谢谢。

彼得

【问题讨论】:

  • 中止时的堆栈跟踪是什么?
  • 嗨,大卫,感谢您的 cmets。我试图使用 GDB 来获取堆栈跟踪,但发生了另一个问题 [stackoverflow.com/questions/9948113/…。所以我需要先解决这个问题。我现在遇到的困难是所有这些问题都来自 50 或 100 或更多连接的负载测试,并且无法每次都重现。一旦有,我会发布更多信息。

标签: c++ pthreads mutex assert


【解决方案1】:

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

【讨论】:

    猜你喜欢
    • 2022-06-12
    • 1970-01-01
    • 2011-05-27
    • 2017-06-15
    • 2023-03-22
    • 1970-01-01
    • 2021-03-16
    • 2010-09-26
    相关资源
    最近更新 更多