솔라리스에서의 시그널 함수에 대해
글쓴이: ddoman / 작성시간: 금, 2004/03/05 - 2:37오후
동작 환경은 솔라리스 8 sparc 입니다.
아래 코드의 간단한 tcp server를 만들었습니다.
void sig_chld( int signo )
{
pid_t pid;
int stat;
while( ( pid = waitpid( -1, &stat, WNOHANG ) ) > 0 )
printf( "child %d terminated\n", pid );
;
// signal( SIGCHLD, sig_chld );
return;
}
int main( int argc, char* argv[] )
{
int listenfd, connfd;
pid_t childpid;
socklen_t clilen;
struct sockaddr_in cliaddr, servaddr;
listenfd = socket( AF_INET, SOCK_STREAM, 0 );
bzero( &servaddr, sizeof( servaddr ) );
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl( INADDR_ANY );
servaddr.sin_port = htons( 9978 );
bind( listenfd, (struct sockaddr*)&servaddr, sizeof( servaddr ) );
listen( listenfd, 1024 );
signal( SIGCHLD, sig_chld );
for( ; ; )
{
clilen = sizeof( cliaddr );
connfd = accept( listenfd, (struct sockaddr*)&cliaddr, &clilen );
if( (childpid = fork()) == 0 )
{
close( listenfd );
printf( "connected from client!\n" );
exit(0);
}
close( connfd );
}
}
다음은 클라이언트..
int main( int argc, char* argv[] )
{
int sockfd;
struct sockaddr_in servaddr;
if( argc != 2 )
{
printf( "usage : client IP_ADDR\n" );
exit(0);
}
sockfd = socket( AF_INET, SOCK_STREAM, 0 );
bzero( &servaddr, sizeof( servaddr ) );
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons( 9978 );
inet_pton( AF_INET, argv[1], &servaddr.sin_addr );
connect( sockfd, (struct sockaddr*)&servaddr, sizeof( servaddr ) );
}
평범한 tcp server/client 예제입니다만,
이상하게 sigchild signal이 정상적으로 오지않습니다.
server를 띄어놓고 client로 접속을 하면
첫번째 연결로 생성된 child process는 죽으면서 sig_chld핸들러가
실행이 됩니다만,
두번째 연결부터는 child가 죽더라도 sig_child 핸들러가 실행이
안되면서 좀비프로세스로 남습니다.
마치 한번 시그널 핸들러가 불리고 시그널 핸들러설정이 풀리는거 같아
sig_chld함수안에서 다시 signal( SIGCHLD, sig_chld );
를 호출 해주면 의도한대로 계속 계속 시그널이 잘 옵니다.(주석처리한부분)
리눅스에서 같은 코드로 컴파일하면
굳이 signal함수를 핸들러안에서 다시 호출해주지 않아도
계속 계속 잘 옵니다만, 솔라리스 8에서는 안되는 이유가 뭔가요?
아시는분 계시면 조언 부탁드립니다.
Forums:


유닉스 계열에 따라 조금 동작의 차이가 있기는 한데, 이미 해보신바와 같
유닉스 계열에 따라 조금 동작의 차이가 있기는 한데, 이미 해보신바와 같이 주석 처리하신 부분을 다시 되살리시는것이 정답입니다.
sigaction도 한번 고려해 보심이...
sigaction도 한번 고려해 보심이...
signal 대신에 sigset 함수를 사용하셔야 될 것 같네요.
signal 대신에 sigset 함수를 사용하셔야 될 것 같네요.
솔라리스는 특이하게 signal 함수는 시그널 처리 후, 다시 디폴트 핸들러로 다시 복귀시킵니다.
리눅스에서 같은 동작을 원하시면 sigset 함수를 쓰셔야 합니다.
아니면 sigaction 함수를 사용하셔서...
---------------------------------
< ACK and you shall receive. >
< ACK and you shall receive. >
댓글 달기