共有メモリ空間って排他処理しなくていいのだろうか?
CreateFileMapping と MapViewOfFile を利用すると、プロセス間を超えた共有メモリ空間を作成することができますがー
これ、つまりは 「同じメモリ空間に対して、複数のプロセスから同時にアクセスされる可能性がある」 == 排他処理しないと落ちるんじゃね!? とか思いまして調べてみたんです。 …が、どーも、排他処理してるコードが見つからず。Advanced Windows でさえ、排他処理してない。 うーん?本当に大丈夫なのかしら〜?
というわけで、実験してみました。↓がコード概略。 最適化してみましたが、/GL はつけませんでした。
// maptest.cpp : コンソール アプリケーションのエントリ ポイントを定義します。
//
#include "stdafx.h"
#include "memtest.h"
#include "DummyRead.h"
const size_t LOOP_TIMES = 1024 * 1024 * 512;
const size_t DISP_SPAN = 4096;
int _tmain(int argc, _TCHAR* argv[])
{
ATL::CAtlFileMapping<> cFile;
_tprintf(_T("0 : Write\n1 : Read\n>"));
wint_t nType = _gettchar();
if(nType == _T('0'))
{ // write
if(FAILED(cFile.MapSharedMem(BUFF_SIZE, _T("kanaria"), NULL, NULL, PAGE_READWRITE, FILE_MAP_WRITE)))
return ::MessageBox(NULL, NULL, NULL, NULL);
char* pAddr = cFile;
for(size_t i = 0; i < LOOP_TIMES; ++i)
{
::memset(pAddr, 9, BUFF_SIZE);
if((i % DISP_SPAN) == 0)
_puttchar(_T('w'));
}
}
else
{ // read
if(FAILED(cFile.MapSharedMem(BUFF_SIZE, _T("kanaria"), NULL, NULL, PAGE_READONLY, FILE_MAP_READ)))
return ::MessageBox(NULL, NULL, NULL, NULL);
char* pAddr = cFile;
for(size_t i = 0; i < LOOP_TIMES; ++i)
{
DummyRead(pAddr);
if((i % DISP_SPAN) == 0)
_puttchar(_T('r'));
}
}
return 0;
}
これ、Raed/Write それぞれ 2ずつ同時に動かしてみたところ……
落ちなかったんですよ。
えええ〜、Windowsがうまいことやってくれてるのかしら? うーん、意外と 窓ってがんばってるんじゃねーの!? すげーすげーすg……………
……
動作チェックしたマシン、コレ、シングルコアCPUだ……orz (Athlon 64 なのよー)
自宅のデュアルマザーで動かしてみよう…うう…
Pen3-850 Dual で試してみた
おんなじコードをビルドして Read/Write それぞれ2こ起動してみました。結果
落ちませんでした…
いやー、なんか信じられん…。個人的には 自分のコードにバグがあるとしか思えない んですが…^^;
排他処理しなくて…OK… かしら〜?