저번 포스팅 Critical section - 공유메모리 에서 pipe로 통신하는 방법 외에도 여러가지 방법이 있어서 그중, 공유메모리를 이용한 통신을 알아보도록 하자.

일단 기본적으로 프로세스간 통신을 위해 알아야 할 함수들이다.

 

int shmget(key_t key, size_t size, int shmflg); // key: 공유하는 키값, size:크기, shmflg:생성 및 접근, 성공하면 양의 정수, 실패 시 -1 리턴

 

shmflg 옵션들

1) IPC_CREATE

 

키에 해당하는 값이 없다면 새로 생성한다.

IPC_CREATE 값을 입력후 | 연산자를 덧붙여 허용권한 설정.

만약 있다면 무시하며, 접근권한을 설정해준다.

 

2)IPC_EXCL

 

공유 메모리가 이미 있다면 실패를 반환하고 접근 불가능.

이옵션을 제거해 주어야 기존 공유메모리에 접근할 수 있다.


void* shmat(int smId, const void* shm_addr, int flag); // smId:공유메모리 식별자, shm_addr:공유 메모리와 연결하고자 하는 프로세스 내부의 메모리.(프로그래머가 직접 정해주는 것보다 시스템에 의해 할당되는 것이 좋으므로 일반적으로 null(0)을 세팅) flag: 속성 설정(SHM_RND:공유메모리와 연결되는 프로세스 내부 어드레스를 시스템이 관리하도록 함 , SHM_RDONLY: 읽기 전용으로 메모리를 연결, SHM_REMAP:연결영역을 대체)
가상 메모리와 물리적메모리 영역을 연결해주는 함수.

int shmdt(const void* shm_addr);
프로세스가 작업을 끝내고 더 이상 메모리 공유가 필요 없을 때, 공유메모리와 연결된 프로세스 내부의 가상 메모리 연결을 해제.

 

공유메모리를 설정하면 공유메모리의 semid가 주어지는데 이 ID로 공유메모리를 식별하거나 찾아들어간다.

 

 

ipcs : 현재 공유메모리 보기.

ipcrm shm [shmid] : 공유메모리 제거.

 

간단한 예제를 보면서 사용법을 익히기로 한다.

 

shared.c

 

#include<stdio.h>
#include<stdlib.h>
#include<sys/shm.h>                //공유메모리 함수의 라이브러리

struct shared_use_st{               //some_text 배열을 공유메모리로 사용할 것임.
                int written_by_you;
                char some_text[2048];
};

int main()
{
        int shmid;
        void* shared_memory=(void*)0;
        int running=1;
        struct shared_use_st* shared_stuff;

        shmid = shmget((key_t)1234,sizeof(struct shared_use_st),0666 | IPC_CREAT);    

        //공유메모리생성
        if(shmid == -1){
                printf("Shmget Error\n");
                exit(1);
        }
        shared_memory = shmat(shmid,(void*)0,0);    //생성한 공유메모리를 shared_memory변수에 붙인다.
        if(shared_memory == (void*)-1)
        {
                printf("Shared_memory location Error\n");
                exit(1);
        }
        shared_stuff = (struct shared_use_st *)shared_memory;//형변환후 최종적으로 구조체를 공유메모리로 설정한다.
        shared_stuff->written_by_you = 0;
        while(running){
                if(shared_stuff->written_by_you)        //written_by_you ==1이면 입력받은내용이있으므로 출력후에 0으로 바꿔줌.
                {
                        printf("Wirten is : %s\n",shared_stuff->some_text);
                        sleep(rand()%4);
                        shared_stuff->written_by_you =0;
                        if(strncmp(shared_stuff->some_text,"end",3)==0)    // end를 입력하면 종료.
                                running=0;
                }
        }

        return 0;
}

 

 

shared1.c

 

#include<sys/shm.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

struct shared_use_st{
        int written_by_you;
        char some_text[2048];
};

int main()
{
        int running =1;
        void *shared_memory =(void *)0;
        struct shared_use_st* shared_stuff;
        char buffer[100];
        int shmid;

        shmid = shmget((key_t)1234,sizeof(struct shared_use_st),0666|IPC_CREAT);

        if(shmid==-1){
                printf("Shmid Error\n");
                exit(1);
        }
        shared_memory = shmat(shmid,(void*)0,0);
        if(shared_memory == (void*)-1)
        {
                printf("Shamt Error\n");
                exit(1);
        }
        printf("Memory located at %p\n",shared_memory);
        shared_stuff = (struct shared_use_st*)shared_memory;
        while(running)
        {
                while(shared_stuff->written_by_you==1)
                {
                        sleep(1);
                        printf("waiting for client...\n");
                }
                printf("Enter some text...\n");
                fgets(buffer,100,stdin);
                strncpy(shared_stuff->some_text,buffer,2048);
                shared_stuff->written_by_you=1;
                if(strncmp(buffer,"end",3)==0)
                {
                        running=0;
                }
        }
        return 0;
}

 

shared.c과 shared1.c가 서로 통신을 하면서 shared1.c에서 입력한 값을 shared.c에서  출력하게 끔하는 소스이다.

shm_com.h라는 라이브러리에 sturct shared_use_st구조체가 선언되어 있다는 것을 알게됬으나, Ubuntu 11.10버전에서는 이상하게 라이브러리가 존재하지 않아서 소스딴에서 전역변수로 넣어주었다. 공유메모리 어렵다 ...조금더 확실히 알고 가야할듯하다. 하지만 지금은 시험보기 3시간전ㅋㅋㅋㅋㅋㅋㅋㅋ

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

Semaphore  (0) 2012.04.27
파일 디스크립터(File descriptor)  (0) 2012.04.24
Process Scheduling - Multilevel Queue scheduling,Multilevel feedback Queue Scheduling  (0) 2012.04.22
Process Scheduling  (0) 2012.04.19
Process Scheduling - Round_Robin  (0) 2012.04.19

+ Recent posts