pthread_mutex_lock __pthread_mutex_verrou_plein: échec de l'Assertion avec robuste et 0x4000000

Je suis en train de travailler sur un projet côté serveur, ce qui est censé accepter plus de 100 connexions client.

C'est un programme multithread utilisation de boost::thread. Certains endroits, je suis en utilisant boost::lock_guard<boost::mutex> pour verrouiller le membre partagé des données. Il y a aussi un BlockingQueue<ConnectionPtr> qui contient les connexions d'entrée. La mise en œuvre de la 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;
};

Pour chaque Connection, il y a un ConcurrentQueue<StreamPtr>, qui contient les Flux d'entrée. La mise en œuvre de la 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;
};

Lors du débogage du programme, c'est d'accord. Mais dans un test de charge avec 50 ou 100 ou plus des connexions client, parfois, il abandonnée avec

pthread_mutex_lock.c:321: __pthread_mutex_lock_full: Assertion `robust || (oldval & 0x40000000) == 0' failed.

Je n'ai aucune idée de ce qui s'est passé, et il ne peut être reproduit à chaque fois.

J'ai googlé beaucoup, mais pas de chance. Veuillez informer.

Grâce.

Peter

Quelle est la trace de la pile lorsqu'elle abandonne?
Salut David, merci pour vos commentaires. J'ai essayé d'utiliser GDB pour obtenir la trace de la pile, mais un autre problème [stackoverflow.com/questions/9948113/... qui se passe. J'ai donc besoin de corriger cela d'abord. La difficulté que je vais avoir maintenant, c'est que tous ces problèmes viennent de la de test de charge avec 50 ou 100 ou plus de connexions, et ne peut être reproduit à chaque fois. Je vais poster plus d'info dès que je l'aurai.

OriginalL'auteur Peter Lee | 2012-03-30