Language/CㅣC++

[C/C++]공유메모리 함수 shmget(),shmat(),shmdt(),shmctl()

NoirStar 2017. 5. 30. 00:35

해커스쿨의 ftz 워게임을 풀던중 공유메모리에 관한 문제가있었다.. 처음봤을때는 이게뭐지... 하다가 키워드 중심으로 검색을 해봤더니 공유 메모리를 생성하고 관리하는 함수들이 있었다. 넘나 어려운것 ㅡ.ㅡ;;

 

공유메모리란 한마디로 여러 프로세서들이 함께 사용하는 메모리 이다. 

프로세스들이 메모리 자체를 공유하게 됨으로써 데이터복사와 같은 오버헤드가 발생하지않아서 속도가 빠르다고한다.

 

 

이함수들을 쓰기위해서는 sys/ipc.h , sys/shm.h 두 헤더파일을 include 해준다. 

동작방식은 간단하더라.. shmget() 으로 공유메모리를 구별하는 key값과 크기, 옵션을 부여하고 공유메모리를 생성한다.

shmat() 으로 프로세스에 메모리 세그먼트를 붙이고 , shmctl() 함수로 공유메모리를 제어한다. 

 

 

 

    int shmget(key_t key, int size, int shmflg)

 

공유메모리를 생성하는 shmget 함수이다. 

key_t key : 공유메모리를 구별하는 key값이다.

int size : 공유메모리 크기를 결정한다.

int shmflg : 여러가지 옵션을 추가할 수 있다.

- IPC_CREATE : 퍼미션 0666을 설정한다. 첫번째인수 key에 해당하는 메모리가 없으면 공유메모리를 생성한다.

- IPC_EXCL : 공유메모리가 있으면 실패로 반환하고 접근하지못하게 한다. 

 

공유메모리의 shmid를 int형으로 리턴하고 실패시에는 -1 이 리턴된다.

 

 

    void *shmat(int shmid, const void *shmaddr, int shmflg)

 

프로세서에 공유메모리 세그먼트를 붙이는 함수이다.

int shmid : shmget 함수에 의해 반환된 int형의 식별자이다.

const void *shmaddr : 일반적으로 NULL 지정. 커널에 매핑되지않은 곳을 자동으로 찾아서 붙여준다.

int shmflg : 여러가지 옵션을 추가할 수 있다.

- SHM_RDONLY : 공유메모리를 읽기전용으로 설정한다.

- SHM_RND : shmaddr 이 NULL이 아닐경우에만 쓴다. shmaddr을 반올림하여 메모리경계에 맞춘다.

 

이 함수는 shmid에 대한 주소를 리턴해주고 , 실패시 -1 리턴된다.

 

     int shmdt(const void *shmaddr)

 

프로세서에서 공유메모리를 분리하는 함수이다.

const void *shmaddr : 분리할 공유메모리 주소다.

 

이 함수는 성공시 0 을 , 실패시 -1 을 반환해준다.

 

 

     int shmctl(int shmid, int cmd, struct shmid_ds *buf)

 


int shmid : 공유메모리를 구별하는 식별자이다.

int cmd : 여러가지 제어명령이 있다.

- IPC_RMID : 지정된 공유메모리 제거, 구조체 제거

- IPC_SET : 공유메모리 공간에 대한 사용자권한 변경을 위해서 사용된다.

- IPC_STAT :  현재 공유메모리 정보를 buf로 지정한 메모리에 저장한다.

- SHM_LOCK : 공유메모리 세그먼트를 잠근다.

- SHM_UNLOCK : 공유메모리 세그먼트를 잠금해제 한다.

struct shmid_ds *buf : 공유메모리 정보를 구하기 위한 버퍼포인터이다.

 

 

밑은 간단한 예제 소스입니다. 

#include<sys/ipc.> 
#include<sys/shm.h> 
#define KEY_NUM 1234 
#define MEM_SIZE 1024  


int main() {

	int shmid;
	void *address;
	if( (shmid = shmget(KEY_NUM,MEM_SIZE,IPC_CREAT | 0666)) != (-1) ) {
    
		address = shmat(shmid,NULL,0);
		printf("공유메모리 만들기 성공 ! \n");
		printf("shmid = %d\n",shmid);
		printf("공유메모리 주소 : %p", address);
        
	} else printf("에러 입니다 !\n");
	return 0;
    
}