우리는 전 시간에 동기화가 무엇이고 race condition이 무엇인지
개념적으로 이해를 했다
그렇다면 동기화 방법인 mutual exclusion,
즉 한번에 하나의 스레드만 critical section에 들어오게 하는건 어떻게 하는걸까?
쉽게 말하면 하나의 스레드가 들어오면 그 다음 스레드가 critical section을 사용 못하게 잠그는거다!
그리고 스레드의 실행이 끝나면 다음 스레드에게 기회 주기!
do {
acqire lock - 하나의 스레드만 들어감
critical section
release lock
}while();
volatile int lock = 0;
void critical() {
while (test_and_set(&lock) == 1):
...critical section
lock = 0;
}
//먼저 while루프에 통해 락을 획득하려고 함
//획득한 애가 critical section에서 움직임
int test_and_set(int *lockPtr) {
int oldLock = *lockPtr;
*locPtr = 1;
return oldLock;
}
t1, t2스레드가 있다고 해보자!
실행 순서!
t1이 먼저 시작했다면 while 조건에 lock이 1이 아니어서
while에 안들어가고 바로 critical section이 실행된다!
2. t2가 실행된다면 lock=1로 되어있어서 while을 일단 계속 반복하고 있다!!
3. t1이 끝나면 아래있는 lock=0으로 바꿔줘서 t2가 그다음 critical section이 실행된다!!
while을 현재 스레드가 끝나기 전까지 모든 스레드들이 반복 돌고 있기 때문에
cpu사용량이 많아진다!!!
그렇다면 이걸 어떻게 해결할 수 있을까?
while을 반복하는게 아니라 현재 critical section에 들어있는 스레드가 끝날때까지
큐에 들어가서 대기하고 있자!!
mutex->lock();
...critical section
mutex->unlock();
그건 아니다!
cpu를 덜 잡아먹지만 빠르게 critical section이 끝나는 멀티코어 환경이라면
다른 코어에서 while문 돌면서 기다리다가 바로 다음 스레드 작업을 하면 실행 속도도 빨라서
항상 좋은건 아니다!
여러개 코어가 있을때 각각 스레드를 실행할때 이득!
세마포는 순서를 정해줄 때 사용 -> 무조건 전에 작업이 끝나야 내 작업 시작이 가능!
카운트를 조잘하여 진입 가능한 프로세스 수 나 스레드 수를 조절할 수 있다!
지금까지 컴공이었지만 이만큼 깊이있게 OS에 대해 고민하면서 프로그래밍 한적이 없었다는것에
매우 쪽팔리다...
그렇지만 이제부터라도 제대로 확실하게 하나씩 원리를 이해하고 언젠가 꼭 완벽히 알아서 활용해 볼거다!