수업 정리/UNIX 프로그래밍

[UNIX 프로그래밍] 11-2강 Shared memory

leebaek 2024. 12. 7. 18:10

  • shared memory
  • shmget 시스템 호출
  • 공유 메모리 생성 예시
  • shmat 시스템 호출
  • shmat을 이용한 공유 메모리 부착 예시
  • 공유 메모리 사용 예시
  • shmctl 시스템 호출

shared memory

- 둘 이상의 프로세스가 물리적 메모리의 일부를 공유

- 가장 효율적인 IPC 기법


shmget 시스템 호출

□ shmget()

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
int shmget(key_t key, size_t size, int permflag);

 

  • key : 공유 메모리 영역의 identifier
  • size : 공유 메모리 영역의 최소 크기
  • permflag : access permission | IPC_CREAT | IPC_EXCL
  • return : 공유 메모리 영역의 identifier

 

> IPC_EXCL:

공유 메모리가 이미 존재할 경우, 새로운 세그먼트를 생성하지 못하도록 함

IPC_CREAT | IPC_EXCL 을 사용해서 공유 메모리가 이미 있으면 오류를 반환하고, 없으면 새로 생성하여 안정성을 높임

 


공유 메모리 생성 예시 ( shmget 사용법 ) 

1. 512byte의 문자를 저장할 공유 메모리 생성

shmid1 = shmget(0111, 512, 0600|IPC_CREAT);

 

2. 10개의 정수를 저장할 공유 메모리 생성

shmid2 = shmget(0112, 10*sizeof(int), 0600|IPC_CREAT);

 

3. struct databuf의 데이터 5개를 저장할 공유 메모리 생성

shmid3 = shmget(0113, 5*sizeof(struct databuf), 0600|IPC_CREAT);

 shmat 시스템 호출

□ shmat() : shmget 호출에 의해 할당된 메모리 영역을 자신의 논리적 자료 공간에 부착함

#include <sys/shm.h>
int *shmat(int shmid, const void *daddr, int shmflag);​

 

  • shmid : 공유 메모리의 identifier
  • daddr : 프로세스 주소 공간 내의 부착 위치 ( NULL인 경우 시스템이 위치 결정함 )
  • shmflag :
    • SHM_RDONLY : 공유 메모리에 대해 '읽기'만 가능
    • 0 : 공유 메모리에 대해 읽기/ 쓰기 가능
  • return 값 : process 내의 유효주소 / 실패 : (void*) -1

 shmat을 이용한 공유 메모리 부착 예시

1. 512byte의 문자를 저장할 공유 메모리 생성 후 부착

buf1 = (char*)shmat(shmid1, 0, 0);

 

2. 10개의 정수를 저장할 공유 메모리 생성 후 부착

buf2 = (int*)shmat(shmid2, 0, 0);

 

3. sturct databuf의 데이터 5개를 저장할 공유 메모리 생성 후 부착

buf3 = (struct databuf*)shmat(shmid3, 0, 0);

 shmdt 시스템 호출

□ shmdt() : 공유 메모리 영역을 프로세스의 논리적 주소 공간으로부터 떼어냄

#include <sys/shm.h>
int shmdt(memprt);

 

  • memptr : 공유 메모리 영역에 대한 유효주소
  • return 값 : 0 or -1

 공유 메모리 사용 예시

1. 표준 입력으로 읽은 문자열을 공유 메모리 공간에 저장 후 출력

shmid1 = shmget(0111, 512, 0600|IPC_CREAT);
buf1 = (char*)shmat(shmid1, 0, 0);

n = read(0, buf1, 512);
wrtie(1, buf1, n);

 

2. 표준 입력으로 읽은 10개의 정수를 공유 메모리 공간에 저장 후 출력

shmid2 = shmget(0112, 10*sizeof(int), 0600|IPC_CREAT);
buf2 = (int*)shmat(shmid2, 0, 0);

for ( i = 0; i < 10; i++ )
	scanf("%d", buf2+i);
    
for ( i = 0; i < 10; i++ )
	printf("%d\n", *(buf2+i));

 

3. struct databuf의 데이터 중 d_nread에 10씩 더하기 /  struct databuf의 데이터 중 d_nread와 d_buf 출력

shmid3 = shmget(0113, 5*sizeof(struct databuf), 0600|IPC_CREAT);
buf3 = (struct databuf*)shmat(shmid3, 0, 0);

for ( i = 0; i < 5; i++ )
	(buf3+i)->d_nread += 10;

for ( i = 0; i < 5; i++ )
	printf("%d ... %s", (buf3+i)->d_nread, (buf3+i)->d_buf);

 


 shmctl 시스템 호출

□ shmctl :  공유 메모리를 제어하는데 사용

#include <sys/shm.h>
int shmctl(int shmid, int command, struct shmid_ds *shm_stat);

 

  • command :  수행할 작업 지정
    • IPC_STAT : 공유 메모리의 상태 정보를 읽어옴 ( shm_stat에 저장 )
    • IPC_RMID :  공유 메모리를 제거함 ( 즉시 삭제하는 것이 아니라, 현재 연결된 프로세스가 없을 때 제거됨 ) ( shm_stat은 NULL로 설정 )