저번 포스팅 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 |