名前から何かを推測しているに違いないと思いboost::interprocess
ます。ドキュメントはここnamed_mutex
でグローバルであることを繰り返します。
私はそれを機能させることができません。同じ実行可能ファイルの 2 つのコピーを同時に実行する必要が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...
また、デモはファイルに書き込みます。プログラムの 2 つのコピーを実行すると、一部のデータが失われます。
file_name
プログラムの 2 つのコピーを削除して実行するとfile_name
、各インスタンスから 100 行を含む書き込みがインターリーブされるはずです。
(注: デモ コードは明らかにofstream
in append モードを使用しておらず、代わりに、このプログラムが実行されるたびにファイルを書き換えるだけなので、ファイルに書き込む 2 つのプロセスをデモで表示したい場合は、その理由を認識しています。なぜそれがうまくいかないのか、しかし私が期待していたのは、上記のコードが相互排除の実行可能なデモンストレーションになることであり、そうではありませんofstream::flush()
。 .)
Visual C++ 2008 で Boost 1.53 を使用する