-
시스템 프로그래밍 실습 9주차 : System V IPCSystem Programming/Ubuntu Linux 2021. 10. 22. 20:44728x90
시스템 프로그래밍 실습 9주차 : System V IPC
[목차]
- System V IPC interface
- Message Queue
- Shared Memory
System V IPC interface
시스템 V IPC
- 시스템 V 계열 유닉스에서 개발해 제공하는 프로세스 간 통신방법
- 메시지 큐, 공유 메모리, 세마포어공통 요소
- 시스템 V IPC를 사용하기 위해서는 IPC 객체를 생성해야 함
- IPC 객체를 생성하기 위해 공통적으로 사용하는 기본 요소는 키와 식별자=> IPC 객체를 생성하면 다음과 같은 IPC 공통 구조체가 정의된다
- ftok() : 키 생성 함수!
#include <sys/types.h> #include <sys/ipc.h> key_t ftok(const char *pathname, int proj_id);
pathname
- 실제로 존재하고 access가능한 파일 또는 디렉토리
- 상대 path이든 절대 path이든 실제로 같은 디렉토리 또는 파일이면 pathname의 문자열이 달라도 같이 인식됨
예). /usr/downman/data 와 ~/data가 실제 같은 디렉토리이면 같은 값임.
즉, ftok("/usr/downman/data", 'S') == ftok("~/data", 'S')
proj_id
- 같은 path에 대해서 구분하기 위한 값으로 하위 8bit값만 사용됩니다.
- 0은 사용할 수 없으며, 하위 8bit만 사용되므로 'M', 'S' 등과 같이 문자를 사용할 수도 있습니다.- ctl() : 시스템 V IPC 제어 함수
- 시스템 V IPC 정보 검색 : ipcs 명령
- 시스템 V IPC 정보 삭제 : ipcrm
https://jihooyim1.gitbooks.io/unixbasic/content/contents/10.html
https://codingsmu.tistory.com/63
Message Queue
(1) 정의
- 메모리를 사용한 PIPE이다.
- 구조체 기반으로 프로세스 간 통신을 한다.
(2) 구조
- FIFO 구조
- msgtype에 따라 다른 구조체를 가져올수 있다.
(3) 사용시기
- 프로세스간 다양한 통신을 할 때 사용 할수 있다.
(4) 유의사항
- 커널에서 제공하는 Message queue 이기 때문에 EnQueue 하는데 제한이 존재 한다.
- 각 메시지에는 메시지 유형이 있어 수신 프로세스는 어떤 유형의 메시지를 받을 것인지 선택 가능
- 각 메시지의 최대 크기는 제한되어 있음
- 프로세스 A가 message queue에 메시지를 보내면
- kernel에 있는 message queue가 가지고 있다가
- 프로세스 B가 읽어갈 수 있다
- msgbuf라는 임의의 구조체를 만들어줘서 message queue에 보내줘야 한다!
- 무조건 맨 처음에는 msgtype이 들어있어야 한다
- msgsnd할 때는 msgtype을 설정해줘야 하며, msgrcv에서는 원하는 msgtype을 읽어올 수 있다!
ex)
Message Queue 관련 함수 4가지
1. msgget() : message queue 생성
int msgget(key_t key, int msgflg;
- key : IPC_PRIVATE 또는 ftok로 생성한 키값
- msgflg : 플래그와 접근 권한 지정
- IPC_CREAT : 새로운 키면 식별자를 새로 생성
- IPC_EXCL : 이미 존재하는 키면 오류 발생
- 메시지 큐 식별자를 리턴(msqid_ds 구조체)2. msgsnd() : message 전송
int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
- msqid : 메시지 큐 식별자
- msgp : 메시지 버퍼 주소
- msgsz : 메시지 버퍼 크기
- msgflg : 블록모드(0)/비블록 모드(IPC_NOWAIT)3. msgrcv() : message 수신
ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long int msgtyp, int msgflg);
- msqid : 메시지 큐 식별자
- msgp : 메시지 버퍼 주소
- msgsz : 메시지 버퍼 크기
- msgtyp : 읽어올 메시지 유형
- msgflg : 블록모드(0)/비블록모드(IPC_NOWAIT)
- msgtyp에 지정할 값
- 0 : 메시지 큐의 다음 메시지를 읽어온다.
- 양수 : 메시지 큐에서 msgtyp로 지정한 유형과 같은 메시지를 읽어온다.
- 음수 : 메시지의 유형이 msgtyp로 지정한 값의 절대값과 같거나 작은 메시지를 읽어온다.4. msgctl() : 메세지 제어
int msgctl(int msqid, int cmd, struct msqid_ds *buf);
- msqid : 메시지 큐 식별자
- cmd : 수행할 제어기능
- buf : 제어 기능에 사용되는 메시지 큐 구조체 주소
- cmd에 지정할 값
- IPC_RMID : 메시지 큐 제거
- IPC_SET : 메시지 큐 정보 중 msg_perm.uid, msg_perm.gid, msg_perm.mode, msg_qbytes 값을 세번째 인자로 지정한 값으로 변경
- IPC_STAT : 현재 메시지 큐의 정보를 buf에 저장
- msqid_ds 구조체예제 1)
- Sender
1. IPC 객체 생성하고 key를 받는다 [ 우편함 ]
2. msgget() 함수로 보낼 message queue 객체를 하나 만든다 / qid는 message queue 식별자 [ 편지 봉투 ]
3. 보낼 msgbuf 구조체를 동적 할당해준 뒤, msgtype과 보내고 싶은 내용을 적어준다 [ 이름과 편지지 ]
4. msgsnd() 함수로 message queue 객체 식별자, msgbuf 구조체의 주소, 크기 등을 넣어 보낸다
5. message queue로 message 보냈으므로 동적 할당 풀어준다
- Receiver
1. IPC 객체 생성하고 key를 받는다
2. msgget() 함수로 보내준 것을 받기 위한 message queue 객체를 하나 만든다 / qid는 message queue 식별자
3. 보내준 것을 받기 위해 msgbuf 구조체를 동적 할당해준다
4. msgrcv() 함수로 받을 message queue 객체 식별자, 받을 msgbuf 구조체의 주소, 보내줬던 message의 msgtype , 크기 등을 넣어 받는다=> 만약에 보낼 때 msgbufd 구조체에서 msgtype=10으로 보냈었다면, 10인 애들만을 찾기 위해 msgrcv에서 세번째 인자에 10 설정해줘야 한다!
5. message queue로 message 받았으므로 동적할당 풀어준다https://codingsmu.tistory.com/63
https://computer-serendipity.com/message-queues/
https://awesomebit.tistory.com/17
https://doitnow-man.tistory.com/119?category=747867
http://www.xevious7.com/linux/lpg_6_4_2.html
https://tttsss77.tistory.com/234
Shared Memory
(1) 정의
- 시스템 상의 공유 메모리를 통해 통신한다.
- 커널에 생성된 공유 메모리를 통해서 프로세스간 데이터를 공유한다.
- 같은 메모리 공간을 두 개 이상의 프로세스가 공유하는 것
- 같은 메모리 공간을 사용하므로 이를 통해 데이터를 주고 받을 수 있음(2) 구조
- 일정한 크기의 메모리를 프로세스 간에 공유하는 구조
- 공유 메모리는 커널에서 관리 된다
- 단순히 공유 메모리를 point 함으로써 프로세스에서 사용되는 메모리가 증가되지는 않는다.
(3) 사용시기
- 프로세스간 Read, Write를 모두 필요로 할때
(4) 유의사항
- 프로세스간의 상용할려면 메모리 크기가 동일 해야 한다.
Shared Memory 관련 함수 4가지
1. shmget() : 공유메모리 생성
int shmget(key_t key, size_t size, int shmflg);
- key : IPC_PRIVATE 또는 ftok로 생성한 키값
- size : 공유할 메모리 크기
- shmflg : 공유 메모리의 속성을 지정하는 플래그
- IPC_CREAT, IPC_EXCL
- 공유 메모리 식별자를 리턴(shmid_ds 구조체)
- shmid_ds 구조체2. shmat() : 공유 메모리 연결
void *shmat(int shmid, const void *shmaddr, int shmflg);
- shmid : 공유 메모리 식별자
- shmaddr : 공유 메모리를 연결할 주소
- shmflg : 공유 메모리에 대한 읽기/쓰기 권한
- 0(읽기/쓰기 가능), SHM_RDONLY(읽기 전용)3. shmdt() : 공유 메모리 해제
int shmdt(char *shmaddr);
- shmaddr : 연결을 해제할 공유 메모리 주소
4. shmctl() : 공유 메모리 제어
int shmctl(int shmid, int cmd, struct shmid_ds *buf);
- cmd : 수행할 제어기능
•IPC_RMID : 공유 메모리 제거
•IPC_SET : 공유 메모리 정보 내용 중 shm_perm.uid, shm_perm.gid, shm_perm.mode 값을 세번째 인자로 지정한 값으로 변경
•IPC_STAT : 현재 공유 메모리의 정보를 buf에 지정한 메모리에 저장
•SHM_LOCK : 공유 메모리를 잠근다.
•SHM_UNLOCK : 공유 메모리의 잠금을 해제한다.
예제 1)
1. IPC 객체 생성하고 key를 받는다
2. shmget()으로 공유메모리 생성
3. 공유 메모리에 올릴 값의 포인터를 shmat() 함수를 통해 공유 메모리에 연결
예제 2)
https://doitnow-man.tistory.com/68
https://codingsmu.tistory.com/63
https://doitnow-man.tistory.com/122
http://www.xevious7.com/linux/lpg_6_4_4.html
728x90'System Programming > Ubuntu Linux' 카테고리의 다른 글
시스템 프로그래밍 실습 10주차 : Sockets (0) 2021.11.01 Shell 만들기 참고할 것 (0) 2021.10.28 시스템 프로그래밍 실습 8주차 : IPC (0) 2021.10.17 시스템 프로그래밍 실습 7주차 : Signals (0) 2021.10.10 시스템 프로그래밍 실습 6주차 : Daemon (0) 2021.10.03