[UNIX] 파이프

Taegang Yun·2023년 12월 8일
1

Unix 프로그래밍

목록 보기
13/19

파이프

두 프로세스 사이에서 한 방향으로 통신할 수 있도록 지원하는 것

  • 셀에서 파이프 기능은 한 명령의 표준 출력을 다음 명령에서 표준 입력으로 수행하는 것을 의미

이름 없는 파이프 : pipe

이름 없는 파이프는 부모-자식 프로세스 간에 통신을 할 수 있게 함

파이프 만들기 : popen()

  • type : “r” 또는 “w”
  • 내부적으로 fork() 함수를 실행해서 자식 프로세스를 만들고, command에서 지정한 명령을 exec() 함수로 실행해 자식 프로세스가 수행하도록 함.
int main(){
	FILE *fp;
	int a;

	fp = popen("wc-l", "w");
	
	for(a = 0 ; a < 100; a++) fprintf(fp, "testline\n");
	pclose(fp);
}

파이프 닫기 : pclose()

  • 관련된 waitpid() 함수를 수행

파이프 만들기 2 : pipe()

  • pipefd[0] 은 읽기 전용으로 열고, pipefd[1]은 쓰기 전용으로 실행

pipe() 통신 과정

  1. pipe() 함수 호출해 파이프에 사용할 파일 기술자를 얻음
  2. fork() 함수를 수행해 자식 프로세스를 생성
  3. 파이프는 단방향 통신이므로 통신 방향을 결정
int main(){
	int fd[2];
	pid_t pid;
	char buf[257];
	int len, status;

	pipe(fd);

	switch(pid = fork()){
		case 0:
			close(fd[1]);
			write(1, "child process", 15);
			len = read(fd[0], buf, 256);
			close(fd[0]);
			break;
		default:
			close(fd[0]);
			write(fd[1], "Test Message\n", 14);
			close(fd[1]);
			waitpid(pid, &status, 0);
			break;
	}
}

이름 있는 파이프 : FIFO

부모-자식 프로세스 관계가 아닌 독립적인 프로세스들이 파이프를 이용하려면 파일처럼 이름이 있어야 함.

select

Timeout은 struct timeval 에 대한 포인터

포인터가 널이면 select는 흥미있는 일이 일어날 때까지 봉쇄. 만일 timeout이 0초를 포함하는 구조를 가리키면 즉각 복귀. 0이 아닌 값을 포함하고 있으면 지정된 시간 후에 복귀

int fd1, fd2;
fd_set readset;

fd1 = open("file1", O_RDONLY);
fd2 = open("file2", O_RDONLY);
FD_ZERO(&readset);
FD_SET(fd1, &readset); FD_SET(fd2, &readset);
switch(select(5, &readset, NULL, NULL, NULL)){
}

FIFO 특수 파일 생성 : mknod

  • FIFO 파일 뿐만 아니라 특수 파일도 생성하는 명령

mknod 파일명 p

-m 옵션은 새로 생성되는 FIFO 파일의 접근 권한을 지정

mkfifo -m 0644 BIT_FIFO

특수 파일 생성 : mknod()

  • 두 번째 인자인 mode에는 특수 파일의 종류와 접근 권한을 지정
    • S_IFIFO : FIFO 특수 파일
    • S_IFCHR : 문자 장치 특수 파일
    • S_IFBLK : 블록 장치 특수 파일
    • S_IFREG : 일반 파일
    • S_IFSOCK : 유닉스 도메인 소켓 파일
  • 세 번째 인자인 dev는 생성하려는 특수파일이 블록 장치 특수 파일이나 문자 장치 특수 파일일 때만 의미가 있다.

FIFO 파일 생성 : mkfifo()

mkfifo("BIT_FIFO", 0644);

Server.c

int pd, n;
char msg[] = "Hello, FIFO";

mkfifo("./HAN-FIFO", 0666);

pd = open("./HAN-FIFO", O_WRONLY);

n = write(pd, msg, strlen(msg)+1);
close(pd);

Client.c

int pd, n;
char inmsg[80];

pd = open("./HAN-FIFO", O_RDONLY);

while((n = read(pd, inmsg, 80)) > 0) 
	write(1, inmsg, n);
profile
언젠간 전문가가 되겠지

0개의 댓글