【发布时间】: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<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.
我不知道发生了什么,而且每次都无法重现。
我搜索了很多,但没有运气。请指教。
谢谢。
彼得
【问题讨论】:
-
中止时的堆栈跟踪是什么?
-
嗨,大卫,感谢您的 cmets。我试图使用 GDB 来获取堆栈跟踪,但发生了另一个问题 [stackoverflow.com/questions/9948113/…。所以我需要先解决这个问题。我现在遇到的困难是所有这些问题都来自 50 或 100 或更多连接的负载测试,并且无法每次都重现。一旦有,我会发布更多信息。