GameChoi 2023. 1. 3. 17:26

1. Race Condition

 - 서로 다른 쓰레드에서 같은 메모리를 공유할 때 발생할 수 있는 문제

   - 서로 다른 쓰레드들이 동일한 자원을 사용할 때 발생하는 문제를 경쟁 상태

1.1 Thread

 - 서로 다른 쓰레드들에서 counter 라는 변수의 값을 1 씩 계속 증가시키는 연산을 수행

void worker(int& counter)
{
    for (int i =0; i < 10000; i++) counter++;
}

int main()
{
    vector<std::thread> workers;
    int counter = 0;
    
    // ref - 레퍼런스로 전달하려면 ref 함수로 감싸야 함
    for (int i = 0; i < 2; i++) workers.push_back(std::thread(worker, std::ref(counter)));
    for (int i = 0; i < 2; i++) workers[i].join();
    
    cout << counter << endl;
}

 - 실행 화면

   - 밑의 그림과 같이 이상한 값이 나옴

     - 이것을 경쟁 상태(Race Condition)이라 부름

Race Condition

 - 이를 이해하기 위해선 CPU 연산 처리를 알아야 함

1.2 CPU

 - CPU 연산 수행

   - CPU의 레지스터라는 곳에 데이터를 기록한 다음 연산을 수행

 - 모든 데이터들은 메모리에 저장

   - 연산 할때 마다 메모리에서 레지스터로 값을 가져온 뒤에 빠르게 연산

   - 다시 메모리에 가져다 놓는 식으로 작동

 - Assembly Code (어셈블리어)

  - 밑의 그림처럼 디버깅을 해서 어셈블리어를 확인해 본다면 명령을 한줄 한줄 CPU가 처리

Assembly Code

 - 위 구조처럼 사용되다가 쓰레드 1번과 쓰레드 2번이 동시에 사용

   - 쓰레드 1번은 rax, eax를 사용하고 멈춘 후 쓰레드 2번이 들어와 모든 값을 실행하고 나간다면 쓰레드 1번이 꼬이게 됨

Thread1 & Thread2

 - 위의 같은 방식이 일어나 2만이 아닌 이상한 값이 생김

   - 쓰레드를 어떻게 스케쥴링 할지는 운영체제가 마음대로 결정