APUE 학습노트-fork, vfork, fork 2회
/*
* 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) 포크를 두 번 호출하면 부모 프로세스는 하위 프로세스가 끝날 때까지 기다릴 필요가 없고, 부모 프로세스의 하위 프로세스가 종료될 때까지 경직 상태에 있을 필요가 없습니다.이렇게 하면 하위 프로세스의 임무를 하위 프로세스의 하위 프로세스에 맡기면 두 임무는 서로 영향을 주지 않는다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.