728x90

Signaling 예제 코드

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>

// 핸들러 함수 정의
void handlerFunc(int sig) {
  printf("handlerFunc() 호출됨\n");
  // SIGINT : 터미널 인터럽트
  // SIG_DFL : 기본 행동 수행, 메인 함수가 하던 일을 계속 수행하고 한 번 더 SIGINT가 오는 경우 프로세스 종료
  signal(SIGINT, SIG_DFL);
}

int main() {
  // SIGINT(키보드 인터럽트) 신호를 받으면 handlerFunc 수행
  signal(SIGINT, handlerFunc);

  int count = 0;
  while(1) {
    printf("count : %d\n", count++);
    sleep(1);
  }
  exit(0);
}

실행 결과

시그널 타입

  • SIGINT : 키보드 인터럽트
  • SIGFPE : 부동 소수점 예외
  • SIGKILL : 프로세스 종료
  • SIGCHLD : 자식 프로세스가 정지 또는 종료
  • SIGSEGV : 세그먼트 오류(비정상 종료, 메모리 엑세스 오류)
728x90

'운영체제 > IPC' 카테고리의 다른 글

[OS] IPC - Message Passing  (0) 2022.12.26
[OS] IPC - Shared Memory  (0) 2022.12.26
728x90

프로세스, 스레드, IPC에 관한 내용은 이 글을 참고하자

Message Passing 예제

sender.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#define BUFFER_SIZE 1024

// 메세지 형태 정의
typedef struct {
  long msgtype;
  int value;
  char buf[BUFFER_SIZE];
} msgbuf;

int main() {
  int key_id;
  msgbuf mybuf;
  int count = 0;
 
  // 메세지 생성
  key_id = msgget((key_t) 1234, IPC_CREAT|0666);
  if (key_id == -1) {
    perror("msgget() error");
    exit(0);
  }
  
  // 메세지 타입 설정
  mybuf.msgtype = 1;
  while (1) {
    // value 값 1 증가시켜서 메세지 전송
    mybuf.value = count++;
    printf("value : %d\n", mybuf.value);
    
    if (msgsnd(key_id, &mybuf, sizeof(msgbuf), IPC_NOWAIT) == -1) {
      perror("msgsnd() error");
      exit(0);
    }
    
    sleep(10);
  }
}

receiver.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#define BUFFER_SIZE 1024

// 메세지 형태 정의
typedef struct {
  long msgtype;
  int value;
  char buf[BUFFER_SIZE];
} msgbuf;

int main() {
  int key_id;
  msgbuf mybuf;
  long msgtype = 1; // 수신받을 메세지 타입 미리 설정
 
  // 메세지 생성
  key_id = msgget((key_t) 1234, IPC_CREAT|0666);
  if (key_id == -1) {
    perror("msgget() error");
    exit(0);
  }
  
  while (1) {
    // 메세지 타입이 1 일 때 수신
    if (msgrcv(key_id, &mybuf, sizeof(msgbuf), 1, 0) == -1) {
      perror("msgrcv() error");
      exit(0);
    }
    
    // 수신 받은 메세지에서 value 출력
    printf("value : %d\n", mybuf.value);
  }
}

실행화면

헤더 파일 및 주요 함수

헤더 파일

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>

int msgget(key_t key, int msgflg)

  • 메세지를 생성

int msgsnd(int msqid, struct msgbuf * msgp, size_t msgsize, int msgflg)

  • 메세지 전송

ssize_t msgrcv(int msgid, struct msgbuf * msgp, size_t msgsize, long msgtype, int msgflg)

  • 메세지 수신
728x90

'운영체제 > IPC' 카테고리의 다른 글

[OS] Signaling  (0) 2022.12.26
[OS] IPC - Shared Memory  (0) 2022.12.26
728x90

Process

  • 컴퓨터에서 실행되고 있는 프로그램
  • 실행되고 있는 프로그램의 인스턴스
  • 프로세스간 독립적
  • CPU로부터 메모리 할당

Thread

  • 프로세스 내에서 실행되는 흐름의 단위
  • 프로세스가 할당받은 자원을 이용
  • 같은 메모리 공간 공유

IPC

  • 프로세스는 독립적으로 실행되기 때문에 메모리를 공유할 수 없다.
  • 따라서 프로세스간 통신을 통해 서로 데이터를 주고 받을 수 있게 해야한다.
  • 방법은 다음과 같다.

1) Message Passing

  • 커널을 통해 메시지를 전달
  • 안전하지만 성능이 떨어짐 (Overhead가 큼)
  • 예제

2) Shared Memory

  • 프로세스간 공유된 메모리를 생성 후 이용
  • 성능이 좋지만 동기화 문제 발생 가능
#include <sys/shm.h>
#include <string.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>

int main() {
  int shmid;
  int pid;
  
  int * cal_num;
  void * shared_memory = (void *) 0;
  
  // 공유 메모리 공간 생성
  shmid = shmget((key_t) 1234, sizeof(int), 0666|IPC_CREAT);
  
  // shmget() 실패 시 -1 return
  if (shmid == -1) {
    perror("shmget failed : "); // 오류 메시지 출력
    exit(0);
  }
  
  printf("shmid return value : %d\n", shmid);
  
  // 공유 메모리를 사용하기 위해 프로세스 메모리 부착
  shared_memory = shmat(shmid, (void *)0, 0);
  if (shared_memory == (void *) -1) {
    perror("shmat failed : ");
    exit(0);
  }
  
  cal_num = (int *) shared_memory;
  // 자식 프로셋스 생성
  pid = fork();
  
  if (pid == 0) {
    // 자식 프로세스
    shmid = shmget((key_t) 1234, sizeof(int), 0);
    
    if (shmid == -1) {
      perror("shmget failed : "); // 오류 메시지 출력
      exit(0);
    }
    shared_memory = shmat(shmid, (void *) 0,  0666|IPC_CREAT);
    if (shared_memory == (void *)-1) {
      perror("shmat failed : ");
      exit(0);
    }
    cal_num = (int *) shared_memory;
    *cal_num = 1;
    
    while(1) {
      *cal_num = *cal_num + 1;
      printf("child %d\n", *cal_num);
      sleep(1);
    }
  } else if (pid>0) {
    // 부모 프로세스
    while(1) {
      sleep(1);
      printf("*cal_num : %d\n", *cal_num);
    }
  }
}

int shmget(key_t , key, size_t size, int flags)

- #include  에 포함
- 새 공유 메모리 세그먼트를 생성하거나 키를 찾는데 사용
- 0666 | IPC_CREAT
0666 : Linux에서 일반적인 엑세스 권한, 메모리 세그먼트 권한 지시
IPC_CREAT : 공유 메모리에 대한 새 메모리 세그먼트를 만들도록 지시
- 참고 : [What is the use of IPC_CREAT | 0666 Flag in shmget()?](https://stackoverflow.com/questions/40380327/what-is-the-use-of-ipc-creat-0666-flag-in-shmget-function-in-c) - Stackoverflow

void shmat(int id, const void addr, int flags)

- #include <sys/shm.h> 에 포함
- 공유 메모리 세그먼트를 프로세스에 연결하는데 사용 ⇒ 메모리 내용에 엑세스 가능

fork()

- 자식 프로세스 생성

 

 
728x90

'운영체제 > IPC' 카테고리의 다른 글

[OS] Signaling  (0) 2022.12.26
[OS] IPC - Message Passing  (0) 2022.12.26

+ Recent posts