Pthread - Mutexでプロセス間排他制御を行う
Mutex関連 #include <pthread.h> int pthread_mutex_init( pthread_mutex_t *mutex, const pthread_mutexattr_t *attr); int pthread_mutex_lock(pthread_mutex_t *mutex); int pthread_mutex_unlock(pthread_mutex_t *mutex); int pthread_mutex_destroy(pthread_mutex_t *mutex);
Mutex属性関連 #include <pthread.h> int pthread_mutexattr_init(pthread_mutexattr_t *attr); int pthread_mutexattr_destroy(pthread_mutexattr_t *attr); int pthread_mutexattr_setpshared( pthread_mutexattr_t *attr, int pshared);
メモリマップドファイル関連 #include <sys/mman.h> void *mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset); int munmap(void *start, size_t length);
#include <pthread.h> #include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <sys/mman.h> #include <fcntl.h> #include <sys/wait.h> #define FILENAME "counter" static pthread_mutex_t *mptr; void my_lock_init() { int fd; pthread_mutexattr_t mattr; fd = open("/dev/zero", O_RDWR, 0); mptr = (pthread_mutex_t*)mmap(0, sizeof(pthread_mutex_t), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); close(fd); pthread_mutexattr_init(&mattr); pthread_mutexattr_setpshared(&mattr, PTHREAD_PROCESS_SHARED); pthread_mutex_init(mptr, &mattr); } void my_lock_wait() { pthread_mutex_lock(mptr); } void my_lock_release() { pthread_mutex_unlock(mptr); } void my_lock_destroy() { munmap(0, sizeof(pthread_mutex_t)); pthread_mutex_destroy(mptr); } void print_counter() { int counter; char buff[16]; FILE *fp; my_lock_wait(); /////////////////////////////////////// //Critical Region if ( (fp = fopen(FILENAME, "r")) != NULL ) { fgets(buff, sizeof(buff), fp); fclose(fp); counter = atoi(buff); counter++; } printf("%d\n", counter); if ( (fp = fopen(FILENAME, "w")) != NULL ) { fprintf(fp, "%d", counter); fclose(fp); } //Critical Region /////////////////////////////////////// my_lock_release(); } void init_counter_file() { FILE *fp; fp = fopen(FILENAME, "w"); fprintf(fp, "0"); fclose(fp); } int main() { int i; pid_t pids[1000]; int n; init_counter_file(); my_lock_init(); n = sizeof(pids)/sizeof(pids[0]); for (i = 0; i < n; i++) { if ( (pids[i] = fork() ) == 0) { print_counter(); exit(0); } } for (i = 0; i < n; i++) { waitpid(pids[i], NULL, 0); printf("pid %u is ended\n", pids[i]); } my_lock_destroy(); puts("Exit"); return 0; }