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
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
Vous devez vous connecter pour publier un commentaire.
0x40000000
estFUTEX_OWNER_DIED
- qui a les documents suivants dans lefutex.h
en-tête:Donc, l'affirmation semble être une indication qu'un fil qui tient la serrure est sortie pour une raison quelconque - est-il un moyen de tha un objet thread peut être détruite alors qu'il tient une serrure?
Une autre chose à vérifier est si vous avez une sorte de corruption de la mémoire quelque part. Valgrind pourrait être un outil qui peut vous aider avec ça.
OriginalL'auteur Michael Burr