데이터의 접근 패턴
테이터가 저장된 위치에서 읽어와서 연산을 하고, 연산 결과를 원래 위치에 저장하는 것을 과정을 거친다.
storage-box
데이터가 저장되어 있는 곳이다.
execution-box
실제 연산하는 곳이다.
데이터가 저장되어 있는 곳에서 읽어와서 작업을 하고 다시 저장을 하기 때문에 프로세스 동기화라는 문제가 발생한다.
데이터를 읽기만 하면 누가 읽든, 읽는 동안 다른 사람이 읽든 상관이 없으나,
만약 A라는 프로세스가 읽는 동안 수정을 할 수도 있고, 그 수정하는 동안에 B프로세스가 다시 가져가서 읽고 있는데, A가 수정된 사항을 저장하게 된다면, 문제가 발생할 수 있다.
storage box를 여러 execution box가 공유한다고 하면 문제가 생긴다.
한쪽에서는 1을 감소시키고, 한쪽에서는 1을 증가시키는 연산이 있다면 데이터에 어떻게 반영이 되어야 할까?
위와 같이 공유된 데이터나 하나의 데이터에 여러 주체가 동시에 접근하려고 할때 Race Condition(경쟁상태)이 발생한다.
경쟁상태에서 하나의 주체가 읽어간동안 다른 주체가 읽어가면 문제가 생기므로 조율할 필요가 있다.
cpu가 여러개 있는 시스템에서는 메모리를 공유한다면 문제가 발생할 수 있다.
프로세스는 자기 주소공간만 접근하기 때문에 race condition이 발생하지 않는다. 하지만 시스템콜이 발생하면 커널에 있는 데이터를 접근하기 때문에 race condition이 발생할 수 있다.
운영체제 커널이 cpu에서 실행을 하고 있고, 카운트라는 변수의 값을 증가시키고 있다.
커널의 코드가 실행되는 도중에 인터럽트가 발생해서, 인터럽트 처리를 하게 되면 커널의 데이터를 양쪽에서 건드리기 때문에 1이 증가한 것만 반영이 된다.
문제를 해결하기 위한 방법으로는 인터럽트가 들어와도 인터럽트 처리 루틴으로 넘기는 게 아니라 인터럽트를 disable시켰다가 작업이 끝난 후에 인터럽트 처리 루틴으로 넘겨서 race condition이 발생하지 않게 한다.
프로세스가 실행되는게 본인의 코드만 실행하는게 아니라 운영체제에 시스템콜을 넘겨서 요청하는 경우도 있다. 유저모드와 커널모드를 번갈아가면서 하는데, cpu를 독점해서 쓰는게 아니라 할당시간만큼 쓰는데, 할달시간이 끝난시점이 시스템콜을 해서 커널의 코드가 실행하면서, code를 수정하는 도중에 할당된 시간이 끝나서 넘어간 상태이고, 다른 프로세스에서 역시 같은 변수를 건드린 상황이라면, 밑에서 증가시킨것은 증가되지 않는다.
time share에서는 프로세스가 커널모드에 있으 때는 할당시간이 끝나도, cpu를 뺏기지 않도록 한다. 커널모드가 끝나고 유저모드로 빠져 나올때 cpu를 빼았는 것이다.
앞에서 설명한 방법으로는 해결이 되지 않는다.
작업주체가 여러개 있으므로 생기는 문제이다.
cpu가 여러개 있는 상황에서는 데이터를 접근할 때 lock을 건다. 다른 누구도 건드리지 못하게 한다. 작업이 끝난 후에 lock을 풀어서 다시 접근할 수 있도록 한다.
사용자프로그램이 아니라 운영체제 커널을 여러개가 접근하기 때문에 발생하기 때문에
커널에 매순간 하나만 접근하게 하면 문제가 없다.
방법1과 같이 커널에 lock을 거는 방법은 cpu가 여러개 있더라도 커널에 접근할 수 있는것이 하나밖에 없다. 비효율적이 될 수 있다.
공유데이터에 동시 접근으로 데이터의 불일치가 발생할 수 있다. 일관성을 유지하기 위해서는 프로세스의 실행 순서를 정의해주는 메커니즘이 필요하다.
여러 프로세스가 동시에 공유데이터에 접근하려는 것을 race condition이라고 하고, race condition을 막기 위해서는 동시에 실행하는 프로세스간의 동기화가 잘 되어야 한다.
x = x + 1 이라는 고급언어의 문장 하나가 cpu에서는 여러개의 인스트럭션으로 실행되기 때문에
1증가시키기 위해서 읽어간 사이에 cpu가 넘어가서 1감소하는 코드를 수행하면, 일관성이 깨어진 불일치 문제가 발생할 수 있다.
공유자원을 사용하던지, 커널에 있는 데이터를 수정중에 cpu를 다른 프로세스가 잡아서 같은 자원을 수정한다면, 문제가 발생할 수 있다.
서로다른 주체가 공유자원에 동시에 접근하게 된다면 문제가 발생하게 된다.
공유데이터를 접근하는 코드를 임계영역이라고 한다.
임계영역에 있는 코드를 수행중에 cpu를 뺏겨서 다른 프로세스에게 cpu가 넘어가게 되면, 임계영역에 접근하지 못하게 해야한다.