프로세스간의 통신 방법에는 여러가지 방법이있다.

IPC - InterProcees Communication 의 준말로 '프로세스 간 통신'을 뜻함.

 

<< IPC 종류 >> 

 

그 중에서 공유메모리 설정을 통한 프로세스간 통신을 알아보도록 알아보자.

IPC 방법중에서 가장 빠른 방법이다.하지만 Critical Section과 같은 문제점이 발생하기도 하기 때문에 이를 조심하며 프로그램을 만들어야 한다.

※Critical Section 이란 두개의 프로세스가 공유되있는 변수혹은 저장공간을 사용하는도중 생기는 문제점이 있는 코드영역을 말함.

ex)

count =0 이라는 공유변수가 있다.

Producer 프로세스와 Consumer 프로세스가 있을떄

 

while(TRUE){

/* Produce an item in nextProduced */

while(counter== BUFFER_SIZE);

buffer[i] = nextProduced;

in = (in +1) % BUFFER_SIZE;

counter++;

}

 

while(TRUE){

/*consume the item in nextConsumed */

while(counter == BUFFER_SIZE );

nextConsumed = buffer[out];

out = ( out + 1) %BUFFER_SIZE;

count --;

}

 

각각의 프로세스의 중간에 저러한 코드가 있다.

Producer 프로그램은 공유메모리(Queue)에 item을 저장하고 consumer프로그램은 공유메모리(Queue)에서 item을 받고 있다.

C언어 코드로는 문제가 없어보이지만, C언어를 어셈블러로 바꾸면 1줄의 코드가 여러줄로 바뀌게 된다.

 

count ++ ==> assembly

 

count -- ==> assembly

C언어 코드로는 한줄이지만, assembly언어로 보면 3줄이다. 만약 Producer의 count++;의 assembly를 수행중에 Context-switch가 일어나게 되는 상황을 생각해보자.

 

ex) count = 5;

Producer의 어셈블리 코드중 add1까지 수행하고 Context-switch가 일어난다.

(Produce의 count=6 이지만 Consumer의 count=5인 상황.)

consumer의 명령이 끝나고 count=4;로 저장되고 Context-switch가 일어남.

PCB 테이블의 Produce count=6이다. Producer 프로그램의 나머지 명령

mov $0x0,%eax에 의해서 count=6이 되어버린다.

 

이러한 문제점이 발견되는 코드영역을 Critical Section이라 부름.

 

공유메모리를 사용하는 방법중에는 fork를 이용한 부모,자식 프로세스간의 메모리 공유이다.

운영체제 강의 시간에 Critical Section 의 solution 중 Peterson's solution을 듣고 직접 해보기 위해 간단한 Pipe를 이용한 프로그램 코드를 구성.

 

#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>

int main()
{
        int pipe1[2];
        pid_t pid;
        int pass=0,process[2]={0},status,count=5;

        //두개의 파이프를 생성.
        pipe(pipe1);
        pipe(process);
        pid=fork();     //자식프로세스를 생성한다.
        if(pid==-1)
                printf("fork 실패, Process Id : %d\n",pid);
        printf("fork 성공, Process Id : %d\n",pid);

        do{
                if(pid!=0)
                        pass=1;                 //부모를 통과시킴.
                while(process[0]==0 && pass==0);//자식프로세스를묶어둠.
                if(pid!=0){
                        close(process[0]);
                        close(pipe1[0]);
                        process[0]=write(pipe1[0],&pass,sizeof(int)); 

//부모의 pass를 자식의 process[0]에 넣는다.
                        pid=wait(&status);
                        if(WIFEXITED(status))        

//자식프로세스가 끝날때까지 부모프로세스가 기다림.
                                printf("Normal exit child process\n");
                        count++;
                }
                else
                        count--;
                printf("%d\n",count);
                break;
        }while(1);
        printf("Process ID : %d\n",pid);

        return 0;
}

(자식프로세스가 끝날때까지 부모가 기다리고나서 count를 증가시킨다. 이때 위의 4는 자식의 count이고 6은 부모의 count이다. 부모의 프로세스가 자식이 종료된 후에 count를 증가시켜준다는 것을 보여준다.)

'O.S' 카테고리의 다른 글

Process Scheduling - Priority  (0) 2012.04.19
Process Scheduling - SJF  (0) 2012.04.19
Process Scheduling - FCFS  (0) 2012.04.19
Interrupt  (0) 2012.04.17
Thread  (0) 2012.04.17

+ Recent posts