UNIX环境高级编程笔记(6)- 进程控制fork、vfork、wait、waitpid

 

 


前言

本文章简单介绍了fork()、vfork()、wait()、waitpid()函数,以及相应实例。


 

一、函数fork

现有进程可以调用fork函数创建一个新进程,父进程和子进程的执行顺序不定,由内核调度决定。

#include <unistd.h>

pid_t fork(void);  //其中pid_t类型实际上是int类型

父进程和子进程之间的具体区别如下:

>fork的返回值不同

>进程ID不同

>两个进程的父进程ID不同

>子进程不继承父进程设置的文件锁

>子进程的未处理闹钟被清除

>子进程的未处理信号集设置为空集

二、函数vfork

vfork函数的调用序列和返回值与fork相同,但是两者的语义不同。

vfork的函数创建一个新进程,该新进程的目的是exec一个新程序,子进程调用exec或者exit之前,它运行在父进程的空间中。

vfork保证子进程先运行,在它调用exec或者exit之后父进程才能被调度运行。

三、函数wait

#include<sys/wait.h>

pid_t wait(int *statloc);

一个进程在终止前,wait使其阻塞,如果子进程已经终止,并且是一个僵死进程,则wait立刻返回并取得改子进程的状态,否则wait使其调用者阻塞,直到一个进程终止。因为wait返回终止进程的ID,所有它总能了解是哪一个子进程终止了。

四、函数waitpid

#include<sys/wait.h>

pid_t waitpid(pid_t pid,int *statloc,int options);

waitpid函数中pid函数不同值代表不同意义

>pid == -1 等待任一子进程

>pid > 0 等待进程ID与pid相等的子进程

>pid == 0 等待组ID等于调用进程组ID的任一子进程

>pid < -1 等待组ID等于pid绝对值的任一子进程

waitpid函数中options可以去值0、WCONTINUED、WNOHANG、WUNTRACED;支持非阻塞和作业控制。

五、函数实例

1.fork()

代码如下(示例):

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

 

2.vfork()

代码如下(示例):

void unix_8_3_vfork()
{
	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);
}

运行结果如下:

3.wait()

代码如下(示例):

void pr_exit(int status)
{
	if(WIFEXITED(status))
		printf("normal termination,exit status = %d\n",WEXITSTATUS(status));
	else if(WIFSIGNALED(status))
		printf("abnormal termination,signal number = %d\n",WTERMSIG(status));
	else if(WIFSTOPPED(status))
		printf("child stopped,signal number = %d\n",WSTOPSIG(status));
}
void unix_8_6_wait()
{
	pid_t pid;
	int status;

	if((pid = fork()) < 0)
		err_sys("fork error");
	else if(pid == 0)
		exit(7);
	
	if(wait(&status) != pid)
		err_sys("wait error");
	pr_exit(status);

	if((pid = fork()) < 0)
		err_sys("fork error");
	else if(pid == 0)
		abort();

	if(wait(&status) != pid)
		err_sys("wait error");
	pr_exit(status);


	if((pid = fork()) < 0)
		err_sys("fork error");
	else if(pid == 0)
		status/=0;
	if(wait(&status) != pid)
		err_sys("wait error");
	pr_exit(status);

	exit(0);
}

运行结果如下:

4.waitpid()

代码如下(示例):

void unix_8_8_waitpid(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)
            exit(0);

        sleep(2);
        printf("second child,parent pid = %ld\n",(long)getppid());
        exit(0);
    }
    if(waitpid(pid,NULL,0) != pid)
        err_sys("waitpid error");
    exit(0);
}

运行结果如下:

5.main函数

代码如下(示例):

#define UNIX_8_1_FORK
#define UNIX_8_3_VFORK
#define UNIX_8_6_WAIT
#define UNIX_8_8_WAITPID
int main(int argc, char *argv[])
{
#ifdef UNIX_8_1_FORK
    unix_8_1_fork();
#endif
#ifdef UNIX_8_3_VFORK
    unix_8_3_vfork();
#endif
#ifdef UNIX_8_6_WAIT
    unix_8_6_wait();
#endif
#ifdef UNIX_8_8_WAITPID
    unix_8_8_waitpid();
#endif
    printf("MAIN END\n");
    return 0;
}

 


总结

本章主要介绍了进程控制中的fork函数、vfork函数、wait函数、waitpid函数以及代码例程。

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

默默的赶路人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值