APUE学习笔记-fork、vfork、fork2次

/*
 * 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, "\n");
	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\n";

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\n");

	if((pid = fork()) < 0){
		err_sys("fork error");
	}else if(pid == 0){
		globvar++;
		var++;
	}else sleep(2);

	printf("pid = %ld, glob = %d, var = %d\n", (long)getpid(), globvar, var);
	exit(0);
	
}

(1)<7>

STDIN_FILENOSTDOUT_FILENO:<unistd.h>,指定标准输入和标准输出的文件描述符。

(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\n");

	if((pid = vfork()) < 0)
		err_sys("vfork error");
	else if(pid == 0){
		globvar++;
		var++;
		_exit(0);
	}

	printf("pid = %ld, glob = %d, var = %d\n", (long)getpid(), globvar, var);
	exit(0);
}

(1)<187>

vfork函数:

    1、它不将父进程的地址空间完全复制到子进程。子进程应立即调用execexit函数,否则它在父进程的空间运行,可能会带来未知的结果。

    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\n", (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)调用两次fork,则父进程不用等待子进程终止,子进程也不用处于僵死状态直到父进程终止,因为父进程的子进程已经终止了。这样把子进程的任务交给子进程的子进程去做,两个任务互不影响。

转载于:https://my.oschina.net/u/2463708/blog/509486

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值