1 분 소요

multi-threaded Program

single thread 는 프로세스와 매우 비슷한 형태를 가집니다. 각각의 thread 들은 고유의 Program Counter 와 레지스터들을 보유하고 있습니다. 그리고 각 스레드들은 별도의 stack 을 가지고 있습니다. 한 프로세스 안에 있는 thread 들은 address space 를 공유하고 같은 data에 접근할 수 있습니다.

  • heap 영역의 경우 race condition 을 방지하기 위해 메모리 라이브러리가 존재합니다. 그러므로 각 thread 들이 공유할 수 있습니다.
  • stack 영역의 경우 race conditon 을 방지하고자 하는 것이 아니라 별도의 context 를 분리하기 위함입니다.

race condition 은 밑에서 다루도록 하겠습니다

context switch

Thread 들은 Thread control block (TCB) 으로 관리합니다. 같은 프로세스 내 thread 의 context switch 경우 address space 는 유지합니다. 다만, 다른 프로세스의 thread 로 context switch 할 경우 address space 를 변경합니다.

why use Threads?

  • Parallelism : multiple CPUs
  • Avoiding blocking : Slow I/O 를 방지합니다. 한개의 thread 가 blocked waiting for I/O 상태가 되었을 때 CPU scheduler 는 다른 threads 로 switch 해줍니다.

race condition

race condition이란 두 개 이상의 프로세스가 공통 자원을 병행적으로(concurrently) 읽거나 쓰는 동작을 할 때, 공용 데이터에 대한 접근이 어떤 순서에 따라 이루어졌는지에 따라 (예를들면 context switch 등이 있습니다.) 그 실행 결과가 같지 않고 달라지는 상황을 말한다. 이를 해결하기 윙해 Critical Section 이 존재합니다.

race condition 해결책

  • Critical Section : 공유되는 자원들을 접근하는 것입니다. 반드시 하나의 스레드가 실행되어야 합니다.
    • Mutual exclusion : critical section 안에 하나의 스레드만 실행되도록 guarantee 해줍니다.
    • atomic : instruction 중간에 interrupt 가 발생 시 instruction 자체를 아얘 실행을 하지 않거나 혹은 해당 instruction 이 끝날 때까지 interrupt 를 처리하지 않습니다.

How to support synchronization

  • 하드웨어가 atomic instruction 을 제공합니다.
  • 운영체제가 더 복잡하고 일반적인 동기화를 시스템콜 형태로 제공합니다.

운영체제가 제공하는 Mutex

  • critical section 에 들어가기 전에 pthread_mutex_lock 호출
  • critical section 에서 벗어나면 pthread_mutex_unlock 호출
  • static 혹은 Dynamic 하게 mutex 를 초기화 해주고 Destroy 해줍니다.

운영체제가 제공하는 Condition Variables

Condition Variable은 특정 조건을 만족하기를 기다리는 변수라는 의미입니다. 따라서 이를 이용하여 주로 thread 간의 신호 전달을 위해 사용합니다. 하나의 thread가 waiting 중이면 조건을 만족한 thread에서 변수를 바꾸고 signaling을 통해 깨우는 방식입니다.

  • pthread_cond_wait
  • pthread_cond_signal
  • wait와 signal 내부적으로 unlock()과 lock()이 각각 앞 뒤로 있기 때문에 외부를 lock()과 unlock()으로 감싸야 합니다.

Compiling

  • #include
  • prompt> gcc -o main main.c -Wall -pthraed

업데이트: