boost named_condition weckt den Wartevorgang nicht auf

Ich habe 2 Prozesse (Produzent und Konsument), die sich eine int-Deque im gemeinsamen Speicher teilen. Ich habe den Produzent-Prozess 2 Zahlen in die Deque gestellt und dann wird er in einen Wartezustand versetzt, der seine Mutex-Sperre verliert. Dann muss der Verbraucher die Nummern entfernen und ausdrucken. Es erfolgt dann eine Benachrichtigung über den Zustand, auf den der Produzent wartet. Der Verbraucher wartet dann von selbst unter einer zweiten Bedingung. Nach diesem Fall wacht der Produzent nicht auf. Ich verwende den gleichen Mutex zwischen den Prozessen. Bitte finden Sie den gesamten Code unten.

Include-Datei 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 

Hersteller prozess:

#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();
        }
    }
}

Verbraucherprozess:

#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();
         }
    }
}

Während das Debuggen bei der ersten Iteration in Ordnung zu sein scheint, setzt der Produzent die Nummern 2 und 4 auf die Deque und wartet dann auf die volle Bedingung. Der Verbraucher erhält dann die Sperre, druckt diese Nummern aus, führt eine Benachrichtigung über die vollständige Bedingung durch und wartet dann. Danach wacht der Produzent nicht auf.

Antworten auf die Frage(1)

Ihre Antwort auf die Frage