私はかなりの数日間これに取り組んできました(boostフォーラムにも投稿されました)が、ロックされたミューテックスを2番目のプロセスに認識させることができないようです。助けてください。これはコードです:
共通ヘッダー ファイル: SharedObject.hpp
#ifndef SHAREDOBJECT_HPP
#define SHAREDOBJECT_HPP
#include <iostream>
#include <boost/interprocess/mapped_region.hpp>
#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/interprocess/containers/list.hpp>
#include <time.h>//for sleep
//--------for mutexes
#include <boost/interprocess/mapped_region.hpp>
#include <boost/interprocess/shared_memory_object.hpp>
#include <boost/interprocess/sync/interprocess_upgradable_mutex.hpp>
#include <boost/interprocess/sync/scoped_lock.hpp>
#include <boost/interprocess/sync/sharable_lock.hpp>
#include <boost/interprocess/sync/upgradable_lock.hpp>
#define MUTEX_SHARED_MEMORY_NAME "NavSharedMemoryMutex"
#define DATAOUTPUT "OutputFromObject"
#define INITIAL_MEM 650000
using namespace std;
namespace bip = boost::interprocess;
class SharedMutex
{
private:
typedef bip::interprocess_upgradable_mutex upgradable_mutex_type;
mutable upgradable_mutex_type mutex;
volatile int counter;
public:
void lockWithReadLock() const { bip::sharable_lock<upgradable_mutex_type> lock(mutex); }
void lockWithWriteLock() { bip::scoped_lock<upgradable_mutex_type> lock(mutex); }
};
//-------------------------------------- SharedMemoryObject
class SharedObject
{
public:
SharedMutex* sharedMutex;
};
typedef bip::allocator<SharedObject, bip::managed_shared_memory::segment_manager> ShmemAllocator;
typedef bip::list<SharedObject, ShmemAllocator> SharedMemData;
#endif /* SHAREDOBJECT_HPP */
これは最初のプログラムです:
#include "SharedObject.hpp"
int main()
{
//-----------Create shared memory and put shared object into it
bip::managed_shared_memory* seg;
SharedMemData *sharedMemOutputList;
bip::shared_memory_object::remove(DATAOUTPUT);
seg = new bip::managed_shared_memory(bip::create_only, DATAOUTPUT, INITIAL_MEM);
const ShmemAllocator alloc_inst(seg->get_segment_manager());
sharedMemOutputList = seg->construct<SharedMemData>("TrackOutput")(alloc_inst);
std::size_t beforeAllocation = seg->get_free_memory();
std::cout<<"\nBefore allocation = "<< beforeAllocation <<"\n";
SharedObject temp;
sharedMemOutputList->push_back(temp);
//-------------------Create a shared memory for holding a mutex
bip::shared_memory_object::remove(MUTEX_SHARED_MEMORY_NAME);//BUG: If another program also removes this, then there won't be any shared memory remaining. This problem has to be handled better. This is not the right way to deal with shared mutexes.
bip::shared_memory_object shm(bip::create_only, MUTEX_SHARED_MEMORY_NAME, bip::read_write);
shm.truncate(sizeof (SharedMutex)); //Allocate memory in shared memory for the mutex
bip::mapped_region region(shm, bip::read_write); // Map the whole shared memory into this process.
new (region.get_address()) SharedMutex; // Construct the SharedMutex using placement new
temp.sharedMutex = static_cast<SharedMutex *> (region.get_address()); //Store the mutex object address for future reference
{
std::cout<<"Program 1: Before first locking -------------------------- 1 v\n";
temp.sharedMutex->lockWithWriteLock();
const unsigned int SLEEP_TIME_IN_SECOND = 60;
std::cout<<"Program 1: sleep for "<< SLEEP_TIME_IN_SECOND << "\n";
sleep(SLEEP_TIME_IN_SECOND);
std::cout<<"Program 1: Finished sleeping\n";
}
std::cout<<"Program 1: unlocked -------------------------------------- 1 ^\n";
seg->destroy<SharedMemData>("TrackOutput");
delete seg;
return 0;
}//main
そして、これが 2 番目のプログラムです。
#include "SharedObject.hpp"
#define CREATE_SEPARATE_MUTEX
int main()
{
bip::managed_shared_memory segment(bip::open_only, DATAOUTPUT); //Open the managed segment
SharedMemData* sharedMemoryTrackOutputList = segment.find<SharedMemData>("TrackOutput").first; //Find the list using the c-string name
assert(sharedMemoryTrackOutputList);
std::cout << "SharedMemoryData address found at = " << (void *) sharedMemoryTrackOutputList << "\n";
std::cout << "size = " << sharedMemoryTrackOutputList->size() << "\n";
SharedMemData::iterator iter = sharedMemoryTrackOutputList->begin();
#ifndef CREATE_SEPARATE_MUTEX
//-------------------Create a shared memory for holding a mutex
bip::shared_memory_object shm(bip::open_or_create, MUTEX_SHARED_MEMORY_NAME, bip::read_write);
shm.truncate(sizeof (SharedMutex)); //Allocate memory in shared memory for the mutex
bip::mapped_region region(shm, bip::read_write); // Map the whole shared memory into this process.
new (region.get_address()) SharedMutex; // Construct the SharedMutex using placement new
(*iter).sharedMutex = static_cast<SharedMutex *> (region.get_address()); //Store the mutex object address for future reference
#endif
{
std::cout<<"Program 2: Before first locking -------------------------- 1 v\n";
(*iter).sharedMutex->lockWithWriteLock();
const unsigned int SLEEP_TIME_IN_SECOND = 1;
std::cout<<"Program 2: sleep for "<< SLEEP_TIME_IN_SECOND << "\n";
sleep(SLEEP_TIME_IN_SECOND);
std::cout<<"Program 2: Finished sleeping\n";
}
std::cout<<"Program 2: unlocked -------------------------------------- 1 ^\n";
return 0;
}//main
プログラム 1 は問題なく動作します。
プログラム 2 の出力は次のとおりです。
SharedMemoryData address found at = 0x7f0a4c2b8118
size = 1
Program 2: Before first locking -------------------------- 1 v
terminate called after throwing an instance of 'boost::interprocess::lock_exception'
what(): boost::interprocess::lock_exception
Aborted (core dumped)
最初に program1 を実行しています。これにより、ミューテックスがロックされ、60 秒間ロックされたままになります。その間、プログラム 2 を実行して、ロックを待機しているかどうかを確認しましたが、クラッシュしました。プログラム 1 が共有メモリへの書き込みを完了するまで、プログラム 2 をミューテックスで待機させるにはどうすればよいですか?