C언어 header/sys | shm.h
shmat(2) - System V shared memory segment를 pointer로 지정하기
자연&사람
2019. 9. 29. 22:01
반응형
shmat(2)
#include <sys/types.h>
#include <sys/shm.h>
void *shmat(int shmid, const void *shmaddr, int shmflg);
shmat(2)는 shmid에 mapping된 System V shared memory segment를 C언어의 pointer 변수에 attach하는 함수입니다.
return되는 attach할 memory 주소는 shmaddr에 의해서 정해집니다.
shmaddr이 NULL이면 system이 사용하지 않는 적당한 주소에 attach하여 return합니다.
shmaddr이 NULL이 아니고 shmflg가 SHM_RND이면, shmaddr이 SHMLBA의 배수이면 shmaddr에 그렇지 않으면 shmaddr보다 작은 주소 중에서 SHMLBA의 배수인 가장 가까운 memory 번지에 attach됩니다. 그렇지 않으면, page의 시작 위치 주소에 attach됩니다.
shmflg가 SHM_RDONLY이면, shared memory segment는 읽기 전용으로 메모리가 attach됩니다. 그렇지 않으면 shared memory segment에 대해서 read / write가 가능하도록 attach됩니다. 쓰기 전용으로는 attach될 수 없습니다.
fork(2)된 child는 attach된 메모리를 공유합니다. execve(2)를 호출하면 자동으로 detach됩니다. 프로세스가 종료되면 자동으로 attach된 pointer는 detatch됩니다.
파라미터
shmid
- shmget(2)함수에 의해서 return된 shared memory segment id
shmaddr
- attach될 메모리 주소 값을 설정합니다.
- shmflg의 값과 shmaddr 주소값에 의해서 attach된 주소를 return합니다.(설명 참조)
shmflg
- SHM_RND, SHM_RDONLY 또는 0을 설정합니다. (설명 참조)
RETURN
(void *) -1이 아님
- 정상적으로 attach된 메모리 번지 값
정상적으로 shmat()호출되면 shmctl(2)에 의해서 얻는 shmid_ds 구조체의 아래 항목의 값을 갱신합니다.
- shm_atime 를 현재시간으로 갱신합니다.
- shm_lpid를 현재 process id로 갱신합니다.
- shm_nattch 값을 1증가시킵니다.
(void *) -1
- 오류가 발생하였으며, 상세 오류 내용은 errno 전역변수에 설정됩니다.
EACCES : 접근권한이 없습니다. shmget(2)함수에서 설정한 권한이 shmat(2)함수를 호출한
process를 실행한 user에게 권한이 없습니다.
EIDRM : shmid가 삭제된 id입니다.
EINVAL : shmid가 유효하지 않거나 shmaddr이 유효하지 않습니다.
또는 shmaddr에 segment를 attach할 수 없거나, shmflg가 SHM_REMAP으로 설정되었는 데,
shmaddr값이 NULL입니다.
ENOMEM : memory를 할당할 수 없습니다.
활용 예제
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdlib.h>
......
int main(int argc, char **argv)
{
int shmid;
int mem_size;
key_t shm_key;
struct my_data_t *shm_data;
......
/* shared memory용 IPC key를 생성함 */
if((shm_key = ftok("~/mywork", 'H')) == -1) {
perror("shared memory key 생성 오류");
return 1;
}
mem_sie = sizeof(struct my_data_t) * 1000;
shmid = shmget((key_t)shm_key, mem_size, 0600 | IPC_CREAT);
if (shmid == -1) {
perror("shmget failed ");
return 1;
}
/* 생성된 shared memroy를 참조함 */
shm_data = shmat(shmid, (void *)0, 0);
if (shm_data == (void *)-1) {
perror("shmat failed ");
return 1;
}
......
return 0;
}
반응형