음…우선 공유메모리가 무엇인지부터 알아야겠다 한 공간을 여러 프로세스가 공유 한다는 것으로만 알았지 이런 실습적인 부분은 아직 본적이 없어서…;;
자 그럼 이제 공유하고 여럿이서 사용할 수 있다는 것도 알았다
그럼 어떻게 공유를 하고 사용할 것인가
우선 공유메모리 함수부터 봐야 알 것 같다
#include <sys/ipc.h>
#include <sys/shm.h>
Shmget() – 공유메모리 생성 접근
Int shmget(key_t key, int size, int shmflg);
Key_t key : 공유 메모리를 구별하는 식별 번호
Int size : 공유 메모리 크기
Int shmflg : 동작 옵션
1) IPC_CREATE
: key에 해당하는 공유 메모리가 없다면 새로 생성한다
IPC_CREAT값을 입력한 후 |(pipe) 연산자를 덧붙여 허용권한을 설정한다
만약있다면 무시하며 생성을 위해 접근 권한을 지정해 주어야 한다
2) IPC_EXCL
: 공유 메모리가 이미 있다면 실패로 반환하여 공유 메모리에 접근하지 못한다 이 옵션이 없어야 기존 공유 메모리에 접근할 수 있다
반환 -1 : 실패
Shmget() 함수는 공유 메모리의 확인자(ID)값을 리턴한다
Ex) shmget(7530, 1028, IPC_CREAT|0660);
Shmat() – 공유 메모리를 프로세스에 첨부
Shmat()는 공유메모리 식별자인 shmid에 공유 메모리 세그먼트를 붙이기 위해서 사용한다
붙이는 영역은 shmaddr로 결정할 수 있다. 만약 shmaddr가 NULL이라면 시스템은 적당한 사용하지 않는 메모리 영역을 붙이게 된다
#include <sys/type.h>
#include <sys/shm.h>
Void *shmat(int shmid, const void* shmaddr, int shmflg);
Int shmid : 공유 메모리를 구별 하는 식별번호
Void *shmaddr : 첨부되는 어드레스 주소, 일반적으로 NULLdmf 지정(0으로 설정하면 커널에 매핑되지 않은 지역을 자동으로 찾는다)
Int shmflg : 동작옵션
SHM_RDONLY : 읽기전용으로
SHM_RND : shmaddr이 NULL이아닌 경우일때만 사용되며, shmaddr을 반올림하여 메모리 페이지 경계에 맞춘다
반환(void *)-1 : 실패
Shmat() 함수는 해당 공유 메모리 id 값에 대한 어드레스를 리턴해준다
Ex) shmat(shmid, NULL, 0);
Shmdt() – 공유 메모리를 분리
Shmdt()는 공유 메모리 영역으로부터 shmaddr주소를 분리시키기 위해서 사용된다
공유 메모리 영역의 분리는 shmat 시스템 콜로 연결된 값과 동일한 shmaddr을 가지고 있는 연결된 영역들 중 하나여야 한다.
#include <sys/type.h>
#include <sys/shm.h>
Shmdt(const void *shmaddr);
- Void *shmaddr : 분리할 공유 메모리 주소
반환 -1 : 실패(0 : 공유 메모리 분리 성공)
Shmctl() – 공유 메모리를 제어
Shmctl()은 공유메모리에 대한 정보를 구하거나 변경 또는 제거하기 위해서 사용한다
#include <sys/ipc.h>
#include <sys/shm.h>
Int shmctl(int shmid, int cmd, struct shmid_ds *buf);
Shmid – 공유 메모리 식별 번호
Cmd – 제어 명령
Shmid_ds *buf : 공유 메모리 정보를 구하기 위한 버퍼 포인터
Cmd 제어명령
- IPC_RMID : shmid로 지정한 공유 메모리를 제거하고 구조체를 제거한다
- IPC_SET : 공유 메모리의 정보 내용중 shm_perm.uid, shm_perm.gid, shm_perm.mode 값을 세번째 인자로 지정한 값으로 치환한다
- IPC_STAT : 현재 공유 메모리의 정보를 buffh 지정한 메모리에 저장한다
- SHM_LOCK : 공유 메모리 세그먼트를 잠근다
- SHM_UNLOCK : 공유 메모리 세그먼트의 잠금을 해제한다
나는 아직 여기까지 밖에 이해하지 못했다 이민재님의 글을 보면서 따라해 볼것이다
1.공유 메모리 영역을 7530을 키값으로 가진 것을 만든다
2.만들어져 있다면 그 영역을 읽을 것이다
3.읽는데 실패할 경우 실패했다고 출력한다
4.읽는데 성공할 경우 읽어서 화면에 출력해준다
5.종료한다
이걸 코드에 맞게 상세화해보자면
2. 공유메모리 영역을 7530을 키값으로 가진 것을 만든다
키 값은 7530
영역 크기는 1024
공유 메모리를 생성하고 생성되어있을 경우 권한 부여
shmget(7530, 1024, IPC_CREAT|0660);
생성에 실패 했을 경우
Printf로 생성실패 메시지 출력
공유 메모리를 프로세스의 가상 메모리 공간에 부착한다
공유 메모리를 구별 하는 식별번호로 shmid를 사용한다
나머지 두 값은 NULL과 0을 사용한다
Void *shmat(shmid, (void *)0, 0);
공유 메모리의 값을 읽는다
공유 메모리 값 읽기에 실패했을 경우 에러를 출력한다
Memcpy로 버퍼에 메모리를 복사한 후에 출력한다
그리고 shmdt로 공유메모리를 분리한다
종료한다
소스코딩은 아직 내가 부족한게 많으므로 따라하려 하던 중 나의 소스를 만들었다 ㅋㅋㅋ
#include <stdio.h>
#include <sys/shm.h>
#include <sys/types.h>
int main(){
int shmid;
void *shared_memory = (void *)0;
char buf[1024];
shmid = shmget((key_t)7530, 1024, 0666);
if(shmid == -1){
printf("shmget failed : ");
exit(0);
}
shared_memory = shmat(shmid, (void *)0, 0);
if(shared_memory == (void *)-1){
printf("shmat failed : ");
exit(0);
}
memcpy(buf, shared_memory, 1024);
printf("%s",buf);
shmdt(shared_memory);
return 0;
}
코딩하고 실행해봤다
Phantom@TeamH4C