부산IT학원/스마트컨트롤러

20140620 (시그널, 멀티쓰레드)

EHOzlO 2014. 6. 20. 10:44

85일차












--------------

시그널

--------------





--- 시그널

프로그램에게 신호를 보내 프로그램이 그에 따라 종료되거나

어떤 처리를 하게 되는데 이 신호를 시그널이라 한다. (신호가 영어로 시그널인데..)




-- 시그널 종류





1. SIGHUP(HUP) : 연결 끊기. 프로세스의 설정파일을 다시 읽는데 사용된다.

2. SIGINT(INT) : 인터럽트

3. SIGQUIOT(QUIT) : 종료

4. SIGILL(ILL) : 잘못된 명령

5. SIGTRAP(TRAP) : 트렙 추적

6. SIGIOT(IOT) : IOT 명령

7. SIGBUS(BUS) : 버스 에러

8. SIGFPE(FPE) : 고정 소수점 예외

9. SIGKILL(KILL) : 죽이기. 이 시그널은 잡히지 않는다.

10. SIGUSR1(USR1) : 사용자 정의 시그널 1

11. SIGSEGV(SEGV) : 세그멘테이션 위반

12. SIGUSR2(USR2) : 사용자 정의 시그널 2

13. SIGPIPE(PIPE) : 읽을 것이 없는 파이프에 대한 시그널

14. SIGALRM(ALRM) : 경고 클럭

15. SIGTERM(TERM) : 소프트웨어 종료 시그널, 일반적으로 kill 시그널이 전송되기 전에 전송된다.

                            잡히는 시그널이기 때문에 종료되는 것을 트랙할 수 있다.

16. SIGKFLT : 코프로세서 스택 실패

17. SIGCHLD(CHLD) : 자식 프로세스의 상태변화

18. SIGCONT(CONT) : STOP 시그널 이후 계속 진행할 때 사용

19. SIGSTOP(STOP) : 정지. 이 시그널 역시 잡을 수 없다.

20. SIGTSTP(TSTP) : 키보드에 의해 발생하는 시그널로 Ctrl+Z로 생성된다.








--- 시그널 집합

시그널 집합은 말 그대로 시그널을 원소로 하는 집합을 의미한다.

위에 시그널 종류들이 하나의 원소들이다.






--- sigemptyset

빈 시그널 집합을 생성


#include <signal.h>


int sigemptyset(sigset_t *set);


set : 생성하고자 하는 시그널 집합



리턴값

성공시 

0


실패시

-1



--- sigfillset

모든 시그널을 원소로 하는 시그널 집합을 생성.


#include <signal.h>


int sigfillset(sigset_t *set);


set : 생성하고자 하는 시그널 집합



리턴값

성공시

0


실패시

-1




--- sigaddset

시그널을 시그널 집합에 추가한다.


#include <signal.h>


int sigaddset(sigset_t *set, int signum);


set : 시그널 집합

signum : 추가하고자 하는 시그널 번호



리턴값

성공시

0


실패시

-1




--- sigdelset

시그널 집합에서 시그널을 삭제


#include <signal.h>


set : 시그널 집합

signum : 삭제하고자 하는 시그널 번호



리턴값

성공시

0


실패시

-1




--- sigismember

시그널이 시그널 집합에 속하는지 확인


#include <signal.h>


int sigismember(const sigset_t *set, int signum);


set : 시그널 집합

signum : 확인하고자 하는 시그널 번호



리턴값

성공시

속하면 1

속하지 않으면 0


실패시

-1






--- sleep

일정 시간 동안 정지


#include <unistd.h>


unsigned int sleep(unsigned int seconds);


seconds : 정저할 시간으로 단위는 초



리턴값

성공 : 남은 시간





--- signal

시그널 처리를 설정


#include <signal.h>


void (*signal(int signum, void (*sighandler)(int)) )(int);


signum : 시그널 번호

sighandler : 설정할 시그널 핸들러

SIG_IGN : 시그널을 받으면 무시한다.

SIG_DFL : 시그널을 받으면 시스템에서 기본적으로 설정한 동작을 한다.

함수 이름 : 시그널을 받으면 '함수 이름' 함수가 실행 된다.



리턴값

성공시

이전의 시그널 핸들러 포인터


실패시

-1 (SIG_ERR)








소스)



결과




처음 Ctrl + C 누르면 signalHandler() 함수가 실행어서 원래 기능을 다시 하게 되어

두번째 Ctrl + C 누르면 종료된다.














--- thread


멀티프로세스는 프로세스를 똑같이 메모리영역을 다 복사하여 실행하는 반면

멀티쓰레드는 실행될 함수단위로 복사한다.


멀티프로세스는 비용이 커지지만 부모 프로세스가 종료되어도 자식프로세스에 실행에는

큰 영향을 끼치지 않는다.

멀티쓰레드는 비용은 작아지지만 부모 프로세스가 종료될식 자식프로세스도 모두 종료된다.





--- pthread_create

쓰레드를 생성한다.


#include <pthread.h>


int pthread_create(pthread_t  *  thread, pthread_attr_t *

                   attr, void * (*start_routine)(void *), void * arg);


thread : 쓰레드 ID

attr : 속성, 주로 NULL

start_routine : 실행시킬 함수

arg : 함수 인수



리턴값

성공시

0


실패시

에러번호




예제 소스)


#include <stdio.h>
#include <pthread.h>
#include <unistd.h>

volatile unsigned int uiCnt;

void * smart1(void *);
void * smart2(void *);
void * smart3(void *);

int main()
{
        pthread_t thread1;
        pthread_t thread2;
        pthread_t thread3;

        pthread_create(&thread1, 0, smart1, 0);
        pthread_create(&thread2, 0, smart2, 0);
        pthread_create(&thread3, 0, smart3, 0);

        getchar();

        return 0;
}


void * smart1(void * vpData)
{
        while(1)
        {
                printf("1 : %u\n", uiCnt);
                sleep(1);
                ++uiCnt;
        }

        return ;
}

void * smart2(void * vpData)
{
        while(2)
        {
                printf("2 : %u\n", uiCnt);
                sleep(2);
                ++uiCnt;
        }

        return ;
}

void * smart3(void * vpData)
{
        while(3)
        {
                printf("3 : %u\n", uiCnt);
                sleep(3);
                ++uiCnt;
        }

        return ;
}




컴파일시 라이브러리를 추가해 줘야한다.

컴파일때 라이브러리 추가 명령은 gcc -o * *.c -lpthread