학습자료/리눅스 2012. 3. 13. 09:54

리눅스에서 Semaphore 사용시 주의점

최근 시스템에 문제가 있어서 디버깅을 하다가 디버거를 붙였다 나오면, 세마포어가 비정상 release 되는것처럼 보이는 희한한 버그를 발견했다.

조사해 보니 세마포어가 release되는게 아니라 sem_wait() 에서 EINTR을 받고 sem_wait() 가 -1을 리턴하는 문제였다.

일부 시그널 핸들러에 의해 이렇게 되는 경우가 있다고 하는데, 따라서 세마포어를 쓸때는 그냥 쓰지 말고 다음과 같이 wrapper 함수를 하나 만들어서 쓰는게 좋을것 같다.

void sema_wait_nointr(sem_t *sem)
{
int sema_result;

sema_result = sem_wait(sem);
while ((sema_result == -1) && (errno == EINTR))
{
sema_result = sem_wait(sem);
}
}


위 문제는 다음의 코드로 확인해 볼수 있다.

<sema_test.c>

#include <stdio.h>
#include <semaphore.h>

sem_t sema_block;

int main()
{
sem_init(&sema_block, 0, 0);

while (1)
{
int sem_result;
sem_result = sem_wait(&sema_block);
printf("Semaphore is released! : %d\n", sem_result);
perror("Semaphore error! ");
}
}

위 파일을 컴파일한후 실행 시켜보자.

$ gcc sema_test.c -l pthread
$ ./a.out &
[1] 15965
$ pstack 15965
#0 0x00b44402 in __kernel_vsyscall ()
#1 0x006f314e in sem_wait@GLIBC_2.0 () from /lib/libpthread.so.0
#2 0x0804847d in main ()
Semaphore is released! : -1
Semaphore error!: Interrupted system call


pstack 명령으로 허무하게 세마포어가 그냥 뚤려버리는것을 볼수가 있다.

혹시나 싶어 mutex 를 가지고 테스트 해보니 mutex 에서는 이런 문제가 발생하지 않는다.

* 3월 31일 추가
- 다른 child process 나 thread 에서 system() 과 같은 함수를 수행해도 (아마도 수행완료후 SIGCHLD 발행시?)
똑같은 증상이 나타나는것을 확인했다.

[출처]http://cityelf.egloos.com/9370134

'학습자료 > 리눅스' 카테고리의 다른 글

fstab[펌]  (0) 2012.06.15
리눅스 LVM[펌]  (0) 2012.06.15
[링크]Semaphore  (0) 2012.03.13
[링크]Pthread API Reference  (0) 2012.03.12
pthread 기본  (0) 2012.03.12
posted by cozyboy
: