: Create shared memory
int shmget(key_t key, int size, int shmflg);
return seg_id, if fail return -1
➡️ 주소는 절대적인 주소가 아닌, process안에서만 통용된다. physical주소로 mapping
➕ Parameter
key
: Key of shared memory segment
- IPC_PRIVATE : key를 IPC_PRIVATE로 설정하면, key값은 중복되지 않는 임의의 값으로 자동으로 생성
size
: memory block size
- 할당할 메모리의 byte단위 크기, 주로 Buffer size
shmflg
: flags
- S_IRUSR : User readable
- S_IWUSR : User writable
- IPC_CREAT : key에 해당하는 메모리가 없으면 공유메모리를 생성 ( 0666 )
- IPC_EXCL : key 값에 해당하는 공유 메모리가 있다면 실패 반환, 접근 막음
: Attach shared memory to address space of a process
: 공유 메모리를 마치 프로세스의 몸 안으로 첨부
void* shmat(int shmid, char *shmaddr, int shmflg);
return memory address, if fail return -1
➡️ void* : 특정 type에 국한 x
➕ Parameter
shmid
: shmget() 리턴으로 얻은 shmid(seg_id)
shmaddr
: mapping 위치 ( NULL : kernel이 알아서 지정 )
shmflg
: attach flags
: Detach shared memory from address space of process
: 프로세스에 첨부된 공유 메모리를 프로세스에서 분리
void shmdt(char *shmaddr);
return 0, if fail return -1
: Controls and deallocate a shared memory block
: 공유 메모리 정보 확인 / 변경 / 제거
shmctl(shmid, IPC_RMID, NULL);
IPC_RMID : RM(remove)ID
➡️ 명령 직후 삭제 x, 쓰는 process가 없을 때 (shm_attach == 0) 삭제 예약
: Process creates or open shared memory segment
int shm_open(const char *name, int oflag, mode_t mode);
return fd, if fail return -1
➕ Parameter
name
: 공유메모리 이름
oflag
: open flag
- O_RDONLY : Read only
- O_RDWR : Read and Write mode
- O_CREAT : Create if it does not yet exist
- O_EXCL : O_CREAT 지정했을 때, 공유메모리가 이미 존재하면 오류 반환
- O_TRUNC : 공유메모리가 이미 있으면, truncate it to zero bytes.
shmflg
: attach flags ( permission )
shm_fd = shm_open(name, O_CREAT | O_RDWR, 0666);
int shm_unlink(const char *name);
return 0, if fail return -1
→ 공유 메모리는 커널이 종료되기 전까지는 제거되지 않음
: Set the size of the object
int ftruncate(int fd, size_t length);
return 0, if fail return -1
➕ Parameter
fd
: 쓰기 mode로 설정된 fd (O_WRONLY, O_RDWR)
length
: 조정할 파일 size
ftruncate(shm_fd, 4096);
void mmap(void start, size_t length, int prot, int flags, int fd, off_t offset);
return 대응된 영역의 포인터, if fail return -1
➡️ fd로 지정된 파일(혹은 다른 객체)에서 offset을 시작으로 length바이트 만큼을 start주소로 대응시키도록 한다.
➕ Parameter
prot
: protection flag
- PROT_EXEC : 페이지 실행 가능
- PROT_READ : 페이지 읽기 가능
- PROT_WRITE : 페이지 쓰기 가능
- PROT_NONE : 페이지 접근 불가
flag
: 대응된 객체의 타입, 대응 옵션, 대응된 페이지 복사본에 대한 수정이 그 프로세스에만 보일 것인지, 다른 참조하는 프로세스와 공유할 것인지를 설정
- MAP_FIXED : 지정된 주소 이외의 주소를 선택하지 않음
- MAP_SHARED : 대응된 객체를 다른 모드 프로세스와 공유
- MAP_PRIVATE : 개별적인 대응을 만듬
shared_memory = mmap(0, 4096, PROT_WRTIE, MAP_SHARED, shm_fd, 0);
int munmap(void *start, size_t length);
return 0, if fail return -1
➕ Parameter
start
: 맵핑이 시작된 첫 번째 주소를 나타낸다.
→ mmap 함수의 return 값이다.
→ process 종료 시 자동으로 unmap
munmap(shared_memory, 4096);
typedef struct {
long type;
int index;
char content[MAX_LEN];
} Message;
: create a message queue
int msgget( key_t key, int msgflg );
return 메시지 큐 식별자, if fail return -1
➕ Parameter
key
: 시스템에서 다른 큐와 구별되는 번호
msgflg
: 옵션
msqid_p2c = msgget((key_t)p2c_key, IPC_CREAT | 0666);
msqid_c2p = msgget((key_t)c2p_key, IPC_CREAT | 0666);
: send a message to a message queue
int msgsnd( int msqid, const void *msgp, size_t msgsz, int msgflg );
return 0, if fail return -1
➕ Parameter
msqid
: 메시지 큐 식별자
msgp
: 전송할 자료
msgsz
: 전송할 자료의 크기typedef struct { long type; int index; char content[MAX_LEN]; } Message;
- 전송 데이터는 long 값을 첫번째에 가지고 있어, 원하는 데이터만 걸러낼 수 있다. 따라서, 데이터의 크기에 long 값이 반드시 들어가기 때문에 type을 나타내는 long크기는 제거한다.
➡️ sizeof(msg) - sizeof(long)
msgflg
: 동작 옵션
- 전송 실패시 0은 큐에 공간이 생길 때까지 wait
- IPC_NOWAIT은 바로 -1을 리턴
Message out_msg;
size_t msg_size = sizeof(Message) - sizeof(long);
out_msg.type = MSG_P2C;
out_msg.index = 0;
int res_snd = msgsnd(p2c, &out_msg, msg_size, 0);
if(res_snd == -1)
fprintf(stderr, "Failed to send the expression to the child\n");
: receive a message from a message queue
ssize_t msgrcv( int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg );
return data size, if fail return -1
➕ Parameter
msqp
: 수신한 데이터
msgtyp
: 메시지 큐에 있는 데이터 중 어떤 데이터를 읽어 들일지에 대한 옵션
- 0이면 큐의 첫번째 자료를 read
- 양수일 경우, 양수로 지정한 값과 동일한 데이터 타입의 자료 중 첫번째 Read
- 음수일 경우, 음수 값을 절대 값으로 바꾼 후, 이 절대값과 같거나 가장 작은 데이터 타입의 데이터를 Read
msgflg
: 동작 옵션
- 전송 실패시 0은 큐에 공간이 생길 때까지 wait
- IPC_NOWAIT은 바로 -1을 리턴
Message in_msg;
size_t msg_size = sizeof(Message) - sizeof(long);
int res_rcv = msgrcv(p2c, &in_msg, msg_size, 0, 0);
if(res_rcv == -1)
fprintf(stderr, "Failed to receive the result from the child\n");
메시지큐 상태 정보 · 변경 · 삭제
int msgctl ( int msqid, int cmd, struct msqid_ds *buf )
return 0, if fail return -1
➕ Parameter
cmd
- IPC_RMID : 메시지 큐를 삭제 ➡️ buffer가 필요없으므로 0으로 지정
- IPC_STAT : 현재 상태를 buf에 저장
- IPC_SET : 현재 상태를 buf 값으로 변경
buf
: 메시지 큐 정보를 받을 버퍼
msgctl(msqid_p2c, IPC_RMID, 0);
msgctl(msqid_c2p, IPC_RMID, 0);