У меня следующая проблема.
У меня есть два класса, в данном случае A и B, которые оба имеют concurrent_queue
. Здесь предполагается, что concurrent_queue - это потокобезопасная очередь с блокирующей функцией push (). Когда объект помещен в очередь в B, он получает доступ к одиночке A, и он также ставится в очередь в A. Это приводит к тому, что целая куча B имеет небольшие очереди со своими собственными объектами и одну большую очередь в A, которая содержит их все. Каждый экземпляр B может жить в отдельном потоке.
С чем я сталкиваюсь, так это то, что часто поток пропускается между двумя строками кода в B :: foo (), то есть A :: mQueue содержит объект, но B :: mQueue еще не содержит объект.
Что мне интересно, так это то, как я могу гарантировать, что при вызове B :: foo () объект либо помещается в обе очереди, либо ни в одну из очередей. Мне кажется, что я должен был бы иметь мьютекс в A, который B мог бы захватить, и заблокировать мьютекс A в B :: foo ().
Есть ли у кого-нибудь предложения, как мне это сделать или как я могу реструктурировать свой код для этого? Я использую библиотеку boost :: threading.
Class A
{
public:
A& instance(){/* return singleton */}
void addToQueue(SomeObject const& obj)
{
mQueue.push(obj);
}
private:
concurrent_queue<SomeObject> mQueue;
};
Class B
{
public:
void foo()
{
SomeObject obj;
//I would like to guarantee that obj is either present in both queues or neither queue
A::instance().addToQueue(obj);
mQueue.push(obj);
}
private:
concurrent_queue<SomeObject> mQueue;
};
В моей реальной реализации это не тот же объект, который ставится в очередь в A и B, а структуры очередей A, которые содержат указатели на B, что позволяет мне удалять все из A и удалять из всех B в в том же порядке, в котором они были поставлены в очередь, но это не должно относиться к вопросу.