Thread
#스레드의 개수는 많으면 많을수록 좋은걸까?
아니다. CPU가 스레드잡을 돌아가면서 처리하기 위해서는 컨텍스트스위칭이 필요한데, OS의 영역이므로 부하가 많이 발생한다. 따라서 무조건 많다고 좋은것은 아니다.
#스레드 개수 < CPU 코어개수 어떤일이 일어날까?
스레드를 할당받지 못한 CPU코어는 놀게된다.
#반대로 스레드 개수 > CPU 코어개수 어떤일이 일어날까?
위에서 언급했던것처럼, CPU를 할당받지 못한 스레드잡을 번갈아가며 실행하기 위해 컨텍스트스위칭이 일어나는데 OS의 영역이기 때문에 부하가 많이 발생한다.
#외부 디바이스 연산이 CPU보다 느려서 발생하는 문제
외부 디바이스가 연산을 하는동안 CPU는 놀게된다. 따라서 노는동안 다른 일을 처리하도록 스레드를 더 배정하도록 한다.
#이벤트
잠자는 스레드를 깨우는 도구, 스레드간 소통하며 일을 처리할때 유용하다.
예를들어 스레드1이 일을 끝나고 스레드2에게 이사실을 알려준다던지~
- RESET 0: 이벤트 발생안함
- SET 1: 이벤트가 발생했다.
- 자동이벤트: 이벤트 상태값이 1이 되었을때(이벤트가 발생했을때) wating중인 스레드를 깨운후 이벤트 상태값을 자동으로 RESET으로 변경한다, 그러니까 자동으로 이벤트 플래그를 내려준다.
- 수동 이벤트: 수동으로 RESET 해야한다. 그 전까지는 모든 이벤트를 기다리는 스레드들이 깨어난다.
#세마포어
뮤텍스나 임계영역은 오로지 스레드 1개만 자원액세스가 가능하다.
하지만 세마포어는 자원에 접근할 수 있는 스레드의 개수를 지정 가능하다.
세마포어는 최초에 상태값을 가지고 있으며, 이는 최대액세스 가능한 스레드의 개수이다.
1) 예를들어 3개의 스레드가 액세스 가능하다고 설정한다면 초기값은 3이고,
2) 스레드가 요청하면 1 감소한다. 그리고 자원을 액세스 할수있게 된다.
3) 자원 액세스가 끝나면 1 증가한다. 그렇다면 다른 스레드도 사용할 수 있게되겠지.
4) 이벤트와 다른점은 이벤트는 마치 플래그변수마냥 0:발생안함 1:발생함 이지만, 세마포어는 그 이상의 값을 가진다는것이지.
예를들어 두 스레드간에 공유중인 큐가 있다고 하자. 먼저 이벤트 사용을 예를 들어보자.
- 스레드A: 큐에서 항목을 꺼내는 역할을 한다.
- 스레드B: 외부에서 데이터가 들어올때까지 대기하다가 데이터가 들어오면 큐에 데이터를 넣고 이벤트를 SET하여 스레드A에게 알린다.
계획대로라면 스레드 A가 큐에 데이터를 적재하고 이벤트를 SET하고 스레드 B가 깨어나 큐에서 데이터를 가져가고 이벤트를 RESET하는 훈훈한 모습이 상상되지만, 그렇게 우리네 인생살이는 그렇게 호락호락 하지않다.
스레드 A가 큐에서 항목을꺼내서 로직을 처리하는동안, 스레드B에게는 두건의 데이터가 들어왔고, 스레드 B는 언제나 그랬듯이벤트가 발생했어요! 라고 이벤트를 SET 한다. 스레드A는 이벤트가 SET된것을 보고 단건의 작업만 실행후 다시 이벤트를 RESET한다. -> 큐에는 데이터가 있는데 이벤트가 RESET되어있는 문제가 발생하게 된다.
이때 이벤트 대신 세마포어로 대체하자. 초기값은 0으로 둔다. 그리고 세마포어에 "자원액세스가 끝났어요"라고 알려준다. 그러면 값이 1이되겠지.
'?'
이부분은 잘 이해가 안간다. 세마포어를 1로두면 이벤트와 다를바 없다면서 왜 저렇게 하는건지 이해가 안가고..
뮤텍스랑도 차이점을 잘 모르겠다. 락/언락을 반복하면 결국 뮤텍스 아닌가.
일단 모르는건 구렁이 담넘듯 덮어두고 넘어가보자.. 언젠간 이해가 되겠지
'Today I learned' 카테고리의 다른 글
2020 12 02 (0) | 2020.12.02 |
---|---|
2020 11 30 (0) | 2020.11.30 |
2020 11 27 (0) | 2020.11.27 |
2020 11 26 (0) | 2020.11.26 |
2020 11 22 (0) | 2020.11.22 |
댓글