수업 정리/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로 설정 )