Я пытаюсь использовать Boost :: Interprocess для создания двух процессов, которые могут взаимодействовать друг с другом. Я прочитал многие доступные учебники и библиотеки по Boost в Интернете и не смог найти причину, по которой мой код ведет себя не так, как мне кажется.
Первый файл: (memObject.h)
#include <boost/interprocess/sync/interprocess_semaphore.hpp>
#include <boost/interprocess/shared_memory_object.hpp>
#include <boost/interprocess/mapped_region.hpp>
#include <boost/interprocess/sync/interprocess_mutex.hpp>
#include <boost/interprocess/sync/scoped_lock.hpp>
#include <boost/interprocess/sync/interprocess_condition.hpp>
#include <cstdlib>
#include <iostream>
#define bip boost::interprocess
struct userCommands
{
userCommands()
{}
// User can send up to a 100-character command
char userCommand[100];
int userInt;
bip::interprocess_mutex mutex;
};
Этот файл должен содержать структуру общей памяти, в которую будут записываться оба процесса.
Второй файл: (oneMutex. cpp)
// PRODUCER
#include "memObject.h"
int main(int argc, char** argv)
{
// Establish destruction of shared memory region on program creation and destruction
struct shm_remove
{
shm_remove() { bip::shared_memory_object::remove("testSharedMemory"); }
~shm_remove() { bip::shared_memory_object::remove("testSharedMemory"); }
} remover;
// Create a shared-memory object called "shm"
bip::shared_memory_object shm(bip::create_only, "testSharedMemory", bip::read_write);
// Set size
shm.truncate(sizeof(userCommands));
// Map the whole shared memory in this process
bip::mapped_region region(shm, bip::read_write);
// Get the address of the mapped region
void * addr = region.get_address();
// Construct the shared structure in memory
userCommands * data = new (addr) userCommands;
std::string userString;
for (int i = 0; i < 1000; i++)
{ // Lock the shared memory region for this scope
bip::scoped_lock<bip::interprocess_mutex> lock(data->mutex);
std::getline(std::cin, userString);
strcpy(data->userCommand, userString.c_str());
std::cout << "Should have coped: " << userString << " to the critical memory region" << std::endl;
}
}
This file должен создать объект struct в пространстве общей памяти и запустить 'for' l oop, с помощью которого он получает доступ к общей памяти и записывает предоставленную пользователем строку в массив символов 'userCommand'.
Third Файл: (twoMutex. cpp)
// CONSUMER
#include "memObject.h"
int main(int argc, char** argv)
{
// Create a shared-memory object called "shm"
bip::shared_memory_object shm(bip::open_only, "testSharedMemory", bip::read_write);
// Set size
shm.truncate(sizeof(userCommands));
// Map the whole shared memory in this process
bip::mapped_region region(shm, bip::read_write);
// Get the address of the mapped region
void * addr = region.get_address();
// Construct the shared structure in memory
userCommands * data = static_cast<userCommands*>(addr);
//userCommands * data = new (addr) userCommands;
std::string userString;
int someInt;
for (int i = 0; i < 1000; i++)
{
bip::scoped_lock<bip::interprocess_mutex> lock(data->mutex);
userString = data->userCommand;
std::cout << "Got: " << data->userCommand << " from the critical memroy region" << std::endl;
}
}
Этот файл должен отображать пространство общей памяти в свой объект («данные») и читать из него при каждой возможности.
Вот Мой вопрос:
«Область действия» al oop в каждом отдельном примере boost :: interprocess scoped_lock была определена как «одна итерация l oop». Кажется, это согласуется с тем, что я знаю о C ++.
Однако, когда я собираю их в отдельные программы и запускаю их одновременно, процесс «Потребитель» (подробно описано в «twoMutex. cpp») не сможет получить доступ. критическая область памяти до тех пор, пока процесс 'Producer' (подробно описанный в 'oneMutex. cpp') не завершит выполнение всего файла.
Когда я переключаю код на простую схему блокировки / разблокировки путем реализации :
data->mutex.lock();
// Do stuff here
data->mutex.unlock();
Он также не работает. Только когда я ввожу некоторый сон после цикла блокировки в l oop, он вообще работает:
data->mutex.lock();
//Do stuff
data->mutex.unlock();
usleep(1e3);
Как мьютекс, второй процесс не должен ожидать доступа к критической области памяти, как только Первый закончен? Почему первый процесс может войти в критическую область памяти несколько раз, в то же время блокируя второй? Если это так, то функциональность scoped_lock фактически бесполезна.
Я сделал пример с глобальными мьютексами в одной программе на C ++, и функциональность всегда согласована: второй поток будет ожидать, пока первый поток не выполнит Fini sh, затем получить доступ к замку.
Больше всего меня смущает то, что эту библиотеку Boost , кажется, рассматривают как окончательную многоплатформенную библиотеку межпроцессных операций, но функциональность, которую она демонстрирует для своих мьютексов, в основном идет вразрез со всем, что я учили о межпроцессном взаимодействии в целом. Кроме того, при копировании примеров почти дословно из каждого источника мне удалось найти, что касается Boost :: Interprocess , они не работали так, как рекламировалось.