[운영체제 정리] 8.프로세스 동기화

프로세스 동기화

컴퓨터 안에서 데이터가 접근되는 패턴

데이터가 저장되어 있는 위치(메모리)에서 데이터를 가져와 연산(cpu)을 하고 다시 저장위치에 가져다 놓는다.

이때 데이터의 동기화 문제가 생긴다. 하나의 저장소에서 여러 사람이 공유 데이터에 접근한다면 데이터가 원하는데로 변경이 안될 가능성이 크고, 데이터의 일관성이 유지가 안될수 있고, 데이터 불일치 문제가 생길수 있다.

 

동기화 문제

여러사람이 하나의 공유 데이터에 접근할때 문제점.예를들어 두 프로세스에서 동시에 시스템 콜이 발생할때, 커널의 데이터에 동시에 접근되어 변경이 될때 문제가 될 수 있다.

 

동기화문제-커널에서 동기화 문제가 발생하는 경우

1.커널 수행중 인터럽트 발생시

2.프로세스가 시스템콜을 해서 커널모드로 수행중인데 타이머로인해 컨텍스트 스위치가 일어나는 경우.

3.멀티프로세서에서 공유메모리 내의 커널 데이터

(유저 레벨에서는 프로세스들이 자기 주소 공간을 가지기 때문에 동기화 문제가 크지 않다)

 

예)1

커널 코드를 작동하면서 커널의 count 메모리 변수를 1증가시킨다고 하면, cpu는 메모리의 변수 값을 cpu의 레지스터로 불러들이고, 그 레지스터값을 1증가시키고, 다시 그 증가시킨값을 메모리에 쓰고...(이 고급언어로 쓰여진 일련의 과정을 cpu는 여러개의 인스트럭션으로 나누어서 처리함)

문제는 cpu 레지스터로 메모리 변수가 로드되고 인터럽트가 발생했을때. 위 그림처럼 인터럽트 핸들러가 count 변수를 -1 하고 다시 커널로 돌아와서 +1하면 처음 count 값이 그대로 있어야하는데 문제는 커널에서 +1 한것만 반영이된다.(커널의 공유메모리 동시 접근문제)

 

해결:빨간점 에서는 인터럽트가 넘어와도 먼저 하던일을 다 끝낼때까지 인터럽트를 발생을 막고 풀어주면 됨.

 

예2)

pa프로세스를 실행하다가 시스템콜을 해서 커널의 코드를 실행하다가 할당시간이 끝나서 Pb에게 넘어감. 다시 pb에서 시스템 콜을 호출..그리고 타이머 인터럽트가 발생해서 다시 pa로 돌아옴..유저레벨에서 컨텍스트스위치가 발생하면 문제가 없지만, 커널의 코드가 실행중이고, 1을 증가 할려고 하는데 타이머..시간이 다 되버렸음.

결과적으로 pa는 cpu 의 레지스터 안으로 카운터 변수를 읽어 들였기때문에 pb에서 +1을 했다고 해서 1이 증가 되어 있는 상태가 아니다..그거랑 별개로 pa의 cpu레지스터에는 0이 있다. 그래서 pa에서 cpu를 얻은 그다음부터 +1을 하면 최종 결과값은 1이 된다.

 

해결:

프로세스가 커널 모드에 있을때는 할당시간이 끝나도 cpu를 뺏기지 않고, 유저모드로 돌아올때 cpu를 뺏을수 있게 한다.

 

예3) cpu가 여러개일때

데이터에 접근을 할때 , 그 데이터에 락을 걸고 누구도 이 데이터에 접근을 못하게 하고 저장이 끝나면 비로소 언락을 해서 누구나 접근을 할수 있게 한다( 커널 전체를 하나의 락으로 막고 커널을 빠져나올때 락 풀어도 되는데 비효율적이기 때문에 변수에 락을 건다. 사진의 메모리는 커널의 메모리임.)

 

프로세스 동기화 문제

크리티컬 색션(임계구역)

공유데이터에 접근하는 로직을 크리티컬 섹션이라고 한다.(임계구역)

 

먼저 크리티컬 섹션에 접근하기전에 다른 프로세스나 스레드가 접근못하게 엔트리 섹션에 락을 걸어주고, 공유데이터의 접근이 종료되면 exit섹션에서 락을 풀어주고 나온다.

 

 

소프트웨어적으로 동기화 문제 해결 - 프로그램 해결법의 충족조건

 

1. turn변수 사용

turn = 프로세스 번호

자기 차례가 아니면 while문에서 계속 기다림. 들어가서 나올때 다른 프로세스 번호를 적어준다.

(상호 배재 조건을 만족하나 프로그레스 조건을 만족하지 못한다..턴을 교대로만 해주기때문..)

 

2. 플래그 변수 사용

프로세스 두개가 각각 자신의 플래그를 가지고 있다. 크리티컬 색션에 들어가겠다는 의중을 표현한것. 크리티컬 색션에 들어갈려면 그 프로세스의 플래그를 참으로 만들고 상대방의 플래그를 체크한다. 상대방의 플래그가 거짓이라면 크리티컬 색션에 들어가서 나올때 플래그를 거짓으로 해놓고 나온다.

 

문제점

플래그를 참으로 맞추고 두번째 줄에서 (while 문)cpu가 빼앗길때.. 둘다 못들어가게 된다.

 

3.피터슨 알고리즘

 

특징: turn 과 flag 변수 둘다 사용.

프로세스가 들어갈때 플래그를 참으로 만들고 상대방 turn 변수를 참으로 만듬. 들어가기 전에 상대방이 플래그를 참으로 가지고 있고 turn이 상대방 차례면 나는(process) 크리티컬 섹션에 들어갈 수 있고, 나올때 나의 플래그를 거짓으로 하고 나온다.둘다 크리티컬 섹션에 들어갈려고 할때, 즉 둘의 프로세스의 플래그가 참일때 turn을 가지고 체크를 함(위의 세가지 충분 조건 모두 만족)

 

문제점: 비지 웨이팅(스핀락). 계속 while문을 걸면서 상대방이 못들어가게 하는것. 내가 cpu를 잡아서 while문에서 돌아도 상대 프로세스에서 변수를 셋팅해줘야 빠져나올수 있음..

 

왜 프로세스 동기화 소스가 복잡할까? 

고급언어가 여러개의 인스트럭션 라인으로 구성되어 있기때문에 라인하나하나를 체크해 주기위해서이다. 예를들면 아래 그림과 같이 c언어 한줄은 여러개의 인스트럭션 라인으로 구성이되어서 cpu가 한줄씩 읽다가 인터럽트에 걸릴수 있기때문이다.

 

하드웨어적으로 동기화 문제 해결- test & set 인스트럭션

그림에 상자안에 a를 읽고 1(참)로셋팅.

크리티컬 섹션에 들어갈때 락 변수를 읽고 0이면 들어가서 락변수를 1로 만들어주고 나올때 락변수를 0으로 만들어준다. 반대로 들어갈때 1이면 계속 대기한다.(하드웨어적으로 락변수를 읽고 쓰는 두가지 작업을 한번에 원자적으로 수행)

 

 

 

참고: 이화여대 반효경 교수님 운영체제 강의정리