업데이트:

카테고리:

/

태그: , ,

Thread Safe

멀티 쓰레드 프로그래밍에서, 어떤 공유 자원에 여러 쓰레드가 동시에 접근해도, 프로그램 실행에 문제가 없는 상태

1. 상호 배제 (Mutual exclusion)

공유 자원에 하나의 Thread만 접근할 수 있도록 통제함

Race Condition

두 개 이상의 프로세스가 공유 자원을 병행적으로 읽거나 쓰는 동작을 할 때, 접근이 어떤 순서에 따라 이뤄졌는지에 따라서 실행 결과가 달라지는 현상

위의 Race Condition 을 방지 하기 위해서 Mutual exclusion을 구현하면 문제가 생긴다.

Deadlock

Untitled (8)

A 프로세스가 A자원을, B 프로세스가 B 자원을 사용할 때, 다음 작업을 위해서 A 프로세스가 B자원이, B 프로세스는 A자원이 필요할 때 Mutual exclusion은 공유 자원에 하나의 프로세스밖에 접근하지 못해, 계속 무한 대기중인 상태

결과적으로 아무것도 완료되지 못하게 된다.

예방법

  • 세마포어 (Semaphore) - 신호 매커니즘

    공유된 자원의 데이터를 여러 프로세스가 접근하는 것을 막는다. 동시에 접근할 수 있는 스레드의 수를 제한하여, 공유가능한 프로세스 카운팅이 0 이면, 더 이상 다른 프로세스는 접근하지 못하도록 한다.

  • 뮤텍스 (Mutex) - 잠금 메커니즘

    공유된 자원의 데이터를 여러 프로세스가 접근하는 것을 막는다. 각 프로세스에서 공유 데이터를 엑세스하는 프로그램 코드의 Running time을 겹치지 않게 실행한다.

  • 모니터

    둘 이상의 스레드나 프로세스가 공유자원에 안전하게 접근할 수 있도록 공유자원을 숨기고 해당 자원에 대한 접근을 인터페이스에게만 허용함

    작업이 차례대로 모니터 큐에 들어와 순서대로 완료되면 빠져나가게된다.

2. 원자 연산 (Atomic operation)

기능적으로 분할할 수 없거나 분할되지 않도록 보증된 조작, 멀티스레드에서 공유 자원들에 대해 여러 스레드가 서로 동시에 액세스 하는 Race Condition을 막기 위한 방법

로직이 실패하거나, 성공하거나 두개의 상태 밖에 없으며 이 사이의 상태는 없어야함

동시에 같은 메모리의 데이터를 사용할 경우 일관성을 유지하기위해 가시성을 제공함

→ 공유된 자원의 메모리 값을 기준으로 데이터 일관성을 보장

3. 쓰레드 지역 저장소 (Thread-local storage)

해당 스레드만 접근할 수 있는 특별한 저장소

저장소가 독립적으로 존재하기 때문에, 다른 스레드에서 접근이 불가

4. 재진입성 (Re-entrancy)

함수나 메서드를 자기 자신이 호출하는 것 - 재귀?

재귀가 가능하다 = 함수 내부에서 다른 인스턴스와 독립적으로 동작

→ 여러 스레드에서 동시에 호출해도 정상 동작한다.

동시성(Concurrency)

여러 작업을 번갈아가면서 처리하여, 여러 작업이 동시에 수행되는것 처럼 보인다.

실제로는 한가지 작업만 수행하고 있으며, 데이터 입출력이나 트랜직션을 기달리는 동안 다른 작업을 수행함

  1. 비선점형 방식 : 프로세스가 스스로 CPU 소유권을 포기, 강제로 프로세스를 중지하지 않음
    • 선입 선출(FIFO) - 먼저 온것을 먼저 처리함, 만약 먼저 들어온게 긴 시간이 걸린다면 준비 큐에서 오래 기달리게 된다.
    • Shortest Job First(SJF) - 실행시간이 짧은 프로세스부터 먼저 실행함, 실행시간이 긴 프로세스가 실행되지 않는 현상이 나타날 수 있으며, 평균 대기시간이 짧음

      프로세스가 실행되지 않는 현상을 막기위해 오래된 작업일수록 우선순위를 높게줘, 긴 시간을 가지고 있더라도 시간이 지나면 실행될 수 있도록한다.

  2. 선점형 방식 : 사용중인 프로세스를 중단시키고, 강제로 다른 프로세스에 CPU 소유권을 넘김
    • 라운드 로빈(RR) - 프로세스에 동일한 시간을 할당하고 그 시간에 프로세스를 완수하지 못하면 다시 준비큐로 돌려보낸다.
    • Shortest Remaining Time First(SRF) - 실행시간이 짧은 순서대로 하는 것은 SJF와 유사하지만, 프로세스가 돌고있을 때 더 짧은 실행시간을 가진 작업이 들어오면 프로세스를 중지하고 해당 작업을 실행한다.
    • 다단계 큐 - 우선순위에 따라서 준비 큐를 여러개 사용해 큐마다 다른 알고리즘을 적용, 프로세스 이동은 되지않아 부담은 적지만 유연성이 떨어짐