RedHat 5.5で実行されている4.1.2でコンパイルされた2つのプログラムがあります。これは、次のように共有メモリshmem1.cをテストする簡単な作業です。
#define STATE_FILE "/program.shared"
#define NAMESIZE 1024
#define MAXNAMES 100
typedef struct
{
char name[MAXNAMES][NAMESIZE];
int heartbeat ;
int iFlag ;
} SHARED_VAR;
int main (void)
{
int first = 0;
int shm_fd;
static SHARED_VAR *conf;
if((shm_fd = shm_open(STATE_FILE, (O_CREAT | O_EXCL | O_RDWR),
(S_IREAD | S_IWRITE))) > 0 ) {
first = 1; /* We are the first instance */
}
else if((shm_fd = shm_open(STATE_FILE, (O_CREAT | O_RDWR),
(S_IREAD | S_IWRITE))) < 0) {
printf("Could not create shm object. %s\n", strerror(errno));
return errno;
}
if((conf = mmap(0, sizeof(SHARED_VAR), (PROT_READ | PROT_WRITE),
MAP_SHARED, shm_fd, 0)) == MAP_FAILED) {
return errno;
}
if(first) {
for(idx=0;idx< 1000000000;idx++)
{
conf->heartbeat = conf->heartbeat + 1 ;
}
}
printf("conf->heartbeat=(%d)\n",conf->heartbeat) ;
close(shm_fd);
shm_unlink(STATE_FILE);
exit(0);
}//main
そしてshmem2.cは次のようになります:
#define STATE_FILE "/program.shared"
#define NAMESIZE 1024
#define MAXNAMES 100
typedef struct
{
char name[MAXNAMES][NAMESIZE];
int heartbeat ;
int iFlag ;
} SHARED_VAR;
int main (void)
{
int first = 0;
int shm_fd;
static SHARED_VAR *conf;
if((shm_fd = shm_open(STATE_FILE, (O_RDWR),
(S_IREAD | S_IWRITE))) < 0) {
printf("Could not create shm object. %s\n", strerror(errno));
return errno;
}
ftruncate(shm_fd, sizeof(SHARED_VAR));
if((conf = mmap(0, sizeof(SHARED_VAR), (PROT_READ | PROT_WRITE),
MAP_SHARED, shm_fd, 0)) == MAP_FAILED) {
return errno;
}
int idx ;
for(idx=0;idx< 1000000000;idx++)
{
conf->heartbeat = conf->heartbeat + 1 ;
}
printf("conf->heartbeat=(%d)\n",conf->heartbeat) ;
close(shm_fd);
exit(0);
}
コンパイル後:
gcc shmem1.c -lpthread -lrt -o shmem1.exe
gcc shmem2.c -lpthread -lrt -o shmem2.exe
そして、2つの端末でほぼ同時に両方のプログラムを実行します:
[test]$ ./shmem1.exe
First creation of the shm. Setting up default values
conf->heartbeat=(840825951)
[test]$ ./shmem2.exe
conf->heartbeat=(1215083817)
戸惑う!! shmem1.cは1,000,000,000回のループなので、840,825,951のような答えを得るにはどうすればよいでしょうか。
shmem1.exeとshmem2.exeをこのように実行すると、ほとんどの結果はconf-> heartbeatが1,000,000,000を超えますが、めったにランダムに、結果conf->heartbeatが
shmem1.exeまたはshmem2.exe !!
shmem1.exeのみを実行すると、常に1,000,000,000が出力されます。私の質問は、shmem1.exeでconf-> heartbeat =(840825951)が発生する理由は何ですか。
更新:わかりませんが、何が起こっているのか理解できたと思います。たとえば、shmem1.exeが10回実行された場合、conf-> heartbeat = 10、今回はshmem1.exeが休憩してから、shmem1に戻ります。 .exeは共有メモリから読み取られ、conf-> heartbeat = 8なので、shmem1.exeは8から続行されます。なぜ、conf-> heartbeat = 8なのですか?shmem2.exeが共有メモリデータを8に更新し、shmem1.exeが休憩する前に共有メモリに10を書き戻さなかったためだと思います....それは私の理論です...方法がわかりませんそれを証明するために!!