shmctl(2)

#include <sys/ipc.h>
#include <sys/shm.h>

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

shared memory의 정보를 읽거나, 정보를 변경, 할당된 shared memory segment를 삭제합니다.

 

 

파라미터

shmid
    - shmget(2) 함수가 return한 shared memory segment id입니다.
cmd
    - shared memory의 상태를 조회/변경 및 할당된 shared memory를 삭제하는 함수입니다.

 IPC_STAT: open된 파일의 정보를 얻는 fstat(2)함수처럼 shmget(2)으로 생성된 shared memory의 
            정보를 조회하여 buf에 저장합니다. struct shmid_ds는 argument buf를 참조하세요.
 IPC_SET : open된 파일의 권한 변경을 하는 fchmod(2)함수와 owner를 변경하는 fchown(2)함수 처럼, 
           shmget(2)으로 생성된 shared memory의 shm_perm.uid, shm_perm.gid, shm_perm.mode 정보를 변경합니다.
 IPC_RMID: shmid를 생성한 shared memory의 key와 관련된 shared memory를 system에서 삭제합니다. 
           argument buf에 설정된 값은 무시되니 NULL을 설정합니다. 
buf
    -IPC_STAT, IPC_SET에서 사용하는 구조체

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 */
    ...
};

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 */
};

 

RETURN

-1이 아님
    - 정상적으로 처리되었습니다.
    
-1
    - 오류가 발생하였으며, 상세한 오류는 errno에 저장됩니다.

 EACCES : cmd가 IPC_STAT일 때에 shmid에 대해서 읽기 권한이 없습니다.
 EFAULT : cmd가 IPC_SET 또는 IPC_STAT의 경우 buf가 접근할 수 없는 주소입니다.
 EIDRM  : shmid가 삭제된 id입니다.
 EINVAL : shmid가 유효하지 않은 ID이거나 cmd가 유효하지 않은 명령어입니다.
 EOVERFLOW : cmd가 IPC_STAT일 때에 GID, UID값이 너무 크서 buf에 저장할 수 없습니다.
 EPERM  : cmd가 IPC_SET 또는 IPC_RMID일 때에 현재 실행중인 프로셋의 effective user ID가 
          shared memory를 생성한 user가 아니거나 owner가 아니어서 변경권한이 없습니다.

 


활용 예제

 

#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;
    }

    ......
   
    /* shared memory를 더 사용하지 않는다면 */

    if(shmdt(shm_data) == -1) {
        perror("shmdt failed ");
        return 1;
    }

    ....
    
    /* 모든 프로세스에서 key에 대한 접근을 할 수 없도록 삭제함. */
    if(shmctl(shmid, IPC_RMID, NULL) == -1) {
        perror("shmctl failed ");
        return 1;
    }
  
    return 0;
}

 

블로그 이미지

사용자 자연&사람

행복한 개발자 programmer since 1995.

댓글을 달아 주세요