시스템 V의 프로세스간 통신
유닉스는 처음 개발된 이래 다양한 형태로 발전했다. 크게 BSD 계열과 시스템 V 계열로 구분할 수 있다.
시스템V계열 유닉스에서 개발해 제공하는 프로세스간 통신 방법이 메세지 큐, 공유 메모리, 세마포어 이다.
이 세가지를 묶어서 시스템V IPC 라고 한다. 이것은 SVR2에서 처음 개발되었고, SVR4에서도 제공하고 있으며 현재는 대부분의 유닉스 시스템에서 제공하고 있다.
IPC 설비
IPC(Inter-Process Communication)란 프로세스 간 통신을 의미한다.
UNIX의 대표적인 IPC는 message_queue, semaphore, shared memory segment가 있다.
key
• key는 message_queue, semaphore, shared memory segment에 대한 identifier (file 이름에 해당)이다.
• 서로 다른 process들도 동일 IPC 객체는 같은 key 값으로 접근할 수 있다.
• 시스템에서 unique한 key값을 사용하여야 한다. → 서로 이름을 공유하기 때문에 꼭 유니크하게 만들어야함!
key값 생성
#include<sys/ipc.h>
key_t ftok(const char *path, int id);
// 해당 파일의 st_dev, st_ino와 id로 key값 생성
//* path: 파일 시스템에 이미 존재하는 임의의 파일 경로명 -> 중요!!!! 이미 존재하는 파일 경로!
//* id: 키값을 생성할 때 지정하는 임의의 번호 (1~256)
ftok함수를 이용하면 시스템에서 파일 이름과 지정한 id를 조합해서 유니크한 key를 생성한다.
IPC 객체 상태 구조
struct ipc_perm{
uid_t cuid : 생성자의 uid;
gid_t cgid : 생성자의 gid;
uid_t uid : 소유자 uid;
gid_t gid : 소유자 gid;
mode_t mode : permission (execution은 의미 없음);
};
IPC 정보 검색 및 삭제
ipc관련 정보 검색
$ipcs
ipc삭제
$ipcrm -m shmid or -q msqid or -s semid
# -m : shmid인 경우
# -q : msqid인 경우
# -s : semid인 경우
message passing
message queue를 통한 message 전달
msgget : queue 생성 → msgQueue만드는데 실패하면 send랑 receive도 실패
msgsnd : message 보내기
msgrcv : message 받기
msgget 시스템 호출
구조체
#include <sys/msg.h>
int msgget(key_t key, int permflags);
// key : message queue의 key 값
// permflags = queue에 대한 access permission
// 1. IPC_CREAT :
// 해당 queue가 없으면, 생성한 후 return; 있으면, return
// 이 flag가 설정 되지 않은 경우에는, queue가 존재하는 경우에만 return
// 2. IPC_EXCL :
// 해당 queue가 존재하지 않는 경우만 성공, 아니면 –1 return
// return 값 : 음수가 아닌 queue identifier -> 파일디스크립터 같은거
msgsnd 시스템 호출
#include <sys/msg.h>
int msgsnd(int mqid, const void *message, size_t size, int flags);
// mqid : message queue identifier
// message 의 주소 : 보낼 message가 저장된 주소
// size : message의 크기
// flags = IPC_NOWAIT
// send가 불가능하면 즉시 return (queue가 가득 찬 경우)
// flag가 설정 되지 않으면 (0이면), 성공 시까지 blocking
// return 값은 0 or –1
message의 구조
struct mymsg{
long mtype; // message type (양의 정수) 0은 불가능!!!
char mtext[SOMEVALUE]; // message 내용 : 원하는 아무 데이터나 가능
};
- long type의 정수 값을 갖는 mtype과 임의의 message의 내용으로 구성
- message의 size는 message 내용의 크기만.
msgrcv 시스템 호출
사용법
#include <sys/msg.h>
int msgrcv(int mqid, void *message, size_t size, long msg_type, int flags);
/*
mqid : message queue identifier
message 주소 : 받은 message를 저장할 저장 장소의 주소
size : 준비된 저장 장소의 크기
msg_type =
0 : queue의 첫 message
> 0 : 해당 값을 갖는 첫 message
< 0 : mtyep값이 절대값 보다 작거나 같은 것 중 최소값을 갖는 첫 message
-> 기본적으로 blocking receive
flags = IPC_NOWAIT
receive가 불가능하면 즉시 return (queue에 해당 msg가 없는 경우)
return 값은 –1; errno = EAGAIN
flag가 설정 되지 않으면 (값이 0이면), 성공 시까지 blocking
flags = MSGNOERROR
message가 size보다 길면 초과분을 자른다. -> 이렇게 받으면 잘랐는지 아닌지 알 수 없음
flag가 설정 되지 않으면 size 초과 시 error
return 값 :
receive 성공 시 : 받은 message의 길이
실패시:-1
access permission 때문에 실패한 경우 errorno=EACCESS
*/
→ 파이프와 메세지 큐의 차이점 : 파이프는 msg_type을 사용해서 메세지 큐 하나로 여러 사람한테 가는 메세지가 섞여있어도 구분해서 사용가능하다.
→ 또한 메세지 큐는 select같은 함수를 사용하지 않아도 여러 프로세스에게 데이터를 받는지 체크해서 blocking 할지말지 문제를 해결할 수 있다.
→ msg_type으로 receiver가 특정한 msg만 msgQueue에서 받아오게 설정할 수 있다.!!!!!
message 송수신의 예
struct q_entry{
long mtype;
int mnum;
};
struct q_entry msg;
qid=msgget(0111, 0600|IPC_CREAT);
while(msgrcv(qid, &msg, sizeof(int), 1, 0)>0) {
msg.mtype=2;
msg.mnum=msg.mnum+8;
msgsnd(qid, &msg, sizeof(int), 0);
}
메세지 큐에 메세지의 타입과 내용을 지정한 후, msgsnd 함수를 사용해서 넣는다.
msgctl 시스템 호출
msgctl 호출
- message queue에 대한 정보 획득
- message queue 제거
사용법
#include <sys/msg.h>
int msgctl(int mqid, int command, struct msqid_ds *msq_stat);
/*
mqid : message queue identifier
command =
IPC_STAT : msg queue의 상태 정보 확인
IPC_RMID : msg_queue 삭제
msqid_ds 구조:
struct ipc_perm msg_perm; // 소유권
msgqnum_t msg_qnum; // msg수
msglen_t msg_qbytes; // bytes수
pid_t msg_lspid; // last sender
pid_t msg_lrpid; // last receiver
time_t msg_stime; // last sending time
time_t msg_rtime; // last receipt time
time_t msg_ctime; // last s/r time
*/
'CS(Computer Science) > UNIX' 카테고리의 다른 글
UNIX - [Shared memory] (0) | 2023.01.02 |
---|---|
UNIX - [Semaphore] (0) | 2023.01.01 |
UNIX - [PIPE - 2] (0) | 2022.12.31 |
UNIX - [PIPE] (3) | 2022.12.30 |
UNIX - [MEMORY MAPPING] (0) | 2022.12.30 |