Linux/Linux_programing

System V 공유메모리 시스템 콜

sosal 2011. 3. 22. 12:03
반응형

/*
 http://sosal.tistory.com/
 * made by so_Sal
 */

System V IPC 시스템콜은 프로세스간의 통신을 말한다.
우선 여기서 다룰 shm* 계열 함수들은 Shared memory 를 이용한
communication models 계열로 정의된다.
(pipe , socket 등은 Message passing model 이다.)



그림 : (a) : Message passing.
그림 : (b) : Shared memory.

(a)는 커널이 Responsible하게 관리하므로 좀더 안전하다고 볼 수 있다.
(b)는 커널은 전혀 관여하지 않고 오로지 프로그래머에게 전적으로 책임이 있게 되는데
보안에 취약하며 굉장히 strict 하게 구현되는것을 요구한다.

shmget : 공유메모리 세그먼트 획득 - allocate a shared memory segment
shmat : 공유메모리에 세그먼트를 프로세스의 메모리에 붙인다. - attach the segment
shmdt : 공유메모리를 프로세스 메모리에서 제거. - detach the segment.
shmctl : 공유메모리 제어 - remove the shared memory segment.

#include <sys/ipc.h>

#include <sys/shm.h>

       int shmget(key_t key,  : Key of shared memory segment
                       int size,     : size of shared memory segment
                       int shmflg   : flags.
                                     );

파일 시스템콜을 사용할 때, file descriptor를 사용하는 것처럼,
공유메모리를 이용한 IPC 통신에서 key라는 매개변수가 메시지를 전달하는 매개체가 된다.
Key : 공유메모리를 유일하게 구분하는 식별번호.
size는 공유메모리의 크기이다.
Flags의 종류들 -
IPC_CREAT : key에 해당하는 새로운 세그먼트를 만든다. 존재할 경우 그 key값을 리턴받는다.
IPC_EXCL   : CREAT 만을 보장한다. 이미 세그먼트가 생성되어있다면 실패를 반환
IPC_PRIVATE : IPC_CREAT와 같이 사용하게 되는데, 자신만이 attach 할 수 있는 메모리를
                      만들고자 할 때 사용된다. 이미 key 가 존재하는 세그먼트라면 실패를 반환.





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

       void *shmat(int shmid,                 : shmget() 리턴으로 얻은 세그먼트 식별자
                         const void *shmaddr, : 첨부되어지도록 기대되는 메모리 주소. (보통 NULL)
                         int shmflg                  : attach flags.
                                      );

원하는 char* 변수를 두어, 그 주소값을 받도록 한다.
Flags의 종류들.
SHM_RDONLY : 공유메모리에 대해 오로지 읽기 권한만 얻게된다.
SHM_RND : shmaddr 을 사용자가 지정하였을 때 사용하는 flag로,
                  공유되는 메모리 세그먼트와와 프로세스 내부 어드레스를 시스템이 관리하도록 함
SHM_REMAP : the mapping of the segment should
                      replace any existing mapping in the range starting at shmaddr

이 함수로부터 얻어진 주소를 통해 sprintf 혹은 printf 등으로 메시지를 쓰고 읽는다.

#include <sys/ipc.h>

#include <sys/shm.h>
       int shmdt(const void *shmaddr);

shmat로부터 얻어진 주소를 detach 한다.



#include <sys/ipc.h>

#include <sys/shm.h>
       int shmctl(int shmid,                     : shmget() 리턴으로 얻은 세그먼트 식별자
                      int cmd,                        : command.
                      struct shmid_ds *buf      : 명령어 실행에 필요한 구조체 자료.
                                                    );

IPC_STAT : 공유 메모리 세그먼트에 관한 정보를 버퍼 buf에 복사하기 위해 사용된다. 
                  사용자는 공유 메모리 세그먼트에  read 접근을 해야 한다.

IPC_SET : shm_perms필드의 uid, gid, or mode 멤버들에 대한 사용자 변경을 적용하기 위해 사용된다.  
                mode의 하위 9비트들만이 사용된다.  shm_ctime 멤버 또한 갱신된다.
                사용자는 소유자, 생성자, 또는 슈퍼 유저이어야 한다.

IPC_RMID : 파괴될 세그먼트를 표시하기 위해 사용된다. 실제로는 마지막 분리후에 파괴된다.  
                 (즉, 관련된 shmid_ds 구조체 의shm_nattch 멤버가  0일때) 사용자는 소유자, 생성자 또는
                 슈퍼 유저이어야 한다. 사용자는 세그먼트가 결국 파괴 되었다는것을 보장해야 한다.
                 그렇지 않으면 폴트가 난 페이지들은 메모리나 스왑에 남아 있을것이다.

                 게다가, super-user는 다음 cmds와 관련된 공유 메모리 세그먼트의스왑핑을
                 금지하거나 허용할수 있다: (Linux only)

SHM_LOCK  : 공유 메모리 세그먼트의 스와핑을 막는다.
                    사용자가 있어야 하는 페이지들을 잠금후에 요구한다면 위반이다.

SHM_UNLOCK : 공유 메모리 세그먼트에 대한 스와핑을 허용한다.


IPC_INFO, SHM_STAT 그리고 SHM_INFO 는 할당된 자원들에 관한 정보를 제공하는 ipcs(8) 의 의해 사용된다.
미래에, 이것 들 은proc 파일 시스템 인터페이스를 위해서 필요할때 수정되거나 이동될수 있다.


            struct shmid_ds {
                 struct    ipc_perm shm_perm;  /* 퍼미션 */
                 int  shm_segsz;                     /* 세그먼트의 크기(bytes) */
                 time_t    shm_atime;               /* 마지막 접근 시간 */
                 time_t    shm_dtime;               /* 마지막 제거 시간 */
                 time_t    shm_ctime;               /* 마지막 변경 시간 */
                 unsigned short shm_cpid;       /* 생성자의 pid */
                 unsigned short shm_lpid;        /* 마지막으로 작동한 프로세스의 pid */
                 short     shm_nattch;              /* 현재 접근한 프로세스의 수 */

                 /* 다음은 개별적이다 */
                 unsigned short   shm_npages;  /* 세그먼트의 크기(pages) */
                 unsigned long   *shm_pages;
                 struct shm_desc *attaches;      /* 접근을 위한 기술자들 */
            };
// Linux man



참고서적 : operating system concepts. 8 edition . Silberschatz, B.Galvin, Gagne.
               Advanced Unix programming. MARK J.ROCHKIND