[CS] IPC share memory

윤동환·2023년 4월 5일
0

Computer Science

목록 보기
8/10
post-thumbnail

공유 메모리 함수

shmget()

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

System V 공유메모리 새 메시지 대기열을 생성하거나 기존 대기열에 액세스하기 위해 shmget() 시스템 호출이 사용됩니다.

매개변수

key : 공유 메모리의 식별자를 얻기위한 고유한 값
size : 공유메모리를 할당 받을 size
shmflg : IPC_CREAT(새로운 키면 식별자 새로 생성), IPC_EXCL(이미 존재하는 키면 오류 발생) 두가지 설정 가능

반환 값

RETURNS: 성공 시 공유 메모리 세그먼트 식별자
오류 시 -1 : errno

errno

  • EINVAL(잘못된 세그먼트 크기가 지정됨)
  • EEXIST(세그먼트 존재, 생성 불가)
  • EIDRM(세그먼트가 삭제 표시되었거나 제거됨)
  • ENOENT(세그먼트가 존재하지 않음)
  • EACCES(허가 거부됨)
  • ENOMEM(세그먼트를 생성할 메모리가 부족함)

예시

int open_segment( key_t keyval, int segsize )
{
        int     shmid;
        
        if((shmid = shmget( keyval, segsize, IPC_CREAT | 0660 )) == -1)
        {
                return(-1);
        }
        
        return(shmid);
}

shmat()

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

shmid로 식별되는 System V 공유 메모리 세그먼트를 호출 프로세스의 주소 공간에 연결합니다. 첨부된 주소는 다음 기준 중 하나를 사용하여 shmaddr에 의해 지정됩니다.

매개변수

shmid : shmget 함수로 생성한 공유 메모리 식별자
shmaddr : 공유메모리를 연결할 주소
shmflg : 공유 메모리에 대한 권한
SHM_EXEC(Linux 전용) - 32768 : 세그먼트의 내용이 실행되도록 허용합니다. 발신자는 반드시 세그먼트에 대한 실행 권한이 있어야 합니다.
SHM_RDONLY - 4096 : 읽기 전용 액세스를 위해 세그먼트를 연결합니다.
SHM_REMAP(Linux 전용) - 16384 : 이 플래그는 세그먼트의 매핑이 대체되어야 함을 지정합니다.
이 경우 shmaddr은 NULL이 아니어야 합니다.
SHM_RND : 전달된 주소를 강제로 페이지 정렬(가장 가까운 페이지 크기로 내림)할 수 있습니다.

기준

  • shmaddr이 null 일 때 : (권장되는 방식)
    시스템은 적절한(사용되지 않은) 정렬된 페이지주소를 선택합니다.

  • shmaddr이 null이 아니고, SHM_RND가 shmflg에 지정된 경우 :
    첨부는 shmaddr 주소와 같거나, SHMLBA의 배수로 반내림하여 shmaddr와 가장 가까운 주소에서 발생합니다.

  • 그렇지 않으면 shmaddr은 첨부가 발생하는 페이지 정렬 주소여야 합니다.
    (주소를 지정할 수 있지만 일반적으로 독점 하드웨어를 용이하게 하거나 다른 앱과의 충돌을 해결하는 데만 사용)

예시

shmctl()

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

반환 값

반환: 성공 시 0
오류 시 -1: errno = EACCES(읽기 권한이 없고 cmd는 IPC_STAT임)
EFAULT(buf가 가리키는 주소는 IPC_SET에서 유효하지 않으며 IPC_STAT 명령)
EIDRM(검색 중에 세그먼트가 제거됨)
EINVAL(shmqid 유효하지 않음)
EPERM(IPC_SET 또는 IPC_RMID 명령이 실행되었지만 호출 프로세스에 세그먼트에 대한 쓰기(변경) 액세스 권한이 없음)

유효 명령

  • IPC_STAT
    세그먼트에 대한 shmid_ds 구조를 검색하고 buf 인수의 주소에 저장합니다.

  • IPC_SET
    세그먼트에 대한 shmid_ds 구조의 ipc_perm 구성원 값을 설정합니다. buf 인수에서 값을 가져옵니다.

  • IPC_RMID
    제거할 세그먼트를 표시합니다.

shmid_ds 구조체

커널은 주소 지정 공간 내에 존재하는 각 공유 메모리 세그먼트에 대해 특수한 내부 데이터 구조를 유지합니다.
이 구조는 shmid_ds 유형 이며 다음과 같이 linux/shm.h 에 정의되어 있습니다.

이 구조에 대한 작업은 특별한 시스템 호출에 의해 수행되며 직접 수정해서는 안 됩니다.

매개변수 buf는 shmid_ds 구조체의 포인터입니다. <sys/shm.h>에 정의되어 있습니다.

struct shmid_ds {
 	struct ipc_perm shm_perm;    /* Ownership and permissions */
 	size_t          shm_segsz;   /* Size of segment (bytes) */
 	time_t          shm_atime;   /* Last attach time */
 	time_t          shm_dtime;   /* Last detach time */
 	time_t          shm_ctime;   /* Last change time */
	 pid_t           shm_cpid;    /* PID of creator */
 	pid_t           shm_lpid;    /* PID of last shmat(2)/shmdt(2) */
 	shmatt_t        shm_nattch;  /* No. of current attaches */
 	...
 };

내부 변수들

  • shm_perm
    이것은 linux/ipc.h 에 정의된 ipc_perm 구조 의 인스턴스입니다 . 여기에는 액세스 권한을 포함하여 세그먼트에 대한 권한 정보와 세그먼트 생성자에 대한 정보(uid 등)가 포함됩니다.

  • shm_segsz
    세그먼트의 크기(바이트 단위로 측정됨).

  • shm_atime
    마지막 프로세스가 세그먼트를 첨부한 시간입니다.

  • shm_dtime
    마지막 프로세스가 세그먼트를 분리한 시간입니다.

  • shm_ctime
    이 구조에 대한 마지막 변경 시간(모드 변경 등).

  • shm_cpid
    생성 프로세스의 PID입니다.

  • shm_lpid
    세그먼트에서 작동할 마지막 프로세스의 PID입니다.

  • shm_nattch
    현재 세그먼트에 연결된 프로세스 수입니다.

ipc_perm 구조체

ipc_perm 구조체는 아래와 같이 정의되어있습니다.

struct ipc_perm {
	key_t          __key;    /* Key supplied to shmget(2) */
	uid_t          uid;      /* Effective UID of owner */
	gid_t          gid;      /* Effective GID of owner */
	uid_t          cuid;     /* Effective UID of creator */
	gid_t          cgid;     /* Effective GID of creator */
	unsigned short mode;     /* Permissions + SHM_DEST and SHM_LOCKED flags */
	unsigned short __seq;    /* Sequence number */
};

shmdt()

공유메모리의 연결을 해제합니다.
프로세스에서 공유 메모리 세그먼트가 더 이상 필요하지 않으면 이 시스템 호출을 호출하여 분리해야 합니다.
이것은 커널에서 세그먼트를 제거하는 것과는 다릅니다!
분리가 성공한 후 연관 shmid_ds 구조의 shm_nattch 구성원이 1씩 감소합니다. 이 값이 0에 도달하면 커널은 세그먼트를 물리적으로 제거합니다.

char *attach_segment( int shmid )
{
        return(shmat(shmid, 0, 0));
}

반환 값

반환값: 오류 시 -1: errno

errno

  • EINVAL(잘못된 연결 주소 전달됨)

Reference

https://www.ibm.com/docs/ko/aix/7.3?topic=s-shmat-subroutine
https://noirstar.tistory.com/8
https://tldp.org/LDP/lpg/node21.html

profile
모르면 공부하고 알게되면 공유하는 개발자

0개의 댓글