c++ - Boost 作用域锁定断言失败

标签 c++ multithreading boost

我在一个 linux 应用程序中使用 Boost 1.41,该应用程序在一个线程上接收数据并将其放入队列中,另一个线程将其从队列中弹出并进行处理。为了使其线程安全,我使用了作用域锁。

我的问题是,很少有锁定功能在读取功能中失败并显示以下消息:

void boost::mutex::lock() 断言 '!pthread_mutext_lock(&m)' 失败

这种情况非常罕见,在上次运行时,它花了 36 小时(约 4.25 亿个事务)才失败。下面列出读写函数,Assert总是在read函数中产生

写入队列

 void PacketForwarder::Enqueue(const byte_string& newPacket, long sequenceId)
 {
    try
    {
        boost::mutex::scoped_lock theScopedLock(pktQueueLock);
        queueItem itm(newPacket,sequenceId);
        packetQueue.push(itm);

        if (IsConnecting() && packetQueue.size() > MaximumQueueSize)
        {
            // Reached maximum queue size while client unavailable; popping.
            packetQueue.pop();
        }
    }
    catch(...)
    {
        std::cout << name << " Exception was caught:" << std::endl;
    }
 }

从队列中读取

while ( shouldRun )
{
    try
    {
        if (clientSetsHaveChanged)
        {
            tryConnect();
        }

        size_t size = packetQueue.size();
        if (size > 0)
        {
            byte_string packet;
            boost::mutex::scoped_lock theQLock(pktQueueLock);
            queueItem itm = packetQueue.front();
            packet = itm.data;
            packetQueue.pop();

            BytesSent += packet.size();

            trySend(packet);   
        }
        else
        {
            boost::this_thread::sleep(boost::posix_time::milliseconds(50));
        }
    }
    catch (...)
    {
        cout << name << " Other exception in send packet" << endl;
    }

我用谷歌搜索并在销毁 scoped_locks 时发现了一些问题,但没有关于未能获得锁的问题。我还通过 boost 发行说明和 Trac 日志进行了搜索,以查看其他人是否已将其确定为问题。我认为我的代码已经很简单了,但显然有问题。有什么想法吗? TIA 保罗

最佳答案

您的程序中有一个线程安全问题,在这段代码中:

    size_t size = packetQueue.size();
    if (size > 0)
    {
        byte_string packet;
        boost::mutex::scoped_lock theQLock(pktQueueLock);
        queueItem itm = packetQueue.front();
        packet = itm.data;
        packetQueue.pop();
        // ...
    }

这里的问题是,在您检查队列大小和获得锁之间,其他一些读取线程可能会从队列中取出最后一项,这将导致 front()pop() 失败。除非您只有一个读者线程,否则您也需要锁定大小检查。

不过我不知道这是否是断言失败的原因。该断言意味着对 pthread_mutex_lock 的调用返回了一个非零值,表示错误。不幸的是,Boost 没有准确显示 possible pthread_mutex_lock errors 中的哪一个。已经发生了。

关于c++ - Boost 作用域锁定断言失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26262438/

相关文章:

c++ - NCURSES:创建没有循环的标题栏

c++ - 您知道 Qt 中的任何词法分析器或词法分析器吗?

c++ - 从 C++ 控制台应用程序开始使用 SQL Express

c++ - 在多线程应用程序中安全卸载 DLL/共享对象

c++ - 如何重新初始化嵌入式 Python 解释器?

c++ - boost::optional<T&> vs T*

c++ - 我如何继承 gtest testing::Test?

java - 获取每个 executorservice 线程背后的查询

ios - Swift:如何确保 seque 在 http 任务完成之前不运行?

c++ - boost.Python 如何公开 boost::shared_ptr 的 typedef?