[질문]프로세스간 뮤텍스동기화 에 대해서
글쓴이: wsong / 작성시간: 목, 2009/07/16 - 6:52오후
프로세스2개와 공유메모리생성후, 공유메모리위의 뮤텍스로 동기화에 대한 간단한 테스트 프로그램인데, 동기화가 안되네요.
<시스템 스레드라이브러리 확인>
이 확인으로 NPTL이 적용된걸로 봐도되나요?
getconf GNU_LIBPTHREAD_VERSION NPTL 2.3.4
<헤더>
단순히 공유메모리용 구조체
#include <pthread.h> typedef struct shm_struct { pthread_mutex_t mtx; pthread_cond_t cond; int i, j; } shm_struct_t;
<프로그램1>
공유메모리생성후 뮤텍스,조건변수 초기화합니다.
락을 걸고 공유메모리의 변수를 1더하고, 60초간 sleep하면서 빙빙돕니다. 이 60초동안 프로그램2가 접근못하는것을 확인하려고 합니다.
인클루드부분 생략... #include "testpro.h" shm_struct_t *g_shm; pthread_mutexattr_t mtx_attr; pthread_condattr_t cond_attr; int shm_init() { int fd; int ret = 0; int shm_size; fd = shm_open("/testpro", O_RDWR|O_CREAT, S_IRUSR|S_IWUSR|S_IROTH); if (fd == -1) { fprintf(stderr, "shm_open() error\n"); return fd; } shm_size = sizeof(shm_struct_t); ret = ftruncate(fd, shm_size); if (ret == -1) { fprintf(stderr, "ftruncate() failed. errno=%d\n", errno); return ret; } g_shm = (shm_struct_t *)mmap(NULL, shm_size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); if (g_shm == MAP_FAILED) { fprintf(stderr, "mmap() failed\n"); return -1; } close(fd); pthread_mutexattr_init(&mtx_attr); ret = pthread_mutexattr_setpshared(&mtx_attr, PTHREAD_PROCESS_SHARED); if (ret) { fprintf(stderr, "pthread_mutexattr_settype() failed.(errno=%d)\n", errno); return ret; } pthread_mutex_init(&g_shm->mtx, &mtx_attr); pthread_condattr_init(&cond_attr); ret = pthread_condattr_setpshared(&cond_attr, PTHREAD_PROCESS_SHARED); if (ret) { fprintf(stderr, "pthread_mutexattr_setpshared() failed. (errno=%d)\n", errno); return ret; } pthread_cond_init(&g_shm->cond, &cond_attr); return ret; } int main() { int ret = 0; ret = shm_init(); if (ret) { fprintf(stderr, "shm_init() failed. \n"); return ret; } while (1) { pthread_mutex_lock(&g_shm->mtx); g_shm->i++; fprintf(stdout, "i = %d, j = %d\n", g_shm->i, g_shm->j); sleep(60); pthread_mutex_unlock(&g_shm->mtx); } return ret; }
<프로그램2>
공유메모리생성(항상 프로그램1이 공유메모리를 생성한 후에 실행됨.이미 생성된 공유메모리에 대해서는 참조를 하게됨.).
락을 걸고 공유메모리의 변수를 1더하고, 5초간 sleep하면서 빙빙돕니다.프로그램1이 락을 걸고 60초 sleep하기 때문에, 프로그램2가 이 60초동안 접근못하는 것을 확인해서, 프로세스간 뮤텍스 사용에 문제 없는 것을 확인하려고 합니다.
헤더부분 생략... #include "testpro.h" shm_struct_t *g_shm; pthread_mutexattr_t mtx_attr; pthread_condattr_t cond_attr; int shm_init() { int fd; int ret = 0; int shm_size; fd = shm_open("/testpro", O_RDWR|O_CREAT, S_IRUSR|S_IWUSR|S_IROTH); if (fd == -1) { fprintf(stderr, "shm_open() error\n"); return fd; } shm_size = sizeof(shm_struct_t); ret = ftruncate(fd, shm_size); if (ret == -1) { fprintf(stderr, "ftruncate() failed. errno=%d\n", errno); return ret; } g_shm = (shm_struct_t *)mmap(NULL, shm_size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); if (g_shm == MAP_FAILED) { fprintf(stderr, "mmap() failed\n"); return -1; } close(fd); return ret; } int main() { int ret = 0; ret = shm_init(); if (ret) { fprintf(stderr, "shm_init() failed. \n"); return ret; } while(1) { pthread_mutex_lock(&g_shm->mtx); g_shm->i++; fprintf(stdout, "i = %d, j = %d\n", g_shm->i, g_shm->j); sleep(5); pthread_mutex_unlock(&g_shm->mtx); } return ret; }
실행순서는 프로그램1->프로그램2 으로 실행했습니다.
결과는 프로그램1이60초간 sleep하는 동안에 프로그램2가 공유메모리의 변수에 접근을 못하는것을 확인하려고 하는데, 프로그램2가 접근해서 값을 변경해버리는 군요.
혹시 문제가 짐작가시는 분은 알려주세요ㅠㅠ
Forums:
흠.. 뭔가
흠.. 뭔가 이상한데요..
IPC와 thread에 대해서 실수하신 것 같네요.
pthread_*로 시작하는 모든 함수들은 한 process에서 여러 thread를 위한 것입니다. 따라서 pthread의 mutex는 한 process에서 여러 thread들 사이에 동기화를 위한 것입니다. 여러 process사이에 일어나는 동기화하고는 아무런 관련이 없습니다.
질문하신 shared memory는 여러 process 사이에 memory를 공유하기 위한 것으로, 이 process 사이에 동기화가 필요하다면 IPC에서 제공하는 동기화 기능을 써야 합니다. pipe나 message queue, 또는 semaphore가 있습니다.
요약하면, thread를 쓰지 않고 multi-process를 쓴다면 pthread_로 시작하는 함수들을 쓸 이유가 없습니다.
--
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
Korean Ver: http://www.cinsk.org/cfaqs/
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
Korean Ver: http://cinsk.github.io/cfaqs/
POSIX에 멀티프로세스간의 뮤텍스 동기화 부분이 있는 걸로 알고 있어요.
이 부분이 뮤텍스의 속성을 설정하는 부분인데. pthread_mutexattr_setpshared()함수의 2번쩨 인수로 PTHREAD_PROCESS_SHARED를 주면, 프로세스간에서 사용할 수 있다는 걸로 알고 있습니다.
솔라리스는 전부터 지원했었는데, 리눅스에서는 2.6버전에서부터 지원하는 거 같은데, 어디가 잘못된건지 잘안되네요
-_-;;;; 무식이
-_-;;;; 무식이 탄로나는 순간이군요. -_-;;;;;
먼저, _POSIX_THREAD_PROCESS_SHARED가 정의되었는지, 확인해보시기 바랍니다.
그리고 올리신 코드, 제 시스템에서는 정상적으로 되는 것 같네요. 단지, wsong님의 ntpl version이 조금 낮은게 걸리긴 합니다:
--
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
Korean Ver: http://www.cinsk.org/cfaqs/
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
Korean Ver: http://cinsk.github.io/cfaqs/
저도 궁금해서
저도 궁금해서 테스트 해봤습니다.
wsong님과 동일한 ntpl version(NPTL 2.3.4)인데,
정상적으로 lock/unlock 동작합니다.
<-_-; sleep (1) 로 변경한거 빼고는 동일합니다.>
$ ./test &
T1: i = 289, j = 0
T1: i = 290, j = 0
$ ./test1
T1: i = 291, j = 0
T2: i = 292, j = 0
T1: i = 293, j = 0
T2: i = 294, j = 0
T1: i = 295, j = 0
T2: i = 296, j = 0
T1: i = 297, j = 0
T2: i = 298, j = 0
T1: i = 299, j = 0
T2: i = 300, j = 0
T1: i = 301, j = 0
T2: i = 302, j = 0
T1: i = 303, j = 0
T2: i = 304, j = 0
T1: i = 305, j = 0
T2: i = 306, j = 0
T1: i = 307, j = 0
T2: i = 308, j = 0
T1: i = 309, j = 0
T2: i = 310, j = 0
T1: i = 311, j = 0
T2: i = 312, j = 0
음....혹시...말입니다. ^^
잘되신다니...하수의 글은 접어야 겠군효 ^^ ㅋ
============================
Stay Hungry, Stay Foolish
============================
Stay Hungry, Stay Foolish
음......위에처럼 되려면 ...
sleep 위치가 틀렸어요~~~
댓글 달기