Я думаю, что я должен предполагать что-то из имени boost::interprocess
, что не соответствует действительности. В документах повторяется, что named_mutex
является глобальным здесь.
Я не могу заставить его работать, хотя. Две копии одного и того же исполняемого файла должны запускаться одновременно, и я ожидаю, что именованный мьютекс в библиотеке с именем boost::interprocess
иногда может фактически БЛОКИРОВАТЬСЯ. Это не так. Это также не предотвращает повреждение файла данных в приведенном ниже коде.
Вот некоторый код из документации по повышению:
#include <boost/interprocess/sync/scoped_lock.hpp>
#include <boost/interprocess/sync/named_mutex.hpp>
#include <fstream>
#include <iostream>
#include <cstdio>
int main ()
{
using namespace boost::interprocess;
try{
struct file_remove
{
file_remove() { std::remove("file_name"); }
~file_remove(){ std::remove("file_name"); }
} file_remover;
struct mutex_remove
{
mutex_remove() { named_mutex::remove("fstream_named_mutex"); }
~mutex_remove(){ named_mutex::remove("fstream_named_mutex"); }
} remover;
//Open or create the named mutex
named_mutex mutex(open_or_create, "fstream_named_mutex");
std::ofstream file("file_name");
for(int i = 0; i < 10; ++i){
//Do some operations...
//Write to file atomically
scoped_lock<named_mutex> lock(mutex);
file << "Process name, ";
file << "This is iteration #" << i;
file << std::endl;
}
}
catch(interprocess_exception &ex){
std::cout << ex.what() << std::endl;
return 1;
}
return 0;
Вот что я сделал с ним, чтобы доказать себе, что мьютекс что-то делает:
#include <windows.h>
#include <boost/interprocess/sync/interprocess_mutex.hpp>
#include <boost/lambda/lambda.hpp>
#include <boost/interprocess/sync/scoped_lock.hpp>
#include <boost/interprocess/sync/named_mutex.hpp>
#include <iostream>
#include <iterator>
#include <algorithm>
#include <fstream>
#include <iostream>
#include <cstdio>
int main (int argc, char *argv[])
{
srand((unsigned) time(NULL));
using namespace boost::interprocess;
try{
/*
struct file_remove
{
file_remove() { std::remove("file_name"); }
~file_remove(){ std::remove("file_name"); }
} file_remover;
*/
struct mutex_remove
{
mutex_remove() { named_mutex::remove("fstream_named_mutex"); }
~mutex_remove(){ named_mutex::remove("fstream_named_mutex"); }
} remover;
//Open or create the named mutex
named_mutex mutex(open_or_create, "fstream_named_mutex");
std::ofstream file("file_name");
for(int i = 0; i < 100; ++i){
//Do some operations...
//Write to file atomically
DWORD n1,n2;
n1 = GetTickCount();
scoped_lock<named_mutex> lock(mutex);
n2 = GetTickCount();
std::cout << "took " << (n2-n1) << " msec to acquire mutex";
int randomtime = rand()%10;
if (randomtime<1)
randomtime = 1;
Sleep(randomtime*100);
std::cout << " ... writing...\n";
if (argc>1)
file << argv[1];
else
file << "SOMETHING";
file << " This is iteration #" << i;
file << std::endl;
file.flush(); // added in case this explains the corruption, it does not.
}
}
catch(interprocess_exception &ex){
std::cout << "ERROR " << ex.what() << std::endl;
return 1;
}
return 0;
}
Выход консоли:
took 0 msec to acquire mutex ... writing...
took 0 msec to acquire mutex ... writing...
took 0 msec to acquire mutex ... writing...
took 0 msec to acquire mutex ... writing...
Также демо пишет в файл, в котором при запуске двух копий программы будут отсутствовать некоторые данные.
Я ожидаю, что если я удалю file_name
и запущу две копии программы, я должен получить чередующиеся записи в file_name
, содержащие 100 строк из каждого экземпляра.
(Обратите внимание, что демонстрационный код явно не использует ofstream
в режиме добавления, вместо этого он просто перезаписывает файл каждый раз, когда эта программа запускается, поэтому, если мы хотим, чтобы демонстрация показывала два процесса записи в файл, я знаю об этом Причина, по которой это не сработает, но я ожидал, что приведенный выше код будет возможной демонстрацией взаимного исключения, что не так.Также можно было бы включить вызовы очень удобного и точно названного метода ofstream::flush()
, и не было 'т.)
Использование Boost 1.53 в Visual C++ 2008
(void)remover;
передnamed_mutex mutex(...
. 09.03.2013remover
состоит в том, чтобы удалить любой возможный мьютекс, который может остаться от предыдущего выполнения, перед созданием нового мьютекса, а затем удалить его в конце, как толькоremover
выйдет за рамки. Я действительно понятия не имею, что делает(void)remover;
, но, возможно, это способ заставить компилятор не оптимизироватьremover
. И то же самое сfile_remover
. 09.03.2013When boost library “interprocess” defines a named_mutex do those named_mutexes work properly between different processes, or only with threads?
Вы прямо не отвечаете на вопрос - но исправляете код 24.06.2020