통신에서 close를 늦게 하고 싶을때...

shean0의 이미지

제가 하려는 의도는 간단합니다.
상황설명::
TCP통신에서 지금 아래 구현한 서버(main_server),
그리고 중간에 경유지 역활을 하는 middle_server,
그리고 client가 있습니다.
그런데 middle_server의 특징이 , 아래의 순서대로 움직입니다.
client==>요청--> middle-->요청==>main
<==응답<--middle<--응답<== main
-->socket close
<--> <--> 소켓 middle가 close
<--> main close
<========> 데이터가 많을때 main는 모두 send하고 close 하면
middle의 소켓이 끊어져.. client가 데이터를 모두 받지 못하기 때문이빈다.
목적::
1. client가 소켓을 끊으면 종료한다.
2. client가 끊지 않으면, 임의의 시간(10seconds)동안 있다가 죽느다.

결과 및 시도...
1.
아래 sleep, select가 예상과 다르게 동작하는 결과 확인은
ps -ef | grep 프로그램 :: sleep이 걸려있음 아직 안 죽었으니
부모+자식 이렇게 있어야 할 것인데...부모만 있네요.
2. 서버쪽과 client 쪽의 소스를 모두 테스트 해 본결과
(단 이때..middle은 없이 main-client 테스트 입니다)
서버가 먼저 close하는 것으로 나옵니다.
ret=close(client_socket); ==> 0 정상close :: 서버쪽 log
ret=close(socket); ==> -1 비정상close :: client log
3. sleep의 return 값분석==> 0
sleep되지 않고 바로 return 된 값. ?? 이상하죠?/
4. 아래 추가 select로 상대방이 io, 즉 소켓을 끊으면 인식하게끔 했는데..
연결을 끊지 않네요
( 이때에두 서버쪽과 client 쪽의 소스를 모두 테스트 해 본결과
단 이때..middle은 없이 main-client 테스트 입니다)
client 는 종료를 하였거든요....
그런데 select에는 아무런 변화가 없는데 (소스에 문제가 있는지)...
전체 메인 코드..

/******************************************
 tele_sok.c ver_1 sean 2002.12.1
******************************************/

#include "my_sok.h"   /*unistd.h 가 있는데*/
#include "my_lib.h"
#include <unistd.h>    /*sleep가 동작안 해서..또 넣어 봤습니다 ???? 에구*/
#define PORT_NO    5001

void ignoreThisSignal(int sig)
{
        printf("ignoreThisSignal interrupt %d\n", sig);
        /* exit(1);  */
        signal(sig, ignoreThisSignal);
}

void killedThisSignal(int sig)
{
        printf("ThisSignal interrupt is [%d]\n", sig);
        if(sig==11) { printf("my_segment fault error \n");  }
        else printf("other Error killed\n");
        exit(1);
}

int main()
{
    int server_sockfd, client_sockfd;
    int server_len, client_len;
    int optval;
    struct sockaddr_in server_address;
    struct sockaddr_in client_address;
    pid_t pid;
int Ppid;
FILE *P_fp;

    server_sockfd = socket(AF_INET, SOCK_STREAM, 0);

    optval = 1;
    setsockopt(server_sockfd, SOL_SOCKET, SO_REUSEADDR, (const void *)&optval, sizeof(optval));

    server_address.sin_family = AF_INET;
    server_address.sin_addr.s_addr = htonl(INADDR_ANY);
    server_address.sin_port = htons(PORT_NO);

    server_len = sizeof(server_address);

    if(bind(server_sockfd, (struct sockaddr *)&server_address, server_len) == -1) {
        fprintf(stderr, "bind error.\n");
        close(server_sockfd);
        exit(1);
    }
    if(listen(server_sockfd, 5) == -1) {
        fprintf(stderr, "listen error.\n");
        close(server_sockfd);
        exit(1);
    }
    printf("listening\n");
        (void)signal(SIGCHLD, SIG_IGN);
        (void)signal(SIGPIPE, killedThisSignal);  /* error return whern write to closed sockt*/
#ifdef S_SIGNAL
        (void)signal(SIGALRM, killedThisSignal);  /* timeout*/
        signal(SIGURG,  ignoreThisSignal);        /* 소켓에 긴급상황 발생*/
        signal(SIGSEGV, ignoreThisSignal);        /* 잘못된 메모리 참조*/

        signal(SIGHUP, SIG_IGN);
        signal(SIGQUIT, SIG_IGN);
        signal(SIGILL,  ignoreThisSignal);      /* 잘못된 명령어*/
        signal(SIGABRT, ignoreThisSignal);      /* 중단 시그널*/
        signal(SIGTERM, ignoreThisSignal);      /* 종료시그널*/
        signal(SIGURG,  ignoreThisSignal);  /* 소켓에 긴급상황 발생*/
        signal(SIGPOLL, ignoreThisSignal);
#endif

    while(1) {
        client_len = sizeof(client_address);
        client_sockfd = accept(server_sockfd, (struct sockaddr *)&client_address,&client_len);
        printf("accepting\n");
        if(client_sockfd == -1) continue;

        pid = fork();
        if(pid < 0) {
            fprintf(stderr, "fork error.\n");
            close(client_sockfd);
            continue;
        } else if(pid == 0) {
           int recheck;
           unsigned int ret=0;
           close(server_sockfd);
           recheck=client_sockfd;

           if(1 !=tele_sok_child(client_sockfd,&recheck) )
              fprintf(stderr,"tele_sok_child ERROR \n");
           ret=usleep(10000000);  /* 10sec*/
           /*ret=sleep(10);     동작안함..??       ret<== 0 */
           printf("sleeping[%d] \n",ret);
           ret= close(client_sockfd);
           printf("==tele_sok.c :close(client_sockfd);=ret[%d]\n",ret);
           printf("wake exit\n");

           exit(0);
        } else {
            close(client_sockfd);
            continue;
        }
    }
}

찿아보니.. 시그널을 받았을경우 sleep이 동작하지 않을수도 있다구 하는데...

다음은 select로 구현한 것입니다..
중간만 발췌하였습니다.. 나머지는 위와 같구요.

        } else if(pid == 0) {
           unsigned int ret;
           struct timeval timeout;
           int result;
           int sock_max;
           fd_set R_Set;
           fd_set E_Set;

           close(server_sockfd);

           alarm(10);
           if(1 !=tele_sok_child(client_sockfd) )
              fprintf(stderr,"tele_sok_child ERROR \n");
           sock_max=client_sockfd;
           FD_ZERO((fd_set*)&R_Set);
           FD_SET(client_sockfd,&R_Set);  /*Reading */
           FD_ZERO((fd_set*)&E_Set);
           FD_SET(client_sockfd,&E_Set);  /*Exception */

           timeout.tv_sec=15;
           timeout.tv_usec=0;  /* 15 seconds */
/*       while(1)  */
         {
           printf("seletting ==\n");
/*           result=select( sock_max+1,(fd_set *)&R_Set,NULL,&E_Set,&timeout);
 */
          result=select( sock_max+1,NULL,NULL,&E_Set,&timeout);
           printf("select result=[%s]\n",result);
           timeout.tv_sec=15;
           timeout.tv_usec=0;  /* 15 seconds */

           if(result==0)
           {
               if(FD_ISSET(client_sockfd, &R_Set) )
               {
                   printf("slect reading \n");
               }
               else if(FD_ISSET(client_sockfd, &E_Set) )
               {
                   printf("slect reading \n");
               }
               else
               {
                   printf("slect ?? \n");
               }
               ret= close(client_sockfd);
               printf("==tele_sok.c :close(client_sockfd);=ret[%d]\n",ret);
               printf("select closed first Phone \n");
               exit(0);
           }
           else
           {
               /* select의 리턴값이 0이 아니면 에러이거나 타임아웃   */
               ret= close(client_sockfd);
               printf("==tele_sok.c :close(client_sockfd);=ret[%d]\n",ret);
               exit(1);
          }
        }
        printf("alarm 0\n");
        alarm(0);

         shutdown(client_sockfd, 2);
         printf("shutdown\n");
         exit(0);
        } else {
            close(client_sockfd);
            continue;
        }

위의 코드는 alarm(10) 혹시나 계속해서 무한대기를 막기 위해서..사용.
select 리턴시 상태로그를 보고..분석하기 위한 작업.
close가 sok번호의 링크-fork햇으니깐..번호가 "1" 이 아니면
중단되지 않을경우도 있기때문에
확실하게 하기위해서 shutdown(2,sok) 사용.
이것입니다.
그런데 위의 코드에서는 select에서 무한 대기하네요 while도 아니고,
client는 종료되었는데두요(직접 client-main접속 테스트 결과)...

휴..무엇을 뺀것인가?? 아님.. 어떻게 이 원인을 분석할 수 있을까요?

펑키의 이미지

안녕하세요.

제가 올려 주신 코드는 보지 않고 그냥 하고자 하시는 목적만 읽어 보고 대충 말씀 드립니다. 이해해주세요. 헤헤~ lol

목적
1. client가 소켓을 끊으면 종료한다.
2. client가 끊지 않으면, 임의의 시간(10seconds)동안 있다가 죽느다.

client가 소켓을 끊으면 종료한다. 이것은 클라이언트/서버쪽의 소켓을 모두 종료하는것을 말씀 하시나요.? 그렇다면 SELECT에서 아주 간단합니다. 먼저 SELECT에서 유효한 분기는 다른것 다 차치하고 ACCEPT와 RECV 디스크립터 알아 내기입니다. 그런데 클라이언트가 접속을 끊으면 SELECT에서 RECV 디스크립트로 리턴하게 됩니다. 이때 RECV를 해버리면 분명 접속이 끊겼으니깐 RECV의 리턴이 0이 되게 됩니다. 이것은 클라이언트가 접속을 끊은것으로 해서 클라이언트와 서버쪽 디스크립터를 닫아줍니다. 이러면 해결이 될듯 싶습니다.

그리고 두번째

2. client가 끊지 않으면, 임의의 시간(10seconds)동안 있다가 죽느다.

이것은 제가 정확히 이해를 잘 못했지만 추측해서 대답을 해드리면 클라이언트가 접속을 한후에 어떤 통신을 하고나서(요기가 중요) 접속을 끊지 않는다면 이 질문의 요지 맞나요.? 아니면 그냥 접속후 10초가 지나가면이 질문이신가요.? 둘중에 어떤것인지 아차.. 그전에 한가지.. 클라이언트가 접속을 하면 서버쪽에 바로 접속을 맺게 되나요.? 오히려 제 질문이 많아 지내요. 하여간 1번째라고 생각을 하면

한가지 통신을 하고 나서 10초를 계산하는것은 RECV 디스크립터가 들어왔을떄 부터 타이머를 돌리시는것은 어떨까요.? 이것은 기술적인 문제보다는 어떠한 정책을 세우고 아이디어를 생각하시는 문제인것 같네요.

A <---> B <----> C

제가 사용하는 방법입니다.

A는 B에 접속하고 A가 로그인 패킷을 보내면 C에 접속하여 유효성을 검사하고 맞으면 B가 A에게 유효한 SESSION값을 주어서 앞으로 이것을 계속 패킷에 뭍혀서 보내게끔 합니다. 중간에 틀리면 막아 버립니다(사실 서버에서 막기가 좀 그렇지만)

이때 중요한것은 A가 B에게 접속후 패킷을 보내면!! 이것을 1차로 검증해서 C에 접속!!하게 됩니다. 하지만 B는 C로 부터 최초 접속후 패킷을 주고 받으면 접속을 끊어 버립니다.(C를 만든 사람이 관리하기 힘들다고 한번 패킷에 접속 한번씩 하고 바로 끊어 버리라고 하더군요. C 시스템을 보니 큐로 관리가 되어서 잘못된 패킷이 들어 가면 큐에 그냥 쌓이고 청소가 않되더군요. 바보)

하여간 이러한 개념일때는 B가 C로 부터 패킷을 받은 다음에(이때 부터) 타이머를 10초 돌리시거나 혹은 A로 부터 B가 패킷을 받은 다음에(이때 부터) 타이머를 돌리시거나 둘중에 하나를 하셔도 될것 같습니다.

단지 A의 접속을 끊어 버리는것인지 C의 접속을 끊어버리는 것인지 제가 잘 몰라서 그냥 대충 대답해 드립니다.

올리기전에 한번 더 읽어 보았는데..

<========> 데이터가 많을때 main는 모두 send하고 close 하면
middle의 소켓이 끊어져.. client가 데이터를 모두 받지 못하기 때문이빈다.

이런 문제가 있으시네요. 그런데 C가 데이터를 모두 전송하고 접속을 끊어 버리면 A도 접속이 끊기나요.? 이것은 제가 잘 모르겠는데 A는 접속을 자기가 끊어 버리지 않는 이상 끊기지 않습니다. 주요한것은 접속의 권한은 클라이언트쪽에 있게 되니깐 상관없을듯 싶습니다. 예를 들면 A/B간의 통신은 c_fd로 B/C간의 통신은 s_fd로 했을때 s_fd가 끊기게 되도 c_fd는 끊기지 않습니다.

즐거운 하루 되세요.

pynoos의 이미지

int tele_sok_child( int );

이 함수가 있으면 문제가 더 쉽게 이해될 것 같습니다.

이런류의 프로그램에서는,

1. send의 return 값 확인해야합니다. 데이터가 많은 경우, 자칫 전송하는 send buffer와 수신하는 쪽 recv buffer가 모두 찰 경우에 send 의 결과가 잘나오지 않는 경우가 있습니다. 물론 block socket에서는 큰문제가 아니겠지만요.

2. select 이 마지막 exception이라는 것은 socket이 종료되거나 reset될때
잡히는 것이 아닙니다. 종료를 감지 하려면 read set에 넣어 주셔야합니다.
될 수 있으면, 마지막 read(recv) 시에 종료여부를 확인하여 넘겨오는 것이 좋을 것 같습니다.

shean0의 이미지

소스를 요약하자면.. 일반 fork에 부모와 자식을 만들고...자식은
recv=>data
send<=data 하고 죽는다
단) client에서 close가 오면 바로 exit(0) 하고, 아니면 10초를 대기하고 죽는다. 이것을 구현하기 위해서
select를 구현하였습니다.
즉, select(); ret=recv(sok,buf,1,0);
non-blocking모드로서 recv-fd가 발생하면

Quote:
ret[1] errno[0]
ret recv[0][]
close phone connectting---2
==tele_sok.c :wait_close ret[-1]
==tele_sok.c :close(client_sockfd);=ret[0]
wake exit

이 로그는 제가 임으로 만든 client(client는 데이터를 바로 받고서 close그리고 exit합니다)의 로그입니다.

아래 소스에서..추가한 부분이 alarm(10) alarm(0) 을 넣어서..

Quote:
ret[-1] errno[4]
====================
ignoreThisSignal interrupt[ 14]
signal-SIGALRM exit
이런식으로 process를 죽였습니다.
즉, client가 close를 제대로 하지 않았을경우를 대비한 것인데요..

문제는 alarm이 각각의 child프로세스에게 모두 날라가기 때문에 .이것을 어떻게 해결해야 하는지를 알고자 합니다.
pid.sig==14 /*sig-Ararm */ 이런식으로 처리해 주고 싶은데..

#define PORT_NO    5001

int  wait_close(int sok);
void setting_signal(void);
void ThisSignal(int sig);

int mypid;
int main()
{
    int server_sockfd, client_sockfd;
    int server_len, client_len;
    int optval;
    struct sockaddr_in server_address;
    struct sockaddr_in client_address;
    pid_t pid;

    server_sockfd = socket(AF_INET, SOCK_STREAM, 0);

    optval = 1;
    setsockopt(server_sockfd, SOL_SOCKET, SO_REUSEADDR, (const void *)&optval, sizeof(optval));

    server_address.sin_family = AF_INET;
    server_address.sin_addr.s_addr = htonl(INADDR_ANY);
    server_address.sin_port = htons(PORT_NO);

    server_len = sizeof(server_address);

 mypid=getpid();
 printf("process [%d] \n",mypid);

    if(bind(server_sockfd, (struct sockaddr *)&server_address, server_len) == -1) {
        fprintf(stderr, "bind error.\n");
        close(server_sockfd);
        exit(1);
    }
    if(listen(server_sockfd, 5) == -1) {
        fprintf(stderr, "listen error.\n");
        close(server_sockfd);
        exit(1);
    }
printf("listening\n");
    setting_signal();

    while(1) {
        client_len = sizeof(client_address);
        client_sockfd = accept(server_sockfd, (struct sockaddr *)&client_address,&client_len);
printf("accepting\n");
        if(client_sockfd == -1) continue;

        pid = fork();
        if(pid < 0) {
            fprintf(stderr, "fork error.\n");
            close(client_sockfd);
            continue;
        } else if(pid == 0) {
           int ret;
           close(server_sockfd);


           mypid=getpid();
           printf("process [%d] \n",mypid);

           setting_signal();
           if(1 !=tele_sok_child(client_sockfd) )
              fprintf(stderr,"tele_sok_child ERROR \n");

           ret=wait_close(client_sockfd);
           printf("==tele_sok.c :wait_close ret[%d]\n",ret);

           ret= close(client_sockfd);
           printf("==tele_sok.c :close(client_sockfd);=ret[%d]\n",ret);
           printf("wake exit\n");

           exit(0);
        } else {
            close(client_sockfd);
            continue;
        } 
    }  
}   

void setting_signal(void)
{
        (void)signal(SIGCHLD, SIG_IGN);
        (void)signal(SIGALRM, ThisSignal);
        (void)signal(SIGSEGV, ThisSignal );     /* 잘못된 메모리 참조*/
        (void)signal(SIGALRM, ThisSignal);
        signal(SIGHUP, SIG_IGN);
        signal(SIGQUIT, SIG_IGN);

        signal(SIGILL,  ThisSignal);      /* 잘못된 명령어*/
        signal(SIGABRT, ThisSignal);      /* 중단 시그널*/
        signal(SIGSEGV, ThisSignal);      /* 잘못된 메모리 참조*/
        signal(SIGTERM, ThisSignal);      /* 종료시그널*/
        signal(SIGCONT, ThisSignal);      /* 중단시 재개*/
        signal(SIGURG,  ThisSignal);  /* 소켓에 긴급상황 발생*/
        signal(SIGPOLL, ThisSignal);
}
void ThisSignal(int sig)
{
        printf("====================\n
                ignoreThisSignal interrupt[ %d] \n", sig);
        if(sig==11) { printf("my_segment fault error \n"); }
        if(sig==14) { printf("signal-SIGALRM exit\n"); }
        signal(sig, ThisSignal);
        exit(-1);
        /* signal(sig, ignoreThisSignal);  */
}

int wait_close(int sok)
{
     int ret;
     struct timeval time_out;
     fd_set ReadSet;
     char tmp_buf[15];
     int block_loop;
     memset(tmp_buf,0x0,sizeof(tmp_buf));
/*
     FD_ZERO(&ReadSet);
     FD_SET(sok, &ReadSet);
*/
     block_loop=0;
     alarm(10);
     while(1)
     {
        memset(tmp_buf,0x0,sizeof(tmp_buf));
        time_out.tv_sec = 10;
        time_out.tv_usec = 0;

                FD_ZERO(&ReadSet);
                FD_SET(sok, &ReadSet);

           ret=wait_close(client_sockfd);
           printf("==tele_sok.c :wait_close ret[%d]\n",ret);

           ret= close(client_sockfd);
           printf("==tele_sok.c :close(client_sockfd);=ret[%d]\n",ret);
           printf("wake exit\n");

           exit(0);
        } else {
            close(client_sockfd);
            continue;
        }
    }
}   

void setting_signal(void)
{
        (void)signal(SIGCHLD, SIG_IGN);
        (void)signal(SIGALRM, ThisSignal);
        (void)signal(SIGSEGV, ThisSignal );     /* 잘못된 메모리 참조*/
        (void)signal(SIGALRM, ThisSignal);
        signal(SIGHUP, SIG_IGN);
        signal(SIGQUIT, SIG_IGN);

        signal(SIGILL,  ThisSignal);      /* 잘못된 명령어*/
        signal(SIGABRT, ThisSignal);      /* 중단 시그널*/
        signal(SIGSEGV, ThisSignal);      /* 잘못된 메모리 참조*/
        signal(SIGTERM, ThisSignal);      /* 종료시그널*/
        signal(SIGCONT, ThisSignal);      /* 중단시 재개*/
        signal(SIGURG,  ThisSignal);  /* 소켓에 긴급상황 발생*/
        signal(SIGPOLL, ThisSignal);
}
void ThisSignal(int sig)
{
        printf("====================\n
                ignoreThisSignal interrupt[ %d] \n", sig);
        if(sig==11) { printf("my_segment fault error \n"); }
        if(sig==14) { printf("signal-SIGALRM exit\n"); }
        signal(sig, ThisSignal);
        exit(-1);
        /* signal(sig, ignoreThisSignal);  */
}

int wait_close(int sok)
{
     int ret;
     struct timeval time_out;
     fd_set ReadSet;
     char tmp_buf[15];
     int block_loop;
     memset(tmp_buf,0x0,sizeof(tmp_buf));
/*
     FD_ZERO(&ReadSet);
     FD_SET(sok, &ReadSet);
*/
     block_loop=0;
     alarm(10);
     while(1)
     {
        memset(tmp_buf,0x0,sizeof(tmp_buf));
        time_out.tv_sec = 10;
        time_out.tv_usec = 0;

                FD_ZERO(&ReadSet);
                FD_SET(sok, &ReadSet);
                errno=0;
                ret = select((sok+1), &ReadSet, 0, 0, &time_out);
                printf("ret[%d] errno[%d] \n",ret,errno);
                block_loop++;
                if (ret == 0)
                {
                    printf("call time-out message\n");
                    return 1;
                }
                if (ret < 0 && errno != EINTR)
                {
                    printf("error : select \n");
                    return -1;
                }

                if (FD_ISSET(sok, &ReadSet))
                {
                    ret=recv(sok,tmp_buf,12,0);
                    printf("ret recv[%d][%s]\n",ret,tmp_buf);
                    if(ret>0)
                    {
                         printf("not yet close phone connectting---1\n");
                    }
                    else if(ret==0)
                    {
                         printf("close phone connectting---2\n");
                         break;
                    }
                    else
                    {
                         printf("closed phone connet \n");
                         return 1;
                    }
                }
                else if(block_loop > 3)
                {
                    printf("Error no limitted loop\n");
                    break;
                }
                else ;

                ret=sleep(2);
                printf("sleep ret[%d]\n",ret);

    }
    alarm(0);
    return -1;
}


언제나 즐프를 꿈꾸며~

pynoos의 이미지

alarm을 fork다음에 하거나
fork한다음에 alarm(0)를 하는 것은 어떨까합니다.

shean0의 이미지

네 말씀 대로 fork다음에 alarm(0)을 넣는것두 생각해 보았는데요..
그래구 이것은
fork --> child 1
child 1 child_2 child_3 child_4 이렇게 있을때..
어느 child 에서든 alarm 시그널을 날리면..
모든 프로스스에게 날가 가는것 아닌가요?/

그래서 다른 child도 죽고요???

제가 잘 못 생각한건가요???
제가 하고자 하는것은 자신의 alarm시그널을 받았을 경우에만 죽고,
다른 child는 다른 child가 보낸것은 무시..이런것이거든요?

누가 보냈는지..즉 pid를 가지고 어떻게 할 수 있지 않을까 생각하는데?영..모르겠네요.

Quote:
아래 소스에서..추가한 부분이 alarm(10) alarm(0) 을 넣어서..
인용:
ret[-1] errno[4]
====================
ignoreThisSignal interrupt[ 14]
signal-SIGALRM exit
이런식으로 process를 죽였습니다.
즉, client가 close를 제대로 하지 않았을경우를 대비한 것인데요..

문제는 alarm이 각각의 child프로세스에게 모두 날라가기 때문에 .이것을 어떻게 해결해야 하는지를 알고자 합니다.
pid.sig==14 /*sig-Ararm */ 이런식으로 처리해 주고 싶은데..

언제나 즐프를 꿈꾸며~

pynoos의 이미지

SIGALARM은 signal등록을 안한 default action이 죽는 것으로 되어있을거구요...
signal을 강제로 보낼경우 다른 process (child라 할지라도)로 전파되지
않을 것입니다.

대개의 경우 signal이 전파되는 경우, session leader에게 SIGINT 같은 것이
전달될경우 전파되는것으로 알고 있습니다.

다른 뭔가가 작동하는 것같아 보이는 군요.

sleep도 하부로 SIGALARM을 쓰는데... 만일 그렇게 되면.. 무슨 이상한일이
일어나겠지요? ^^

shean0의 이미지

네 알겠습니다.
즉 결론은 SIGALARM을 등록해서 ...처리했구요.
그런데 제가 테스트 중에

ret=sleep(10); printf("ret[%d]",ret); 
ret[0] 

으로 나오는 결과에세 man을 찿아보니 시그널이 날라올경우에 이런경우가 있다구 하던군요...

제가 여기에서 많은 고민이 시작되었구요....

언제나 조언을 해주신 모든 분께 감사를 ~

pynoos wrote:
SIGALARM은 signal등록을 안한 default action이 죽는 것으로 되어있을거구요...
signal을 강제로 보낼경우 다른 process (child라 할지라도)로 전파되지
않을 것입니다.

대개의 경우 signal이 전파되는 경우, session leader에게 SIGINT 같은 것이
전달될경우 전파되는것으로 알고 있습니다.

다른 뭔가가 작동하는 것같아 보이는 군요.

sleep도 하부로 SIGALARM을 쓰는데... 만일 그렇게 되면.. 무슨 이상한일이
일어나겠지요? ^^

언제나 즐프를 꿈꾸며~

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.