Ich arbeite an einem serverseitigen Projekt, das mehr als 100 Client-Verbindungen akzeptieren soll.pthread_mutex_lock __pthread_mutex_lock_full: Assertion fehlgeschlagen mit robust und 0x4000000
Es ist Multithread-Programm mit boost :: thread. An einigen Stellen verwende ich boost::lock_guard<boost::mutex>
, um die freigegebenen Mitgliedsdaten zu sperren. Es gibt auch eine BlockingQueue<ConnectionPtr>
, die die Eingangsverbindungen enthält. Die Umsetzung der 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;
};
Für jede Connection
, gibt es eine ConcurrentQueue<StreamPtr>
, die die Eingangsströme enthält. Die Umsetzung des 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;
};
Wenn das Programm debuggen, es ist okay. Aber in einem Lasttest mit 50 oder 100 oder mehr Client-Verbindungen, manchmal abgebrochen es mit
pthread_mutex_lock.c:321: __pthread_mutex_lock_full: Assertion `robust || (oldval & 0x40000000) == 0' failed.
Ich habe keine Ahnung, was passiert ist, und es kann nicht jedes Mal reproduziert werden.
Ich googelte viel, aber kein Glück. Bitte beraten.
Danke.
Peter
Was ist der Stack-Trace beim Abbruch? –
Hallo David, danke für deine Kommentare. Ich habe versucht, GDB zu verwenden, um den Stack-Trace zu erhalten, aber ein anderes Problem [http://stackoverflow.com/questions/9948113/boostweak-prt-lock-crashes-with-a-sigsegv-segmention-fault] passiert. Also muss ich das zuerst beheben. Die Schwierigkeit, die ich jetzt habe, ist, dass all diese Probleme von den Belastungstests mit 50 oder 100 oder mehr Verbindungen herrühren und nicht jedes Mal reproduziert werden können. Ich werde mehr Infos posten, sobald ich es habe. –