APUE 학습노트-fork, vfork, fork 2회

3177 단어
/*
 * Fatal error related to a system call.
 * Print a message and terminate.
 */
void
err_sys(const char *fmt, ...)
{
	va_list		ap;

	va_start(ap, fmt);
	err_doit(1, errno, fmt, ap);
	va_end(ap);
	exit(1);
}

/*
 * Print a message and return to caller.
 * Caller specifies "errnoflag".
 */
static void
err_doit(int errnoflag, int error, const char *fmt, va_list ap)
{
	char	buf[MAXLINE];

	vsnprintf(buf, MAXLINE-1, fmt, ap);
	if (errnoflag)
		snprintf(buf+strlen(buf), MAXLINE-strlen(buf)-1, ": %s",
		  strerror(error));
	strcat(buf, "
"); fflush(stdout); /* in case stdout and stderr are the same */ fputs(buf, stderr); fflush(NULL); /* flushes all stdio output streams */ }
#include "myapue.h"

int globvar = 6;
char buf[] = "a write to stdout
"; int main(void) { int var; pid_t pid; var = 88; if(write(STDOUT_FILENO, buf, sizeof(buf) - 1) != sizeof(buf) - 1) err_sys("write error"); printf("before fork
"); if((pid = fork()) < 0){ err_sys("fork error"); }else if(pid == 0){ globvar++; var++; }else sleep(2); printf("pid = %ld, glob = %d, var = %d
", (long)getpid(), globvar, var); exit(0); }

(1)<7>
stdIN_FILENO、stdOUT_FILENO:, 표준 입력과 표준 출력의 파일 설명자를 지정합니다.
(2)<184>
버퍼buf는 이미 알고 있는 문자열로 초기화되었기 때문에 길이가 고정되어 있기 때문에sizeof는 컴파일할 때 버퍼의 길이를 계산합니다.
(3)
write 함수는 버퍼가 없습니다.
printf 함수 버퍼 (표준 IO 라이브러리)
표준 출력이 터미널 장치에 연결되면 행 버퍼입니다.그렇지 않으면 전체 버퍼입니다. (이곳은 프로세스가 끝날 때 버퍼의 내용을 해당 파일에 기록합니다.)
#include "myapue.h"

int globvar = 6;

int main(void)
{
	int var;
	pid_t pid;

	var = 88;
	printf("before vfork
"); if((pid = vfork()) < 0) err_sys("vfork error"); else if(pid == 0){ globvar++; var++; _exit(0); } printf("pid = %ld, glob = %d, var = %d
", (long)getpid(), globvar, var); exit(0); }

(1)<187>
vfork 함수:
1. 부모 프로세스의 주소 공간을 하위 프로세스로 완전히 복사하지 않습니다.하위 프로세스는 exec나 exit 함수를 즉시 호출해야 합니다. 그렇지 않으면 부모 프로세스의 공간에서 실행됩니다. 알 수 없는 결과를 가져올 수 있습니다.
2. vfork는 하위 프로세스가 먼저 실행되고 exec나 exit를 호출한 후에 부모 프로세스가 스케줄링되어 실행될 수 있도록 보장합니다.
(2)<159>
_exit 함수: 프로그램을 정상적으로 종료하고 핵에 들어가 청소 처리를 하지 않습니다.
#include "myapue.h"
int main(void)
{
	pid_t pid;
	
	if((pid = fork()) < 0)
		err_sys("fork error");
	else if(pid == 0){
		if((pid = fork()) < 0)
			err_sys("fork error");
		else if(pid > 0)//first child
			exit(0);
		
		//second child
		sleep(2);
		printf("second child, parent pid = %ld
", (long)getppid()); exit(0); } //parent if(waitpid(pid, NULL, 0) != pid) err_sys("waitpid error"); exit(0); }

(1)<190>
fork 함수: 하위 프로세스의 반환 값은 0이고 부모 프로세스의 반환 값은 새 하위 프로세스의 프로세스 ID입니다.
waitpid 함수: 첫 번째 매개 변수는pid,pid>0: 프로세스 ID가 pid와 같은 하위 프로세스를 기다립니다.성공하면 프로세스를 종료하는 프로세스 ID가 반환됩니다.
(2) 포크를 두 번 호출하면 부모 프로세스는 하위 프로세스가 끝날 때까지 기다릴 필요가 없고, 부모 프로세스의 하위 프로세스가 종료될 때까지 경직 상태에 있을 필요가 없습니다.이렇게 하면 하위 프로세스의 임무를 하위 프로세스의 하위 프로세스에 맡기면 두 임무는 서로 영향을 주지 않는다.

좋은 웹페이지 즐겨찾기