==================================Outline====================================
IPC
- pipe 함수
- mkfifo 함수
- 공유 메모리
----------------------------------------------------------------------------
pipe 함수
파이프 함수를 사용하면 변수를 통하여 서로 데이터를 주고 받을 수 있다. 하지만 이 같은 경우는 복사된 동일한 프로세스만이 변수를 사용한 데이터의 공유가 가능할 뿐이다.
#include <unistd.h>
int pipe(int filedes[2]);

mkfifo 함수
서로 상이한 프로그램 간의 데이터 입출력을 위해서는 파일을 사용하여야 한다. 이 때 사용하는 함수가 'mkfifo'이다.
#include <sys/types.h>
#include <sys/stat.h>
int mkfifo(const char *pathname, mode_t mode);
mkfifo의 mode에 대해서 알아보자.
File mode bits:
S_IRWXU
read, write, execute/search by owner
S_IRUSR
read permission, owner
S_IWUSR
write permission, owner
S_IXUSR
execute/search permission, owner
S_IRWXG
read, write, execute/search by group
S_IRGRP
read permission, group
S_IWGRP
write permission, group
S_IXGRP
execute/search permission, group
S_IRWXO
read, write, execute/search by others
S_IROTH
read permission, others
S_IWOTH
write permission, others
S_IXOTH
execute/search permission, others
S_ISUID
set-user-ID on execution
S_ISGID
set-group-ID on execution
S_ISVTX
on directories, restricted deletion flag
#include <sys/types.h> #include <sys/stat.h> #include <unistd.h> #include <stdio.h> #include <fcntl.h>
int main() { if(mkfifo("/tmp/myfifo_r", S_IRUSR|S_IWUSR) == -1) { return 1; } printf("Sucess Named PIPE : tmp/myfifo_r\n");
return 0; }
|
//리눅스는 확장자로 파일을 구분하지 않는다.
//fifo(first in, first out)

서버와 클라이언트가 통신하는 IPC를 만들어보자.
다수의 클라이언트가 접속하는 경우 파이프는 부적합하다. 접속자의 수만큼 파이프를 만들어야 하기 때문이다.
/// pipe_client.c ///
#include <sys/types.h> #include <sys/stat.h> #include <fcntl.h>
#include <unistd.h> #include <stdio.h> #include <string.h> #include <errno.h>
#define MAXLINE 1024
int main(void) { int rfd, wfd; //file descriptors char buf[MAXLINE]; //buf if( (rfd = open("/tmp/myfifo_w", O_RDWR) ) < 0) //write pipe open { //if error, terminate program perror("read open error"); return 0; }
if( (wfd = open("/tmp/myfifo_r", O_RDWR) ) < 0) //read pipe open { //if error, terminate program perror("write open error"); return 0; } while(1) { printf("> "); fflush(stdout); //empty print buff memset(buf, 0x00, MAXLINE); //empty buff if( read(0, buf, MAXLINE) < 0 ) //if none read from keyboard, terminate program { printf("error\n"); return 1; } if( strncmp(buf, "quit\n", 5) == 0 ) //if input "quit" terminate program break;
write( wfd, buf, strlen(buf) ); //write at write pipe read( rfd, buf, MAXLINE ); //read from read pipe printf("Server -> %s", buf); //print what read from server }
close(wfd); //close write pipe close(rfd); //close read pipe return 0; }
|
/// pipe_server.c ///
#include <sys/types.h> #include <sys/stat.h> #include <stdlib.h> #include <fcntl.h>
#include <unistd.h> #include <stdio.h> #include <string.h> #include <errno.h>
#define MAXLINE 1024
int main(void) { int rfd, wfd; //file descriptors char buf[MAXLINE]; //buf mkfifo("/tmp/myfifo_r", S_IRUSR|S_IWUSR); //write pipe open mkfifo("/tmp/myfifo_w", S_IRUSR|S_IWUSR); //read pipe open if( (rfd = open("/tmp/myfifo_r", O_RDWR) ) == -1) //if error at opening read pipe, terminate program { perror("rfd error"); return 0; }
if( (wfd = open("/tmp/myfifo_w", O_RDWR) ) == -1) //if error at opening write pipe, terminate program { perror("wfd error"); return 0; } while(1) { memset(buf, 0x00, MAXLINE); //empty R/W buff if( read(rfd, buf, MAXLINE) < 0) //if error at reading from pipe, terminate program { perror("Read Error::"); return 1; } printf("read : %s", buf); //print buff read from read pipe lseek(wfd, 0, SEEK_SET); //cursor at beginning of buff write(wfd, buf, MAXLINE); //echo what read from buff } return 0; }
|

파이프는 큰 데이터를 소수의 클라이언트가 사용할 때 쓰고, 도메인은 적은 데이터를 다수의 클라이언트가 사용할 때 쓴다.
공유 메모리
shmget함수를 사용한다.
#include <sys/types.h>
#include <sys/shm.h>
int shmget(key_t key, int size, int shmflg);
#include <sys/ipc.h> #include <sys/shm.h> #include <string.h> #include <unistd.h> #include <stdio.h> #include <stdlib.h>
int main() { int shmid;
int *cal_num; void *shared_memory = NULL;
shmid = shmget( (key_t)1234, sizeof(int), 0); if (shmid == -1) { perror("shmget failed : "); exit(0); } shared_memory = shmat(shmid, NULL, 0); if (shared_memory == (void *)-1) { perror("shmat failed : "); exit(0); }
cal_num = (int *)shared_memory; while(1) { sleep(1); printf("read data : %d\n", *cal_num); } return 1; }
|
#include <sys/ipc.h> #include <sys/shm.h> #include <string.h> #include <unistd.h> #include <stdio.h> #include <stdlib.h>
int main() { int shmid;
int *cal_num; void *shared_memory = NULL;
shmid = shmget( (key_t)1234, sizeof(int), 0666|IPC_CREAT); if (shmid == -1) { perror("shmget failed : "); exit(0); } shared_memory = shmat(shmid, NULL, 0); if (shared_memory == (void *)-1) { perror("shmat failed : "); exit(0); }
cal_num = (int *)shared_memory; while(1) { *cal_num = *cal_num +2; sleep(1); } return 1; }
|

소스 파일들
myfifo.c
pipe.c
pipe_client.c
pipe_server.c
shm_consumer.c
shm_producer.c