본문 바로가기

Computer Science/OS

병행 프로세스와 상호 배제

병행 프로세스 - 병행 프로세스의 개념 

오른쪽으로 시간이 흘러갑니다.

 

한 프로세스 입장에서는 쉬었다 가고 하는 겁니다.

cpu입장에서는 이거했다 저거했다 하는 것입니다.

 

프로세스 입장은 다른애와 무관하게 계속 가고 있는 것 입니다.

 

cpu가 진짜 여러개라서 parallelism이라고 합니다.

 

 

 

병행 프로세스 - 병행 프로세스의 종류

다른 프로세스가 읽은 것을 쓰는 협력 프로세스가 있을 수 있습니다.

 

진짜 관심있는 것은 협력 프로세스 입니다.

 

각각 역활을 분담해서 모듈화를 합니다.

 

협력 프로세스는 스레드와 비슷한 것인데 여러 작업을 동시 수행합니다.

 

협력하는데 문제가 생겨서 문제를 해결하려는게 이번에 배울 것입니다.

 

협력 프로세스의 대표적인 문제가

공유 자원 사용 시 충돌 발생 입니다.

 

여기서 공유자원은 입출력 장치, 메모리, 프로세스 등 입니다.

서로 사용하려 합니다

 

 

병행 프로세스 - 협력 프로세스들의 수행 방식의 구분

2개의 프로세스가 협력을 하긴 합니다.

 

B프로세스의 어떤 결과를 기다리고 있다가 A가 반응하는 것은 동기적

 

B프로세스의 결과를 받긴 받는데 어느 시점이라고 받는 것은 아닙니다. 이것이 비동기적 입니다.

 

동기적으로 처리해야 하는 상황이 많습니다.

 

1. 정보공유

2. 계산 속도 증가

3. 모듈화

4. 편의성

5. 프로그래밍 단순화

 

5번 입니다.

프로그래밍이 복잡해집니다.

 

 

병행 프로세스 - 병행 프로세스의 해결 과제(문제점)

상호 배타적 사용(=상호 배제)

한번에 하나씩만 들어가야 합니다.

 

메모리를 공유할 경우 두 프로세스가 공유하는 공간이 있을 수 있습니다.

 

결정성 확보

결정성 이란? 동시에 수행하는 다른 프로세스의 실행 속도와 관계없이 항상 일정한 실행 결과 보장

 

 

병행 프로세스 - 선행 그래프와 병행 프로그램

그래프는 정점 집합간선 집합으로 구분된다.

 

각 노드가 프로세스이다.

집합의 크기가 4이고 선행은 3개를 해야합니다.

 

선행 제약이 생겨놨는가?

어떤 코드는 반드시 뭘 하고나서 실행히야 한다. 라는 것이 있습니다 왜이럴까요?

 

a,b값을 먼저 알아야 하니 S1,S2를 실행합니다.

 

그러면 S1, S2는 선행제약이 없습니다. 왜 없을까요? 굳이 이유가 없기 때문입니다.

 

선행 그래프는 선행제약의 논리적인 표현입니다.

독립적으로 병행 실행 가능한건은 선행제약이 없어야 합니다.

 

오른쪽 선행그래프는 문제가 있습니다. 사이클이 있습니다.

하나의 사이클에서는 순서대로 할 수 없다입니다.

 

P2, P3가 P4만 끝나면 동시에 실행될 수 있을거 같습니다.

병행실행 가능한것은 2쌍이 존재합니다.

병행 실행 가능한 것은 

{P2, P1}, {P3, P4}, {P2, P4} 3쌍이다.

 

 

프로그램을 짤 때 병행 프로그램을 짤 수 있습니다.

2문법이 차이가 나는데 

 

fork는 자식만들 때 사용합니다.

(연산 흐름 분할)

결합하는건 join입니다.

 

이러한 선행관계를 가집니다.

S1을 먼저하고 fork를 하는데 L로 나눕니다.

 

원래 흐름은 그대로 가고

나눠진 흐름은 레이블 L부터 시작합니다.

 

원래 흐름은 S1 -> S2를 하고

나눠진 흐름은 S1 -> S3를 합니다.

 

join count(2)는 2개를 join하는 것입니다.

L1 : S2는 앞에꺼와 같습니다.

 

2개의 흐름을 하나로만들고 S3를 실행합니다.

맨 위에 꼭지점에서 fork L1을 합니다. 그리고 원래 흐름은 S1을 진행합니다.

2개의 실행흐름이 join으로 가서 하나의 흐름으로 바뀝니다.

 

count를 일단 1개 감소시킵니다.

0이 아니면 누군가 아직도 도착안한것(=흐름) 이 있다는 것입니다.

나는 죽어버리면 됩니다.

 

그럼 마지막에 도착한애는 count가 0이되기 때문에 수행하지 않고 넘어갑니다.

10개가 오면 9개는 quit이 되고 마지막 1개는 살아서 그 다음을 계속합니다.

 

 

1. fork는 한번하지 않을까 싶다.

왜냐하면 Tp가 Tr로 가는데 Tq가 분리되어 Tr로 가기 때문이다.

 

2. join은 한 번하지 않을까 싶다.

 

내 흐름은 왼쪽으로 가게끔 코드를 작성해 봅시다.


count = 2; (join 할 갯수는 2개)

Tp;

fork L1;

.

.

goto L2;

L1: Tq;

L2: join count;

     Tr;


Tp를 수행하고 바로 join을 수행해야 하기 때문에 goto Tr로 하면 됩니다.

 

fork한다음 L1으로 가고 그 다음 L2로 가서 실행합니다.

 

만약 나의 흐름을 오른쪽으로 바꾼다면 코드를 짜봅시다.

 


count = 2; (join 할 갯수는 2개)

Tp;

fork L1;

Tq

.

.

L1: join count;

     Tr;


 

만약 goto L1이 있는거와 없는것의 차이?

뭐가 있을까요? 없다면 원래 흐름대로 흘러가다가 Tr을 실행하고 join을 안할거 같습니다.

아니였습니다.

 

1. fork는 2번 사용합니다.(흐름이 나눠지는대 에서 사용합니다.)

2. join은 2번 사용하는거 같습니다.

 


count = 4; (join 할 갯수는 2개)

A;

fork L1;

B

.

.

goto L2;

L1: C;

L2: join count;

     D;

L3: join count;

     E;


 

1. fork는 2번 사용합니다.(흐름이 나눠지는대 에서 사용합니다.)

2. join은 2번 사용하는거 같습니다.


count = 4; (join 할 갯수는 2개)

S1;

fork L1;

S2;

S4

.

.

goto L2;

L1: S3;

L2: join count;

     S6;

S5

L3: join count;

     S7;


 

728x90