c++ - boost named_condition no está despertando el proceso de espera
synchronization boost-interprocess (1)
El mutex no debe estar bloqueado en la notificación. Esta es la razón del punto muerto.
Tengo 2 procesos (productor y consumidor) que comparten un intqueque en la memoria compartida, el proceso del productor puso 2 números en el deque y luego se pone en estado de espera perdiendo su bloqueo de exclusión mutua. Luego hago que el proceso del consumidor elimine los números y los imprima. Luego hace una notificación sobre la condición que el productor está esperando. El consumidor luego se queda solo esperando una segunda condición. Después de este caso, el productor no se despierta. Estoy usando el mismo mutex entre los procesos. Por favor, encuentre todos los códigos a continuación.
Incluir archivo shared_memory.h:
#ifndef SharedMemory_h
#define SharedMemory_h
#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/interprocess/containers/deque.hpp>
#include <boost/interprocess/allocators/allocator.hpp>
#include <boost/interprocess/sync/scoped_lock.hpp>
#include <boost/interprocess/offset_ptr.hpp>
#include <boost/interprocess/sync/named_condition.hpp>
using namespace boost::interprocess;
typedef allocator<offset_ptr<int>, managed_shared_memory::segment_manager> ShmemAllocator;
typedef deque<offset_ptr<int>, ShmemAllocator> Deque;
#endif
Proceso de productor:
#include "shared_memory.h"
struct shm_remove
{
shm_remove() { shared_memory_object::remove("MySharedMemory"); }
~shm_remove() { shared_memory_object::remove("MySharedMemory"); }
} remover;
struct mutex_remove
{
mutex_remove() { named_mutex::remove("MyMutex"); }
~mutex_remove() { named_mutex::remove("MyMutex"); }
} mutex_remover;
//Create shared memory, mutex and condtion
managed_shared_memory segment(create_only, "MySharedMemory", 10000000);
named_mutex mutex(create_only,"MyMutex");
named_condition full(open_or_create,"FullCondition");
named_condition empty(open_or_create,"EmptyCondition");
const ShmemAllocator alloc_inst (segment.get_segment_manager());
int main()
{
Deque* MyDeque;
offset_ptr<int> a, b;
try{
MyDeque = segment.construct<Deque>("MyDeque")(alloc_inst);
try{
a = static_cast<int*> (segment.allocate(sizeof(int)));
b = static_cast<int*> (segment.allocate(sizeof(int)));
}catch(bad_alloc &ex){
std::cout << "Could not allocate int" << std::endl;
}
}catch(bad_alloc &ex){
std::cout << "Could not allocate queue" << std::endl;
}
scoped_lock<named_mutex> lock(mutex);
while(1)
{
while (MyDeque->size() == 2)
{
full.wait(lock);
std::cout << "unlocked producer" << std::endl;
}
if (MyDeque->size() == 0)
{
*a = 2;
MyDeque->push_back(a);
}
if (MyDeque->size() == 1)
{
*b = 4;
MyDeque->push_back(b);
empty.notify_one();
}
}
}
Proceso del consumidor:
#include "shared_memory.h"
managed_shared_memory segment(open_only, "MySharedMemory");
Deque* MyDeque = segment.find<Deque>("MyDeque").first;
named_mutex mutex(open_only, "MyMutex");
named_condition full(open_only, "FullCondition");
named_condition empty(open_only, "EmptyCondition");
int main()
{
scoped_lock<named_mutex> lock(mutex);
while(1)
{
//volatile int size = MyDeque->size();
while (MyDeque->size() == 0)
{
empty.wait(lock);
}
if (MyDeque->size() == 2)
{
std::cout << "Consumer: " << *MyDeque->front() << std::endl;
MyDeque->pop_front();
}
if (MyDeque->size() == 1)
{
std::cout << "Consumer: " << *MyDeque->front() << std::endl;
MyDeque->pop_front();
full.notify_one();
}
}
}
Mientras que las cosas de depuración parecen ir bien para la primera iteración, el productor pone los números 2 y 4 en el deque y luego espera en la condición completa. El Consumidor luego obtiene el candado, imprime estos números, notifica a una persona con el estado completo y luego entra en espera. Después de esto, el productor no se despierta.