boost named_condition 没有唤醒等待进程
我有 2 个进程(生产者和消费者)在共享内存中共享一个 int 双端队列,我让生产者进程在双端队列中放入 2 个数字,然后它进入等待状态,失去互斥锁.然后我让消费者??进程删除数字并打印它们.然后它会根据生产者正在等待的条件发出通知.然后消费者在第二个条件下自行等待.在这种情况下,生产者不会醒来.我在进程之间使用相同的互斥锁.请在下面找到所有代码.
I have 2 processes (producer and consumer) sharing an int deque in shared memory, I have the producer process put 2 numbers in the deque and then it gets in a wait state losing its mutex lock. I then have the consumer process removing the numbers and printing them. It then does a notify on the condition which the producer is waiting on. The consumer then goes on its own wait on a second condition. After this case the producer does not wake up. I am using the same mutex between the processes. Please find all code below.
包含文件 shared_memory.h:
Include file 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
生产者进程:
#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();
}
}
}
消费者进程:
#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();
}
}
}
虽然第一次迭代的调试似乎没问题,但生产者将数字 2 和 4 放在双端队列上,然后等待完整的条件.消费者然后获得锁,打印这些数字,在完整条件下执行 notify_one,然后进入等待.在此之后,生产者不会醒来.
While debugging things seem to go ok for the first iteration, the producer puts numbers 2 and 4 on the deque then waits on the full condition. The Consumer then gets the lock, prints these numbers, does a notify_one on the full condition and then goes into a wait. After this the producer does not wake up.
推荐答案
互斥锁不能跨通知锁定.这就是死锁的原因.
The mutex must not be locked across notifying. This is the reason of the deadlock.
相关文章