POSIX shm
参考
Pthread - Mutexでプロセス間排他制御を行う - s-kitaの日記
送信
#include <stdio.h> #include <unistd.h> /* for ftruncate */ #include <sys/mman.h> /* for shm_open */ #include <sys/stat.h> /* for *_MODE */ #include <fcntl.h> /* for O_* */ #define FILE_MODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) #include <pthread.h> int EndFlag=0; int main() { //int id; int *adr; pthread_mutex_t *mtx; //int adr; //key_t key; int fd, ret; /* 共有メモリ・オブジェクトを作成 */ fd = shm_open("/shared_memory", O_RDONLY, FILE_MODE); if(fd == -1) { perror("shm_open"); fprintf(stderr, "recv を先に呼んでください\n"); return 1; } /* 共有メモリ・オブジェクトを作成 */ fd = shm_open("/shared_memory", O_CREAT | O_RDWR, FILE_MODE); if(fd == -1) { perror("shm_open"); return 1; } /* 使用するメモリ領域を拡張 */ ret = ftruncate(fd, sizeof(int)); if (ret != 0) { /* error handling */ perror("ftruncate"); return 1; } adr = mmap (0, sizeof(int), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); /* mutex */ fd = shm_open("/shared_memory_mtx", O_CREAT | O_RDWR, FILE_MODE); if(fd == -1) { perror("shm_open mtx"); return 1; } ret = ftruncate(fd, sizeof(pthread_mutex_t)); if (ret != 0) { /* error handling */ perror("ftruncate mtx"); return 1; } mtx = mmap (0, sizeof(pthread_mutex_t), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if(adr == MAP_FAILED) { /* error handling */ perror("mmap"); return 1; } else { while(1){ sleep(1); pthread_mutex_lock(mtx); printf("*** send1 %d\n", *adr); *adr = *adr + 1; sleep(1); printf("*** send2 %d\n", *adr); *adr = *adr + 1; sleep(1); printf("*** send3 %d\n", *adr); *adr = *adr + 1; pthread_mutex_unlock(mtx); } } ret = shm_unlink("/shared_memory"); if (ret != 0) { /* error handling */ perror("shm_unlink"); return 1; } ret = shm_unlink("/shared_memory_mtx"); if (ret != 0) { /* error handling */ perror("shm_unlink mtx"); return 1; } return(0); }
受信
#include <stdio.h> /* for perror */ #include <unistd.h> /* for ftruncate */ #include <signal.h> #include <sys/mman.h> /* for shm_open */ #include <sys/stat.h> /* for S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH */ #include <fcntl.h> /* for O_* */ #define FILE_MODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) #include <pthread.h> int EndFlag=0; void sigHandle(int sig) { EndFlag=sig; } int main() { //int id; int *adr; pthread_mutex_t *mtx; pthread_mutexattr_t mattr; //int adr; //key_t key; int fd, ret; signal(SIGINT,sigHandle); signal(SIGTERM,sigHandle); signal(SIGQUIT,sigHandle); /* 共有メモリ・オブジェクトを作成 */ fd = shm_open("/shared_memory", O_CREAT | O_RDWR, FILE_MODE); /* O_CREAT: 存在しない場合、共有メモリーオブジェクトを作成する */ /* O_RDWR : 読み書きアクセス用にオブジェクトをオープンする。 */ /* O_EXCL : O_CREAT が一緒に指定されており、 name で指定された共有メモリーオブジェクトが既に存在した場合、 エラーを返す。 */ if(fd == -1 ) { perror("shm_open"); return 1; } /* 使用するメモリ領域を拡張 */ ret = ftruncate(fd, sizeof(int)); if (ret != 0) { /* error handling */ perror("ftruncate"); return 1; } adr = mmap (0, sizeof(int), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); *adr = 2147483646; /* mutex */ fd = shm_open("/shared_memory_mtx", O_CREAT | O_RDWR, FILE_MODE); if(fd == -1) { perror("shm_open mtx"); return 1; } ret = ftruncate(fd, sizeof(pthread_mutex_t)); if (ret != 0) { /* error handling */ perror("ftruncate mtx"); return 1; } mtx = mmap (0, sizeof(pthread_mutex_t), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); /* プロセス間排他y用に初期化 */ pthread_mutexattr_init(&mattr); pthread_mutexattr_setpshared(&mattr, PTHREAD_PROCESS_SHARED); ret = pthread_mutex_init(mtx, &mattr); if (ret != 0) { fprintf(stderr, "pthread_mutex_init error\n"); return 1; } if(adr == MAP_FAILED) { /* error handling */ perror("mmap"); return 1; } else if(mtx == MAP_FAILED) { /* error handling */ perror("mmap mtx"); return 1; } else { while(1){ sleep(1); if(EndFlag!=0){ fprintf(stderr,"EndFlag=%d\n",EndFlag); break; } ret = pthread_mutex_lock(mtx); if (ret != 0) { fprintf(stderr, "pthread_mutex_lock error\n"); } *adr = *adr - 1; printf("*** decr1 %d\n",*adr); sleep(3); *adr = *adr - 1; printf("*** decr2 %d\n",*adr); sleep(2); pthread_mutex_unlock(mtx); if (ret != 0) { fprintf(stderr, "pthread_mutex_unlock error\n"); } } } ret = shm_unlink("/shared_memory"); if (ret != 0) { /* error handling */ perror("shm_unlink"); return 1; } ret = shm_unlink("/shared_memory_mtx"); if (ret != 0) { /* error handling */ perror("shm_unlink mtx"); return 1; } return(0); }