본문 바로가기
Study/운영체제

4. Threads - Threading issues

by 이미뇨 2023. 4. 12.
  • fork() and exec()
    • fork() 시스템 호출은 현재 실행 중인 프로세스를 복제하여 자식 프로세스를 생성
      • 자식 프로세스는 부모 프로세스의 모든 자원을 상속
    • exec() 호출은 현재 프로세스를 다른 프로그램으로 대체
  • Cancellation : 스레드를 즉시 종료시키는 기능
    • 비동기식 I/O 작업에서 사용
    • 일반적으로 스레드를 종료하기 위해 pthread_cancel() 함수를 사용
  • Signal handling
    • 프로세스 또는 스레드가 다른 프로세스 또는 운영 체제로부터 수신하는 메시지
  • Thread-local storage
    • 스레드별로 고유한 데이터를 저장하기 위한 메커니즘
    • 스레드 간에 공유할 필요가 없는 데이터를 저장하고 검색할 수 있음
  • Scheduler activation (already covered)
    • 스레드 실행에 대한 운영 체제의 개입을 줄이는 기술
    • 스레드를 일시 중지하고 다른 스레드로 전환하기 위해 운영 체제에 대한 호출을 줄일 수 있음
    • upcall 인터페이스

1. fork() and exec()

  • 멀티스레드 프로세스의 fork()
    • - 프로세스의 모든 스레드를 복제하시겠습니까?
    • - 해당 스레드만 복제하시겠습니까?
    • -> UNIX는 두 가지 버전의 fork를 지원
      • fork(), fork1()
  • 멀티스레드 프로세스의 exec() : 전체 프로세스 교체 (하나만 바꿔치기가 안된다.)

2. Cancellation

스레드(대상 스레드)가 완료되기 전에 종료

* Problem with thread cancellation : 스레드가 리소스를 다른 스레드와 공유

  • cf. 프로세스에는 자체 리소스가 있습니다.
    → 스레드는 다른 스레드와 공유된 데이터를 업데이트하는 동안 취소할 수 있음

Setting thread cancellation type

pthread_setcanceltype 함수는 취소 유형을 설정

pthread_t pthread_setcanceltype(int type, int *oldtype);
  • Asynchronous cancellation(비동기 취소)
    • (PTHREAD_CANCEL_ASYNCHRONOUS)
    • 스레드가 무엇을 하고 있든지 즉시 스레드를 종료
  • Deferred cancellation(지연 취소)
    • (PTHREAD_CANCEL_DEFERRED)
    • 대상 스레드가 주기적으로 취소되어야 하는지 여부를 확인
    • pthread_testcancel() 함수를 사용하여 확인
    • 지연 취소는 비동기 취소보다 안전

 

Enabling/disabling thread cancelation

pthread_t pthread_setcancelstate(int state, int *oldstate);
  • 호출하는 스레드의 현재 취소 상태를 지정하고, 예전 취소 상태를 포인터 oldstate에 복사
  • 죽으라는 명령을 받았을때 죽을수 있는가 없는가 확인
  • 취소 상태는 PTHREAD_CANCEL_DISABLE 또는 PTHREAD_CANCEL_ENABLE로 지정할 수 있음
    • PTHREAD_CANCEL_DISABLE: 취소는 활성화되지 않은 채 대기 상태로 남아 있음 (계속 돌겠다!)
    • PTHREAD_CANCEL_ENABLE로 : 취소 활성화 (죽임)

3. Signal Handling

Signal : UNIX에서 프로세스에게 특정 이벤트가 발생했음을 알리기 위해 제공되는 메커니즘

  • Signal은 여러 소스에서 생성될 수 있으며, 프로세스에 전달되어 처리된다.
  • 처리는 기본 신호 핸들러(커널) 또는 사용자 정의 신호 핸들러를 통해 이루어진다.
  • Signal은 Unix 및 기타 POSIX 호환 운영 체제에서 사용되는 IPC(Inter-Process Communication)의 한 형태
  • 비동기식 알림으로 프로세스에 이벤트 발생을 알리는 역할

Types of signal

  • Synchronous : 동일한 프로세스의 신호 (Ex) illegal memory access, division by 0)
  • Asynchronous: 외부 소스로부터의 신호 ( Ex) -C)

man -S2 signal

man -S2 signal

: UNIX 계열 운영체제에서 시그널 처리와 관련된 시스템 콜(signal handling system calls)에 대한 매뉴얼 페이지를 보여줌

 

Installing Signal Handler

/* Defining signal handler */
typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);

/* Example */
#include <signal.h>
#include <unistd.h>

void sig_handler(int signo);

// press CTRL-\ to terminate this program
int main()
{
    int i = 0;
    signal(SIGINT, (void *)sig_handler);
    while(1){
        printf("%d\n", i++);
        sleep(1);
    }
    return 1;
}

void sig_handler(int signo)
{
    printf("SIGINT was received!\n");
}

 

Question : 신호를 어느 스레드로 전달해야 하는가?

Possible options:

  • 신호가 적용되는 스레드에
  • 프로세스의 모든 스레드에
  • 프로세스의 특정 스레드에
  • 모든 신호를 수신할 특정 스레드 할당 (신호 유형에 따라 다름)

Another: 신호를 전달할 스레드 지정 ( Ex) pthread_kill(tid, signal) in POSIX - 시그널을 특정 스레드로 보내라.)

 

4. Thread-Local Storage

  • 하나의 프로세스 내에서 생성된 모든 스레드는 global variables(전역 변수)를 공유
  • 때로는 스레드 간 공유할 필요가 없는 데이터가 필요
  • 스레드 지역 저장소(Thread Local Storage, TLS) : 스레드별로 별도의 저장소

Thread-Local Storage in pthread

Thread-local storage (TLS): 각 스레드가 데이터의 자체 복사본을 가질 수 있도록 한다.

EX)

__thread int tls;  // 각 스레드는 자체적으로 'int tls' 변수를 가지게 된다

지역 변수와는 다르다.

  • 지역 변수는 단일 함수 호출에서만 볼 수 있지만, TLS는 함수 호출 간에도 볼 수 있다

정적 데이터와 유사

  • TLS는 각 스레드에 대해 고유

스레드 풀을 사용할 때와 같이 스레드 생성 프로세스를 제어할 수 없는 경우 유용

 

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

#define THREADS 3

__thread int tls;
int global;

void *func(void *arg)
{
    int num = (int) arg;
    tls = num;
    global = num;
    sleep(1);
    printf("Thread = %d tls = %d global = %d\n", num, tls, global);
}

int main()
{
    int ret;
    pthread_t thread[THREADS];
    int num;
    
    for(num = 0; num < THREADS; num++){
        ret = pthread_create(&thread[num], NULL, &func,(void *)num);
        
        if(ret){
            printf("error pthread_create\n");
            exit(1);
        }
    }
    
    for(num = 0; num < THREADS; num++){
        ret = pthread_join(thread[num], NULL);
        if(ret){
            printf("error pthread_join\n");
            exit(1);
        }
    }
    return 0;
}

'Study > 운영체제' 카테고리의 다른 글

4. Threads - Thread libraries  (0) 2023.04.12
4. Threads - Multithreading models  (0) 2023.04.12
4. Threads - Overview  (0) 2023.04.12
3. Processes - Example of IPC system  (0) 2023.04.11
3. Processes - Inter-process communication  (0) 2023.04.11