블로그

[OS] Linux IPC - Pipe, Shared memory, Message queue 본문

CS

[OS] Linux IPC - Pipe, Shared memory, Message queue

왕방토 2022. 12. 21. 10:41
728x90

 

 

<IPC>: Inter Process Communication / 프로세스끼리 통신을 하는 방법

  • IPC 식별자: Key, Id
    • key 생성 API: key_t ftok(const char *pathname, int proj_id)
    • -> pathname과 proj_id를 동일하게 주면 key는 같아짐
  • IPC 자원들은 커널에 의해 만들어지며 커널에 존재
  • 생성된 IPC들은 제거하기 전까지 시스템에 남아있음
  • IPC의 종류: signal, pipe, message queue, shared memory, semaphore 등...

뭐가 많다~

Pipe

  • 단방향 통신 -> 한쪽에서 데이터를 쓰면 반대쪽에선 데이터를 읽음 -> 근데 이게 동시에 양방향이 안된다는 거지 A->B로 했다가 다 닫고 다시 열어서 B->A로 하는건 가능함
  • 양방향 통신을 위해서는 두개의 pipe가 필요
  • Unnamed pipe: 같은 조상을 둔 프로세스 사이에서 상속을 통해 통신 가능
  • Named pipe -> FIFO
  • int pipe(int filedes[2]): pipe를 생성하며 2개의 파일 디스크립터를 리턴함 / 0:R, 1:W
  • read()
  • write
  • open()
  • close()
  • 보통 읽고쓸때 반대 파일 디스크립터를 close해줌 -> 필수는 아닌데 권장한다고 함 이거 더 찾아보기

 

FIFO(named pipe)

  • 파일 시스템상의 파일을 이용해 통신
  • 따라서 FIFO의 이름을 아는 모든 프로세스 사이에 통신 가능
  • 이름처럼 FIFO와같이 동작하기 때문에 여러 프로세스들이 FIFO에 write 한 후에 A라는 프로세스가 FIFO에서 read할 때 FIFO로 읽지 특정 프로세스가 write한 내용을 특정해 가져올 순 없다
    • 생성: mkfifo(FIFO파일이름, 권한)
    • 삭제: unlink(FIFO파일이름)

 

 

파일 디스크립터

  • 정의: 특정한 파일에 접근하기 위한 추상적인 키
  • open()의 리턴값으로 할당됨
  • 0, 1, 2는 운영체제가 가져다가 쓰는 번호 -> 따라서 보통 3번부터 open으로 할당
    • 0: STDIN / 1: STDOUT / 2: STDERR

 

Shared Memory

  • #include <sys/ipc.h>, <sys/shm.h>
  • 메모리를 복사할 필요가 없으므로 속도가 빠르다 -> DB같은 데이터를 공유할 때 유용하다
  • 단방향이 아닌 양방향이므로 동기화 기법이 반드시 필요하다
    • int shmget(key_t key, size_t size, shmflg) : shm id를 리턴
      • key 값
      • shm 크기
      • 권한 및 플래그
    • shmat(shm id, shm주소, 플래그): shm id의 shm를 연결할 주소를 리턴 / err: -1
      • shm주소: 0을 넣어주면 OS가 임의로 결정
      • 플래그: 0을 넣어주면 R&W, SHM_READONLY인 경우 R
    • shmdt(shm주소): shm연결 해제 / success:0, err: -1
    • shmctl(int shmid, int cmd, struct shmid_ds *buf): shm 삭제 / success:0, err: -1

 

 

**공유(양방향) -> 동기화 생각하고 코드 짜줘야 함 -> mutex, semaphore

 

공유하면서 자동으로 동기화도 가능한 IPC

Message Queue -> "메시지 플래그 0"을 통해서 공유와 함께 동기화까지 할 수 있음(대기하는 프로세스는 블로킹됨)

  • #include <sys/types.h>, <sys/ipc.h>, <sys/msg.h>
  • int msgget(key_t key, int msgflg): msq id 리턴
    • key 값
    • 권한 및 플래그
  • mgssnd(메시지 큐 id, 메시지 구조체 포인터, 메시지 구조체 크기 메시지 플래그)
  • msgrcv(메시지 큐 id, 메시지 구조체 포인터, 메시지 구조체 크기, 메시지 타입, 메시지 플래그)
  • int mgsctl(int msgid, int cmd, struct msqid_ds *buf)
  • 메시지 플래그
    • IPC_NOWAIT(==1): 메시지 타입이 있다면 빼고 없으면 기다리지 않고 err 리턴
    • 0: 메세지 타입이 있다면 빼고 없으면 들어올 때까지 기다린다

 

Comments