어떻게 동기화를 유지할 수 있는걸까? -> 스핀락, 뮤텍스, 세마포어를 통해 살펴보자!

박경현·2023년 9월 8일
0

우리는 전 시간에 동기화가 무엇이고 race condition이 무엇인지
개념적으로 이해를 했다

그렇다면 동기화 방법인 mutual exclusion,
즉 한번에 하나의 스레드만 critical section에 들어오게 하는건 어떻게 하는걸까?

lock을 사용하자! & 스핀락

쉽게 말하면 하나의 스레드가 들어오면 그 다음 스레드가 critical section을 사용 못하게 잠그는거다!
그리고 스레드의 실행이 끝나면 다음 스레드에게 기회 주기!

do {
	acqire lock - 하나의 스레드만 들어감
    	critical section
    release lock
}while();

while을 반복하면서 자신의 차례를 기다리는 spin lock

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에 대해 고민하면서 프로그래밍 한적이 없었다는것에
매우 쪽팔리다...

그렇지만 이제부터라도 제대로 확실하게 하나씩 원리를 이해하고 언젠가 꼭 완벽히 알아서 활용해 볼거다!

profile
SW로 문제를 해결하려는 열정만 있는 대학생

0개의 댓글