CS/OS 수업 / / 2021. 4. 5. 02:40

운영체제 6주차


 

 

Pthread는 스레드 관리에 관련된 POSIX(UNIX 계열 라이브러리 표준) 표준 라이브러리 API이다(참고)
  • pthread_t(int): 스레드 id
  • pthread_attr_t(struct): 스레드 속성 정보 저장 구조체
  • pthread_attr_init(&attr): attr 값 초기화(라이브러리 함수)
  • pthread_create(&tid, &attr, run, (void*)count): 스레드 번호 부여, 스레드 구조체에 스레드 정보 저장(거의 사용할 일 없음), 스레드를 실행할 함수, 함수에 전달할 매개변수
  • C에서는 개발자가 스레드 함수를 명시적으로 실행하지 않더라도 pthread_create(&tid, &attr, run, (void*)count)함수 실행이 완료되면 스레드가 만들어져서 자동으로 run 함수가 실행된다. 즉, 스레드가 생성되면 위 템플릿 기준으로 main 함수가 실행되는 스레드와 run 함수가 실행되는 스레드가 존재하므로 총 2개의 실행 흐름이 존재한다.
  • run 함수가 종료되면 return해서 다른 주소 위치로 돌아가는 게 아니라 그냥 끝난다.
  • pthread_join(tid, NULL): 메인 스레드가 서브 스레드가 끝날 때까지 기다린다. 즉, printf("sum = %d \n", sum); 은 실행되지 않고 서브 스레드가 종료되야 실행된다. 이렇게 하면 별도의 스레드를 사용한 의미가 없어진다.

 

프로세스가 생성되면 OS 메모리 영역에 PCB가 생성되고, CPU가 할당되고(CPU의 레지스터가 프로세스의 주소 값을 가리킨다). pthread_create()(라이브러리 함수, 시스템 콜 아님)을 호출하면 함수 내부에서 clone() 이라는 시스템 콜을 호출한다. clone을 호출하면 OS가 스레드를 생성(TCB, Thread Control Block)한다. 여기서 이해해야 할 부분은 PC 레지스터의 동작 과정이다. pthread_create() 함수가 실행되고 TCB가 생성되고 run 함수가 실행된다. run 함수를 실행하기 위해 PC는 run 함수의 주소 값을 담을 것이다. 그런데 run 함수가 실행되는 스레드와 별개로 main 함수가 실행되는 스레드도 계속 실행돼야 하는데 PC 레지스터가 run 함수 쪽으로 이동했다면 main 함수의 다음 실행 명령은 어떻게 찾아갈까? 정답은 한 프로세스 내에서 여러 개의 스레드가 있다면 동시에 여러 개의 스레드를 실행하기 위해서(실제로 동시에 실행되는 건 아니다) Context Switching이 발생한다. Context Switching을 실시간으로 하기 위해서 아까 스레드가 생성되면서 같이 생성된 TCB에 스레드 관련 정보(레지스터 저장 값)를 저장한다. 즉 프로세스 내에서 스레드 단위로 Context Swithcing이 발생한다!!

 

만약 CPU가 두 개 이상인 환경(멀티 프로세서)이라면 두 개의 스레드는 어떻게 실행될까?

단일 프로세서 환경일 때: OS 메모리 영역에 생성된 PCB는 다른 PCB와 Linked List로 연결돼서 관리되고 하나의 프로세스에 생성된 여러 개의 스레드 정보를 담고 있는 TCB들은 PCB와 Linked List로 연결돼서 관리된다. main 함수와 run 함수는 timer의 설정 시간(10~100ms)마다 interrupt가 발생해서 스레드 단위로 Context Switching이 발생한다. Context Switcing이 발생하면 레지스터에 저장된 main 함수의 정보는 TCB에 저장되고, run 함수 스레드 관련 정보를 가지고 있는 TCB 값을 레지스터에 저장해 실행 준비를 한다.

 

멀티 프로세서 환경일 때: pthread_create()가 실행되면서 스레드가 생성되면 1번 cpu는 그대로 main 함수를 실행하고, 2번 cpu에 run 함수 관련 TCB 정보를 2번 cpu 레지스터에 저장한 후 실행한다. 멀티 프로세서 환경에서는 스레드 간 Context Switcing을 할 필요 없다.

프로세스 내 스레드는 프로세스의 PCB난 code, data, files을 공유하는 반면, stack(함수의 지역변수 저장 주소값)이나 레지스터는 각자 TCB에 저장해서 관리된다.

 

스레드의 장점

 

 

  • 사용자 스레드
    • 스레드 라이브러리에서 스레드를 관리하며 응용 프로그램에게 스레드 생성 등의 관련 함수를 제공
    • 예: POSIX > Pthread, Mach > C-thread, Solaris > UI-thread

 

  • 커널 스레드
    • 스레드를 커널에서 직접 지원한다. 즉, 운영체제가 스레드 생성 등의 스레드 관리를 위한 시스템 콜을 제공한다
    • 커널 스레드를 지원하는 운영체제 예
      • Windows XP/2000: 시스템 콜(PsCreateSystemThread)
      • Linux: Clone()
      • Solaris
      • Mac OS X

다중 스레딩 모델

  • 사용자 수준의 스레드 라이브러리와 커널 스레드의 매핑(결합)한 모델
    • One-to-One model (1:1)
      • 각 사용자 수준 스레드 하나가 하나의 커널 스레드에 대응됨
      • 한 스레드가 시스템 콜을 호출하여 중지 상태(e.g. IO 등)가 되었을 때 다른 스레드가 실행될 수 있다.
      • 여러 스레드들은 다중 프로세서에서 병렬로 동시에 실행할 수 있다
      • 각 스레드마다 커널 스레드를 만들어야 하므로 커널에 오버헤드가 된다. 따라서 커널(운영체제)은 생성할 수 있는 스레드 개수를 제한하여 오버헤드를 제한한다. 사용자 스레드 - 커널 스레드의 1대 1 생성에 대한 오버헤드 때문에 one-to-one의 장점에도 불구하고 다른 모델을 사용한다.
      • 프로세스가 pthread_create 호출→ pthread_create가 시스템 콜인 clone 호출

    • Many-to-Many model (N:1)
      • 여러 개의 사용자 수준 스레드가 하나의 커널 스레드에 대응.
      • 사용자 수준의 스레드 라이브러리에서 스레드를 관리.
      • 처음 pthread_create 때는 clone 시스템 콜을 호출하지만, 두 번째 pthread_create부터는 clone을 호출하지 않고 Library에서 관리한다. 사용자 스레드가 여러 개가 있지만 커널 스레드는 한 개밖에 없으므로 여러 개의 스레드를 Context Switching을 통해 번갈아 실행 한다.
      • 한 스레드가 시스템 호출을 하면, 전체 스레드가 중지 상태가 됨
      • 스레드들을 다중 프로세서 환경에서 TCB가 하나밖에 생성이 안 되기 때문에 각 프로세서들에 스레드를 할당해서 실행할 수 없다.
      • Many-to-One modeld은 스레드 관리가 User Mode에서 이루어지기 때문에 처리 속도가 빠르지만 하나의 스레드가 블록되면 프로세스가 블록된다.
      • 예: Solaris Green Threads, GNU Portable Threads
    • Many-to-Many model (M:N)
    • 1대1로 커널 스레드가 생성되지 않기 때문에 커널 오버헤드를 어느 정도 줄일 수 있다
    • 하나의 커널 스레드가 중단이 돼도, 다른 TCB가 있기 대문에 병렬로 실행될 수 있다.
    • 멀티 프로세서 환경에서도 실행 가능
    • 여러 가지 모델이 나온 이유는 메모리 비용 때문이지만, 현재에는 메모리 비용도 많이 싸지고 성능도 좋아졌기 때문에, 커널의 오버헤드가 큰 문제가 되지 않기 때문에 One-to-One 모델을 사용해도 큰 문제가 없을 듯하다.

  • (참고)Solaris에서는 3가지 모델을 전부 지원한다.

 

 

'CS > OS 수업' 카테고리의 다른 글

운영체제 8주차  (0) 2021.04.20
운영체제 7주차  (0) 2021.04.14
운영체제 4주차  (0) 2021.03.22
운영체제 2주차  (0) 2021.03.15
운영체제 3주차  (0) 2021.03.15
  • 네이버 블로그 공유
  • 네이버 밴드 공유
  • 페이스북 공유
  • 카카오스토리 공유