article thumbnail image
Published 2020. 4. 27. 23:31

 

  1. Implicit Threading : 쓰레드의 스케줄링을 사용자가 하는 것이 아니라 운영체제 또는 컴파일러에게 맞기는 것이다.
  2. Thread Pool
    1. 쓰레드를 만들고 제거되는 상황에서, 쓰레드를 만드는 시간이 동작하는 시간보다 오래걸릴 수 있다.
      시스템의 동작을 보장하는 최대한의 쓰레드 수에 대한 제한이 필요하다.
    2. 쓰레드가 필요하면 Thread Pool 에서 가져오고, 다 쓰면 Thread Pool에 돌려놓는다.
    3. 쓰레드를 만들고 없에는 과정을 분리시킬 수 있다.
  3. Fork Join : 메인 쓰레드가 task를 수행할때 쓰레드를 fork로 쪼개서 수행하고, task가 끝나면 join으로 재결합해서 가져온다.
  4. OpenMP : 공유메모리를 이용한 멀티쓰레딩 프로그램 만들 때 쓰이는 프로그램
  5. Issue in Threading : fork(), exec()는 프로세스를 기준으로 만들어졌다. 그래서 Thread 처리할 때 문제가 있다.
    1. 하나의 프로세스 안에 세 개의 쓰레드가 존재하는 경우, 하나의 쓰레드가 fork()를 한다면 쓰레드 하나 짜리 프로세스를 만들어야 하는가? 아니면 쓰레드 세 개 짜리 프로세스를 만들어야 하는가?
    2. 나의 프로세스 안에 세 개의 쓰레드가 존재하는 경우, 하나의 쓰레드가 exit()을 한다면 exit()을 호출한 쓰레드만 종료시켜야 하는가? 아니면 프로세스 전체를 종료시켜야 하는가?
    3. fork() 
      1.  하나의 프로그램 내의 thread가 fork를 호출하면 모든 thread를 가지고 있는 프로세스를 만들 것인지 아니면 fork를 요청한  thread만을 복사한 프로세스를 만들 것인가의 문제
      2. pthread 에서는 fork로 불렀던 쓰레드 하나만 복사한다.
      3. UNIX 에서는 fork로 부르면 모든 쓰레드 다 복사한다. fork1 은 하나만 복사한다.
    4. exec()
      1. fork를 하여 모든 thread를 복사 했을 경우 exec을 수행하면 모든 thread들은 새로운 program으로 교체가 됨 
      2. 교체될 thread의 복사는 불필요한 작업으로 판단해여, 현재 address space가 싹 날아가고 새로 만들어진다.
  6. Signal Handling : 일반적으로 한 프로세스에 있는 쓰레드들 끼리는 Signal Handler를 공유한다.
  7. Thread Cancellation : thread의 작업이 끝나기 전에 외부에서 작업을 중지시키는 것
    1. Asynchronous Cancellation : 한 thread가 target thread를 종료시킨다. (얘가 문제)
    2. Deferred Cancellation : target thread가 주기적으로 자신이 종료되어야 되는지 확인한다. cancellation point를 확인한다.
  8. Thread Local Storage (TLS) : thread들은 프로세스의 데이터를 공유하지만, 자기만 access할 수 있는 데이터를 TLS라고 한다.
  9. Thread in Linux
    1. 리눅스에서 thread 라는 것이 없고 대신 task라고 불린다.
    2. 리눅스에서 Process 는 address space를 공유하는 task들의 집합체라고 불린다.
    3. task를 만들 때는 clone() 을 이용한다.

 

 


 

 

 

 


 

 

Implicit Threading쓰레드의 스케줄링을 사용자가 하는 것이 아니라 운영체제 또는 컴파일러에게 맞기는 것이다.


• 프로세스를 시작할 때 아예 일정한 수의 스레드를 미리 풀로 만들어 두는 것이다.
• 새 스레드를 만들어 주는것 보다 기존 스레드로 서비스 해주기 때문에 빠르다.
• 스레드 갯수를 재한해두기 때문에 스레드 대량 생산으로 인한 오류를 막을 수 있다.

  • 매번 쓰레드가 생성되는 낭비를 방지하기 위해서 사용
  • thread를 미리 준비해놓고 작업을 할 때 쉬고 있는 thread를 사용
  • 이 경우 생성시간을 줄일 수 있다. concurrent threading 가능

 

뭔가를 모아놓고 pool에다 가둬놓고 빼서 쓴다.

컴퓨터에 쓰레드를 풀의 형태로 만들어놓고 쓰레드가 필요하면 쓰레드를 하나씩 가져가서 쓰고 다시 반환한다.

쓰레드를 만드는 것과 사용하는 것을 분리해놓기 위함이다.

쓰레드를 만들고 없에는 과정을 분리시킬 수 있다.


메인쓰레드가 쓰레드를 fork로 만들어놓고 task들이 끝나면 join해서 가져오고

task를 쪼개서 수행하고 다시 join하고

Divide and Conquer 처럼 돌아간다.

더보기

 

 


 

OpenMP : 컴파일러야 ,나 이거 컴퓨터에 있는 코어만큼 parrallel 하게 돌려줘 


 

 

 

 

중요한건 아님 

IOS에서 제공하는 것이다.


 

 

  • fork하면 process의 모든 thread를 복사할건가? 아님 지금 fork를 호출한 Thread만?
  • 둘다 지원하니 잘 선택하시게
  • exec은 process를 replace한다 즉 지금 호출한 thread말고 다 죽여버리니까 조심해서 써

 

exec() 부르면 현재 address space가 싹 날아가고 새로 만들어진다.

 

우리가 프로그램을 돌리고 있을 때 쓰레드가 만약에 fork()를 부른다.

그러면 똑같은 쓰레드를 만들어야 하나? 아니면 single thread만 만들 것인가?

pthread에서는 fork()를 부르면 불렀던 애만 만든다. 아래 부분 ****

쓰레드 하나만 복사한다.

 

UNIX 에서는 fork()를 부르면 모든 쓰레드를 다 복사한다. 윗 부분

하나만 부르려면 fork1()을 사용한다. 


• 쓰레드를 signal로 하여 제어하는 것이다.
• 신호는 특정 사건에 발생되고 생성되면 프로세스에게 전달된다. 그리고 신호를 받은 프로세스는 반드시 신호를 처리해야한다.
• 위 같은 특징을 멀티 쓰레드 프로세스에 적용시키면 신호를 특정 쓰레드나 모든 쓰레드에게 전달되게 하여 적용시킬 수 있다.

  • Signal은 event 발생으로 생겨나서 프로세스에 전달되는데
  • 프로세스에 전달되서 시그널을 핸들하게 된다.
  • Sync - illegal use of memory
  • Async - 외부 event에 의해 보내짐
  • multithread는 쓰레드가 뭐를 받을 지 명시할 수 있게 되있다.

 

각각의 프로세스에서는 signal을 받으면 처리해야 하는 signal handler 가 등록되어 있다.

멀티 쓰레드에서는 일반적으로 프로세스에 있는 쓰레드들 끼리는 signal handler는 공유한다.

각 쓰레드들이 signal을 받았을 때 모두 같은 signal handler를 공유해서 동작한다.

 

signal을 멀티쓰레드에 보내면 쓰레드들 중 여유있는 아무 쓰레드 하나가 받아서 처리할 수 있다.

아니면 해당하는 쓰레드에게 처리하라고 설정할 수 있다.

 


• 쓰레드 취소는 쓰레드가 끝나기 전에 그것을 강제 종료 시키는 작업이다. 병렬로 무언가를 찾고 있을때 하나의 쓰레드가 찾으면 나머지 쓰레드는 찾을 필요가 없다.
• 취소되어야 할 스레드를 target 스레드라고 부른다.
• 비동기식 취소(Asynchronous cancellation) : 한 스레드가 목적 스레드를 즉시 강제 종료시킨다.
• 지연 취소(Deferred cancellation) : 목적 스레드가 주기적으로 자신이 강제 종료해야 하는지 검사한다. cancellation point를 확인한다. 또한 쓰레드는 자신이 취소되어도 안전하다고 판단되는 시점에서 취소 여부를 검사한다. 이 지점을 취소점(cancellation point)라고 부른다.

 

  • 쓰레드를 종료하는 두가지 방법
  1. Asynchronous cancellation : thread가 다른 하나의 thread를 선택해서 사살
  2. Deferred cancellation : 내가 죽어야 하나 계속 확인(periodically)
  • async가 문제야. 왜냐면 다른 애를 선택해서 죽이는 중에 resource가 할당 되거나 죽은지 모르고 resource를 할당하게 될 수도 있다.
  • 그래서 deferred cancellation을 보통 default로 사용합니다.
  • 그 밖에 thread-local storage 문제와 scheduler activations 문제가 있다.

 

뻘짓하는 쓰레드를 죽이려면??


• 한 프로세스에 속한 스레드들은 그 프로세스의 데이터를 모두 공유한다. 그러나 상황에 따라서는 각 스레드가 자기만 엑세스할 수 잇는 데이터를 가져야 할 필요가 있다. 이러한 데이터를 Thread-Local Storage(TLS)라고 부른다.

서로 같은 이름으로 참조를 할 수 있지만, 각 쓰레드들은 자신의 고유한 변수들을 따로 가질 수 있다.

 

 

 

 

 

 


실제 시스템에서 어떻게 쓰레드를 쓸 것인가?

리눅스는 쓰레드를 지원하고 리눅스 내에서는 쓰레드라는 것은 없고 task 라는 것으로 쓰레드를 abstract한다.

그리고 사실 리눅스에는 쓰레드라는 것이 없다.

Thread => task (리눅스 안에서는)

 

task는 address space를 공유한다.

만약 task가 address space를 공유하지 않으면 서로 다른 process이다.

 

리눅스에서 Process가 address space를 공유하고 있는 task의 집합으로 정의된다.

 

task를 만들 때는 clone() 이라는 system call로 만들 수 있다.

clone()을 할 때 옵션을 넣을 수 있다.

 

task_struct가 2개 있다.

pid가 서로 다르니까 task가 다르다고 할 수 있다.

mm_struct >> address space

files_struct >> 열려있는 파일

sighand_struct >> signal handler

 

 

'🚦 Server > Operating System' 카테고리의 다른 글

pthread  (0) 2020.04.29
fork() 와 exec()  (6) 2020.04.28
PA1: My Simple Shell  (0) 2020.04.27
08. Threads (2)  (0) 2020.04.23
07. Threads (1)  (0) 2020.04.21
복사했습니다!