멀티 스레드 환경에서 변수, 객체나 함수 등의 자원이 여러 스레드에 의해 동시에 접근되어도 프로그램이 정상적으로 동작하는 상태를 Thread Safe하다고 말한다.
public class NoThreadSafeClass {
private int result = 0;
public int getResult() {
for (int i = 0; i< 100 ; i++){
result = result + 1;
}
return result;
}
}
public class ThreadSafeClass {
private int result = 0;
public synchronized int getResult() {
for (int i = 0; i< 100 ; i++){
result = result + 1;
}
return result;
}
}
즉 어떤 함수가 한 스레드에서 호출돼서 실행중일 때, 다른 스레드가 그 함수를 호출해서 동시에 함께 실행되더라도 각 스레드에서의 함수의 수행 결과가 서로 간섭하지 않고 정상적으로 나오는 상태를 스레드 세이프라고 한다.
Peterson's Algorithm은 1981년 수학자인 개리 피터슨이라는 사람이 고안한 알고리즘이다. 두 개 이상의 프로세스의 동기화(Synchronization) 문제를 해결하는 방법 중 하나
※ Critical-section problem 의 예전 버전 해결 방법이다. 예전 버전이므로 현대 버전에 적용되는 것이 보장 되지 않지만 알고리즘 자체가 동기화 문제 해결 방법 들의 기반이 된다.
여러 개의 프로세스가 있을 때, i번째 프로세스의 Peterson 알고리즘 구조도
// flag: 신호, 공유자원을 사용하고 싶다라고 표현하기 위한 변수, 임계구역에 들어갈 때는 true, 나올 때는 false로 설정
// turn: 차례, 누구 차례인지를 명시하는 변수, turn = 0 이면, 0번째 프로세스가 임계 구역에 들어가고, 1번째 프로세스가 기다린다.
boolean flag[2];
int turn;
while(true) {
// i번째 프로세스가 공유자원을 사용하고 싶다는 신호를 전달하기 위해 flag를 true로 바꿔준다.
flag[i] = true;
// i 번째 프로세스가 쓰기 전에 먼저 쓰고 싶어했던 프로세스가 있는지 확인하고 수행시켜주는 코드
// 예를 들어 j번째 프로세스가 이 공유 자원을 쓰고 싶어 했으면 i번째 프로세스는 j번째 프로세스에 차례를 양보한다.
turn = j;
// busy waits 상태. turn이 j일 경우, 내 차례가 아니고 j가 자원까지 쓰고 싶어하면 나는 spinlock에 머무른다.
// 이제 내 차례거나 j가 자원을 쓰고 싶지 않은 경우(!flag[j]), spinlock을 빠져나와 임계 구역에 진입할 수 있다.
// turn과 flag를 통해 동시 접근을 막는다.
while(flag[j] && turn == j);
// critical section
// 임계 구역에 진입해서 작업을 한다.
flag[i] = false; // 다 썼으면 flag를 false로 바꿔준다.
// remainder section
}
코드의 순서가 바뀌게 된다면 critical section problem이 발생할 수 있다.

공유 자원에 대해 여러 개의 프로세스(스레드)가 동시에 접근을 시도할 때 접근의 타이밍이나 순서 등이 결과값에 영향을 줄 수 있는 상태

멀티 프로그래밍 환경에서 공유된 자원에 대한 접근을 제한하는 방법

동시 프로그래밍에서 공유 불가능한 자원의 동시 사용을 피하기 위해 사용하는 알고리즘

스레드 세이프(Thread-Safe)를 보장하기 위해 반드시 락(lock)을 사용해야 하는 것은 아닙니다. 락은 일반적으로 가장 직관적이고 널리 사용되는 방법이지만, 성능 문제나 특정 요구 사항에 따라 락을 사용하지 않는 다른 방법들도 존재합니다.
String(Java), tuple(Python) 같은 불변 객체.std::atomicAtomicInteger, AtomicBooleanatomic 라이브러리ThreadLocal(Java), threading.local(Python)CopyOnWriteArrayList(Java), CowArrayList(C++)ConcurrentLinkedQueue.akka(Java/Scala Actor 모델), Go의 채널(Channel).https://velog.io/@sooyoungh/Thread-safe%EC%8A%A4%EB%A0%88%EB%93%9C-%EC%84%B8%EC%9D%B4%ED%94%84%EB%9E%80
https://worthpreading.tistory.com/90
https://wooono.tistory.com/523
https://wookkingkim.tistory.com/entry/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-Petersons-Algorithm%ED%94%BC%ED%84%B0%EC%8A%A8%EC%9D%98-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98
https://8156217.tistory.com/40
https://m.blog.naver.com/365blackstar/223367838123
https://velog.io/@yarogono/CS-Race-condition%EC%9D%B4%EB%9E%80
https://chelseashin.tistory.com/40