TIL

스핀락, 뮤텍스, 세마포

race condition(경쟁 조건)

여러 프로세스/스레드가 동시에 같은 데이터를 조작할 때 타이밍이나 접근 순서에 따라 결과가 달라질 수 있는 상황

synchronization(동기화)

여러 프로세스/스레드를 동시에 실행해도 공유 데이터의 일관성을 유지하는 것

critical section(임계 영역)

공유 데이터의 일관성을 보장하기 위해 하나의 프로세스/스레드만 진입해서 실행 가능한 영역

mutual exclusion(상호 배제)

여러 프로세스/스레드 사이에서 공유 불가능한 자원의 동시 사용을 피하는 알고리즘으로 임계 영역에 구현된다.

상호 배제를 구현하기 위해 락을 사용하게 된다.

스핀락(spinlock)

volatile int lock = 0; //global

void critical() {
	while (test_and_set(&lock) == 1); // lock을 획득할 때까지 기다
	// critical section
	lock = 0;
}

int test_and_set(int* lockPtr) {
	int oldLock = *lockPtr;
	*lockPtr = 1;
	return oldLock;
}

TestAndSet은 CPU atomic 명령어

실행 중간에 간섭 받거나 중단되지 않고 같은 메모리 영역에 대해 동시에 실행되지 않는다.

뮤텍스(mutex)

class Mutex {
	int value = 1; // 임계 영역에 진입하기 위해 얻어야 하는 값
	int guard = 0;

	void lock() {
		while(test_and_set(&guard));
		if (value == 0) { // 다른 스레드가 락을 먼저 얻은 경우
			// 현재 스레드를 큐에 넣음;
			guard = 0; 
			// 그리고 스레드를 sleep
		} else {
			value = 0; // 락 취득
			guard = 0;
		}
	}

	void unlock() {
		while (test_and_set(&guard));
		if (큐에 하나라도 대기 중이라면) {
			// 그 중 하나를 깨운다;
		} else {
			value = 1; // 락 반환
		}
		guard = 0;
	}
}

세마포(semaphore)

class Semaphore {
	int value = 1; // 임계 영역에 진입하기 위해 얻어야 하는 값
	int guard = 0;

	void wait() {
		while(test_and_set(&guard));
		if (value == 0) { // 다른 스레드가 락을 먼저 얻은 경우
			// 현재 스레드를 큐에 넣음;
			guard = 0; 
			// 그리고 스레드를 sleep
		} else {
			value -= 1;
			guard = 0;
		}
	}

	void signal() {
		while (test_and_set(&guard));
		if (큐에 하나라도 대기 중이라면) {
			// 그 중 하나를 깨워서 준비 시킨다;
		} else {
			value += 1;
		}
		guard = 0;
	}
}

뮤텍스와 바이너리 세마포는 다르다.

priority inversion과 priority inheritance


https://www.youtube.com/watch?v=gTkvX2Awj6g

https://j-i-y-u.tistory.com/21