Sending a Signal to Thread
멀티 쓰레드 환경에서 시그널을 보내는 방법과 이를 다루는 코드 예제를 알아본다.
기본 환경
아래는 간단한 멀티 쓰레드 환경을 구현한 코드이다.
세 개의 쓰레드가 각각 thread1, thread2, thread3 함수를 실행하며, 각 함수는 무한 루프 내에서 메시지를 출력한다.
void* thread1(void *data){
while(1){
printf("thread 1\n");
sleep(2);
}
}
void* thread2(void *data){
while(1){
printf("thread 2\n");
sleep(2);
}
}
void* thread3(void *data){
while(1){
printf("thread 3\n");
sleep(2);
}
}
메인 쓰레드가 종료될 때의 동작
메인 쓰레드가 종료되면 나머지 쓰레드 역시 종료된다. kill()을 이용해 SIGTERM 시그널을 보내는 예제는 다음과 같다.
int main(){
pthread_t tid[3];
int thr_ret;
thr_ret = pthread_create(&tid[0], NULL, thread1, NULL);
thr_ret = pthread_create(&tid[1], NULL, thread2, NULL);
thr_ret = pthread_create(&tid[2], NULL, thread3, NULL);
sleep(3);
kill(getpid(), SIGTERM);
printf("Main return\n");
return 0;
}
결과:
- 메인 쓰레드가 SIGTERM을 받고 종료되며, 모든 쓰레드가 함께 종료된다.
메인 쓰레드에서 시그널 핸들러 실행
시그널 핸들러는 기본적으로 메인 쓰레드에서만 실행된다. 다음은 SIGALRM 시그널을 처리하는 핸들러를 등록한 코드이다.
void sig_handler(int signo) {
printf("Signal %d handled in main thread\n", signo);
}
int main() {
pthread_t tid[3];
int thr_ret;
signal(SIGALRM, sig_handler); // 시그널 핸들러 등록
thr_ret = pthread_create(&tid[0], NULL, thread1, NULL);
thr_ret = pthread_create(&tid[1], NULL, thread2, NULL);
thr_ret = pthread_create(&tid[2], NULL, thread3, NULL);
sleep(3);
kill(getpid(), SIGALRM); // SIGALRM 시그널 전송
printf("Main return\n");
return 0;
}
결과:
- SIGALRM 시그널을 처리하는 핸들러가 호출되며, 이는 메인 쓰레드에서 실행된다.
특정 쓰레드에 시그널 보내기
pthread_kill() 함수는 특정 쓰레드 ID에 시그널을 보낼 수 있다. 하지만 SIGTERM 또는 SIGKILL은 모든 쓰레드를 종료시킨다는 점에 유의해야 한다.
int main() {
pthread_t tid[3];
int thr_ret;
signal(SIGALRM, sig_handler); // 시그널 핸들러 등록
thr_ret = pthread_create(&tid[0], NULL, thread1, NULL);
thr_ret = pthread_create(&tid[1], NULL, thread2, NULL);
thr_ret = pthread_create(&tid[2], NULL, thread3, NULL);
sleep(3);
pthread_kill(tid[0], SIGALRM); // 특정 쓰레드(tid[0])에 SIGALRM 전송
// pthread_kill(tid[1], SIGALRM);
// pthread_kill(tid[2], SIGALRM);
sleep(10);
printf("Main return\n");
return 0;
}
결과:
- pthread_kill()로 지정된 쓰레드에 시그널을 전달한다.
- 전달된 시그널은 해당 쓰레드의 시그널 핸들러에서 처리된다.
추가 설명
- 시그널 핸들링 동작
- POSIX 표준에 따르면, 시그널은 특정 쓰레드에 직접 전달되거나, 해당 쓰레드가 시그널 핸들러를 실행하게 된다.
- SIGTERM과 SIGKILL은 프로세스 전체를 대상으로 하므로 모든 쓰레드를 종료시킨다.
- pthread_kill()와 kill() 차이
- kill()은 프로세스 전체에 시그널을 보낸다.
- pthread_kill()은 특정 쓰레드에 시그널을 전달할 수 있다.
반응형
'CS 지식 > 시스템 프로그래밍' 카테고리의 다른 글
[C언어] Deadlock(교착상태) 원인과 해결법 (0) | 2025.01.28 |
---|---|
[C언어] pthread 라이브러리를 이용한 스레드 동기화 (0) | 2025.01.28 |
[C언어] 스레드의 개념과 pthread 라이브러리 (0) | 2025.01.28 |
[C언어] 프로세스 간 통신 (IPC) (0) | 2024.10.18 |
Assembly(어쌤블리어)의 기초 (0) | 2024.10.18 |
댓글