[질문]프로세스간 뮤텍스동기화 에 대해서
글쓴이: 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를 주면, 프로세스간에서 사용할 수 있다는 걸로 알고 있습니다.
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);솔라리스는 전부터 지원했었는데, 리눅스에서는 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 위치가 틀렸어요~~~
댓글 달기