파이프
:부모의 프로세스가 생성된 자식 프로세스에게 단방향으로 데이터를 전달하는 방법파이프 기법은 부모 프로세스가 자식 프로세스에게 전달하는 기법(단방향 통신) pipe로 먼저 생성 후 fork 로 자식 프로세스 생성하고 부모가 write(fd[1], 메시지내용, 크기) 자식은 read (fd[0], 받은버퍼, 크기)로 하여 통신한다
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define MSGSIZE 255
char* msg = "Hello Child Process!";
int main()
{
char buf[255];
int fd[2], pid, nbytes;
if (pipe(fd) < 0) // pipe(fd) 로 파이프 생성
exit(1);
pid = fork(); // 이 함수 실행 다음 코드부터 부모/자식 프로세스로 나뉘어짐
if (pid > 0) { // 부모 프로세스에는 자식 프로세스 pid값이 들어감
printf("parent PID:%d, child PID:%d\n", getpid(), pid);
write(fd[1], msg, MSGSIZE); //fd[1]에 씁니다.
exit(0);
}
else { // 자식 프로세스에는 pid값이 0이 됨
printf("child PID:%d\n", getpid());
nbytes = read(fd[0], buf, MSGSIZE); // fd[0]으로 읽음
printf("%d %s\n", nbytes, buf);
exit(0);
}
return 0;
}
메세지큐 :
메시지큐는 프로세스간 양방향 통신(심지어 자기자신에게도 보내고 받을수 있음)
- 생성 : msgget(키,생성 상수|권한) *권한이라고 하면 0644같은걸 줘서 rw-r 이런식으로
- 보내기 : msgsnd(키,보낼데이터,텍스트크기, 플래그) *보낼데이터는 구조체로 타입과 텍스트가 있어야함, 텍스트 크기는 보낼데이터의 텍스트 크기, 플래그는 블럭, 노블럭인데 블럭은 해당 함수를 실행할까지 멈춰있는것, 노블럭은 실행하지 못하더라도 다음문장 실행
- 받기 : msgrcv(키, 받을데이터, 텍스트크기, 타입, 플래그) * 나머지 내용은 보내기랑 같고 타입은 보내기에서 보낼데이터에 적힌 타입을 의미
// messageQueue Send
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/msg.h>
typedef struct msgbuf {
long type;
char text[50];
} MsgBuf;
int main(void) {
int msgid, len;
MsgBuf msg;
key_t key = 1234;
msgid = msgget(key, IPC_CREAT|0644);
if(msgid == -1) {
perror("msgget");
exit(1);
}
msg.type = 1;
strcpy(msg.text, "Hello Message Queue\n");
if(msgsnd(msgid, (void *)&msg, 50, IPC_NOWAIT) == -1) {
perror("msgsnd");
exit(1);
}
return 0;
}
// messageQueue Receive
#include <sys/msg.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
typedef struct msgbuf {
long type;
char text[50];
} MsgBuf;
int main(void) {
MsgBuf msg;
int msgid, len;
key_t key = 1234;
if((msgid = msgget(key, IPC_CREAT|0644)) < 0) {
perror("msgget");
exit(1);
}
len = msgrcv(msgid, &msg, 50, 0, 0);
printf("Received Message is [%d] %s\n", len, msg.text);
return 0;
}
*메시지큐에 전송되는 데이터 구조 (type의 자료형이 long이니 반드시 유의해야 한다)
struct { long data_type; char data_buff[BUFF_SIZE]; }
struct { long data_type; int data_num; char data_buff[BUFF_SIZE]; }
struct { long data_type; int data_num; }
*ipcs : 현재 사용중인 메시지 큐, 공유 메모리 보기
공유 메모리
: 변수에 할당하듯이 커널에 메모리 공간을 할당하여 사용하는 방식이다
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
int main(void) {
int shmid, pid;
char *shmaddr_parent, *shmaddr_child;
key_t key = ftok(".",1);
printf("key : %d\n",key);
shmid = shmget((key_t)key, 10, IPC_CREAT|0644);
if(shmid == -1) {
perror("shmget error\n");
exit(1);
}
pid = fork();
if (pid > 0) { // parent process
wait(0); // wait for child process exit
shmaddr_parent = (char *)shmat(shmid, (char *)NULL, 0);
printf("%s\n", shmaddr_parent);
shmdt((char *)shmaddr_parent);
}
else { // child process
shmaddr_child = (char *)shmat(shmid, (char *)NULL, 0);
strcpy((char *)shmaddr_child, "Hello Parent!");
shmdt((char *)shmaddr_child);
exit(0);
}
shmctl(shmid, IPC_RMID, (struct shmid_ds *)NULL);
return 0;
}
- 공유 메모리 생성 : shmget
- 공유 메모리 연결 : shmat
- 공유 메모리 분리 : shmdt (현재 프로세스와 공유 메모리 분리)
- 공유 메모리 삭제 : shmctl
ftok | 패스경로의 inode의 값("."를 쓰면 현재경로), id를 넣으면 알아서 key를 생성해주는 함수 |
shmat | 공유 메모리 연결 |
shmdt | 현재 프로세스와 공유 메모리 분리 |
shmctl | 공유 메모리 삭제 |
시그널
: 시그널 매크로에 사용자 정의나 블럭을 하여 다른 프로세스간에 통신하는 기법
#include<signal.h>
#include<unistd.h>
#include<stdio.h>
#include<stdlib.h>
static void signal_hanlder(int signo){
printf("Catch SIGINT!, but no stop\n");
}
int main(void){
if(signal(SIGINT,signal_hanlder) == SIG_ERR){
printf("Can't catch SIGINT!\n");
exit(1);
}
for(;;)
pause();
return 0;
}
SIGINT 라는 프로세스에 인터럽트를 보내서 프로세스를 죽이는 시그널을 사용자 정의 함수로 바꾸는 코드
#include<sys/types.h>
#include<signal.h>
#include<stdlib.h>
#include<stdio.h>
int main(int argc,char *argv[]){
printf("sigkill start\n");
int pid = atoi(argv[1]);
int sig_num = atoi(argv[2]);
if(kill(pid,sig_num)<0)
{
perror("To send Signal is failed\n");
exit(1);
}
return 0;
}
*kill 함수는 쉘명령어와 다르게 시그널을 전송하는 함수이다.
출처 http://forum.falinux.com/zbxe/index.php?category=520920&document_srl=413771&mid=C_LIB
실행 결과
프로세스가 종료되는것이 아니라 사용자가 정의된 함수로 실행된다
시그널과 프로세스
'컴퓨터공학 > 시스템 프로그래밍' 카테고리의 다른 글
시스템콜 , 프로세스 생성 (0) | 2019.11.30 |
---|---|
프로세스 ID (0) | 2019.11.30 |
ABI와 표준 (0) | 2019.11.30 |
하드링크와 소프트링크 (0) | 2019.11.29 |
foreground, background, 프로세스 관리 (0) | 2019.11.29 |