제1 5 장 프로 세 스 간 통행 15.4 협동 프로 세 스

3643 단어
(1) 협동 프로 세 스 가 무엇 입 니까?
필터 프로그램 이 필터 프로그램의 입력 을 만 들 고 이 필터 프로그램의 출력 을 읽 을 때 협동 프로 세 스 가 됩 니 다.
(2)
협동 프로 세 스 는 보통 셸 배경 에서 실 행 됩 니 다. 표준 입력 과 표준 출력 은 파 이 프 를 통 해 다른 프로그램 에 연 결 됩 니 다.
(3) popen 이 만 든 프로 세 스 와 협동 프로 세 스 의 차이 점.
popen 은 다른 프로 세 스에 연 결 된 표준 입력 이나 표준 출력 을 위 한 단 방향 파이프 만 제공 합 니 다.
협동 프로 세 스 는 다른 프로 세 스에 연 결 된 두 개의 단 방향 파이프 가 있다.
(1) 간단 한 필터 프로그램 (add 2 는 컴 파일 된 실행 가능 한 프로그램)
#include "apue.h"

int
main(void)
{
	int		n, int1, int2;
	char	line[MAXLINE];

	while ((n = read(STDIN_FILENO, line, MAXLINE)) > 0) {
		line[n] = 0;		/* null terminate */
		if (sscanf(line, "%d%d", &int1, &int2) == 2) {
			sprintf(line, "%d
", int1 + int2); n = strlen(line); if (write(STDOUT_FILENO, line, n) != n) err_sys("write error"); } else { if (write(STDOUT_FILENO, "invalid args
", 13) != 13) err_sys("write error"); } } exit(0); }

(2)
프로그램 은 바 텀 I/O (UNIX 시스템 호출): read, write 함 수 를 통 해 표준 입 출력 에 대한 읽 기와 쓰 기 를 실현 합 니 다.(버퍼 가 없 는 I/O 입 니 다) < 7 >
표준 I/O 함수 fgets 와 printf 를 사용 하면 이 프로그램 은 작 동 하지 않 습 니 다.표준 I/O 라 이브 러 리 는 파이프 에 기본적으로 모든 버퍼 를 사용 하기 때문이다.(표준 I/O 함 수 는 버퍼 가 없 는 I/O 함수 에 버퍼 가 있 는 인 터 페 이 스 를 제공 합 니 다)
add 2 가 표준 입력 에서 읽 어서 막 혔 을 때 드라이버 가 파이프 에서 읽 을 때 도 막 혀 서 잠 금 이 생 겼 습 니 다.
setvbuf 함 수 를 통 해 표준 입 출력 을 줄 버퍼 로 바 꾸 어 프로그램 이 정상적으로 작 동 하도록 할 수 있 습 니 다.
다른 상황 에서 필터 프로그램 을 수정 할 수 없다 면 다른 기술 을 통 해 필터 프로그램 이 정상적으로 작 동 할 수 밖 에 없다.예 를 들 어 가짜 단말기 기술.
(3)
int sscanf(const char *str, const char *format, ...);
int sprintf(char *str, const char *format, ...);
이 두 함 수 는 문자열 을 읽 고 쓴다.
(1) 필터 프로그램 을 구동 하 는 프로그램.
#include "apue.h"

static void	sig_pipe(int);		/* our signal handler */

int
main(void)
{
	int		n, fd1[2], fd2[2];
	pid_t	pid;
	char	line[MAXLINE];

	if (signal(SIGPIPE, sig_pipe) == SIG_ERR)
		err_sys("signal error");

	if (pipe(fd1) < 0 || pipe(fd2) < 0)
		err_sys("pipe error");

	if ((pid = fork()) < 0) {
		err_sys("fork error");
	} else if (pid > 0) {							/* parent */
		close(fd1[0]);
		close(fd2[1]);

		while (fgets(line, MAXLINE, stdin) != NULL) {
			n = strlen(line);
			if (write(fd1[1], line, n) != n)
				err_sys("write error to pipe");
			if ((n = read(fd2[0], line, MAXLINE)) < 0)
				err_sys("read error from pipe");
			if (n == 0) {
				err_msg("child closed pipe");
				break;
			}
			line[n] = 0;	/* null terminate */
			if (fputs(line, stdout) == EOF)
				err_sys("fputs error");
		}

		if (ferror(stdin))
			err_sys("fgets error on stdin");
		exit(0);
	} else {									/* child */
		close(fd1[1]);
		close(fd2[0]);
		if (fd1[0] != STDIN_FILENO) {
			if (dup2(fd1[0], STDIN_FILENO) != STDIN_FILENO)
				err_sys("dup2 error to stdin");
			close(fd1[0]);
		}

		if (fd2[1] != STDOUT_FILENO) {
			if (dup2(fd2[1], STDOUT_FILENO) != STDOUT_FILENO)
				err_sys("dup2 error to stdout");
			close(fd2[1]);
		}
		if (execl("./add2", "add2", (char *)0) < 0)
			err_sys("execl error");
	}
	exit(0);
}

static void
sig_pipe(int signo)
{
	printf("SIGPIPE caught
"); exit(1); }

(2)
1) SIGPIPE 의 신호 처리 프로그램 을 등록 합 니 다.
SIGPIPE 신 호 는 프로 세 스 를 읽 지 않 은 파이프 에 쓸 때 발생 합 니 다.
이 예 에서 입력 을 기다 리 는 동안 협동 프로 세 스 를 죽 이 고 두 개의 수 를 입력 하면 이 신호 가 발생 한다.
2) 두 개의 파 이 프 를 만든다.
3) 하위 프로 세 스 를 만 듭 니 다.
4) 부자 프로 세 스 가 필요 하지 않 은 파 이 프 를 각각 닫 습 니 다.
5) 부모 프로 세 스 는 fgets 와 fputs 읽 기와 쓰기 표준 입력 을 사용 하고 write 와 read 읽 기와 쓰기 파 이 프 를 사용 합 니 다.

좋은 웹페이지 즐겨찾기