进程常用的三个函数fork、exec、wait(few函数)

109 篇文章 12 订阅
72 篇文章 19 订阅

1、fork():

创建子进程

pid_t fork(void);
    函数的作用:用于创建子进程。
    包含头文件:
        #include <sys/types.h>
        #include <unistd.h>
    返回值:
        fork()的返回值会返回两次。一次是在父进程中,一次是在子进程中。
        在父进程中返回创建的子进程的ID,
        在子进程中返回0
        在父进程中返回-1,表示创建子进程失败,并且设置errno

写时复用,(vfork()函数基本废弃。)

2、exec():

子进程中执行别的程序,参考该文

int execl(const char *path, const char *arg, ...);

int execlp(const char *file, const char *arg, ...);

int execle(const char *path, const char *arg, ..., char *const envp[]);

int execv(const char *path, char *const argv[]);

int execvp(const char *file, char *const argv[]);

int execve(const char *path, char *const argv[], char *const envp[]);

 例子:

int main()
{
    puts("begin");
    fflush(NULL); //exec函数组前需要刷新所有的流
    execl("/bin/date","date","+%s",NULL);//参数是从argv[0]开始的,即从进程名开始的
    perror("execl()");//如果execl成功的话,该语句不执行,执行的话,肯定是失败了。
    exit(-1);
    puts("end");
    exit(0);
}

结果:begin可以打印,end无法打印。 

 注意:因为前面有puts,故在exec前要使用fflush(NULL),如果是在终端中输出是没有问题的,

但如果是重定向到文件时,begin是打印不出来的。因为还没有输出呢,就被exec给替换了。这一点与fork类似。

3、wait():

用在父进程中等待子进程结束后,回收子进程,解除阻塞;若子进程一直没有退出,则阻塞住父进程。

#include <sys/types.h>
#include <sys/wait.h>
pid_t wait(int *status)

wait函数是没有指向的,不针对特定的子进程。
wait函数是死等的,必须等到子进程退出,如果子进程没有退出,则就阻塞在这个地方。

 成功:返回终止进程的ID。

失败:返回-1

status,返回的是进程的退出状态,如果不关心该状态,则置为NULL。

#include <sys/types.h>
#include <sys/wait.h>
pid_t waitpid(pid_t pid,int *status,int options)


waitpid(-1,&status,0)  等价于 wait(&status);

 二者相同的参数 status:

若关心退出状态,则需通过一系列的宏来表明退出状态:

WIFEXITED(status) :是否正常终止。如果正常终止,则返回值为return true.

WEXITSTATUS(status):正常结束的(即WIFEXITED(status)返回真)同时使用该宏,返回结束值,即exit()的参数。(与上一宏连用)

WIFSIGNALED(status):返回true,如果子进程被信号终止(异常退出)。

WTERNSIG(status):如果WIFSIGNALED(status)返回真,(子进程被信号打断,)则返回打断的信号编码。(与上一宏连用)

WCOREDUMP(status):如果WIFSIGNALED(status)返回真,判断,是否产生core dump文件。(与上上一宏连用)

WIFSTOPED(status):如果子进程是stopped by delivery of a signal. 则返回真。

WSTOPSIG(status);如果WIFSTOPED(status)为真,则返回stop的信号。(与上一宏连用)

WIFCONTINUED(status);如果是被stoped ,检测有没有信号将进程继续,有则返回true.(与上上一宏连用????)

waitpid的 option参数,是个位图: 

参数为:
0 :阻塞,死等pid 子进程
WNOHANG  :立即返回,如果没有子进程退出,相当于将阻塞变为非阻塞。

 waitpid的pid 参数:

<-1 :收进程group id = pid的绝对值任何一个子进程。
-1:收任何一个子进程。
0:收与父进程同组process group ID任何的子进程,//没有进程号为0的进程
>0: 指定的子进程id号

命令:ps ajx 查看组ID.

注意:

1)为了避免僵尸进程,fork要与wait成对出现。

2)exec则一般是与fork连用,运行一个新的进程任务。

例1:

#include <QCoreApplication>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
    pid_t pid,son_pid;

    pid = fork();
    if(pid<0)
    {
        perror("fork");
    }else if(pid==0)
    {
        printf("this is son,pid=%d\n",getpid());
        sleep(10);
        printf("son exit\n");
        exit(0);
    }else{
        printf("this is father,pid=%d\n",getpid());
        son_pid = wait(NULL);
        printf("father catch son pid = %d\n",son_pid);
        printf("father exit\n");
        exit(0);
    }
}

 

运行结果: 

  

 通过运行结果发现:子进程和父进程的名字是一样的。

父进程调用wait后,阻塞住等待子进程结束,回收子进程资源。

int main()
{
    pid_t pid;
    puts("beigin");
    fflush(NULL);
    pid = fork();
    if(pid<0)
    {
        perror("fork()");
        exit(1);
    }
    if(pid == 0)
    {
        execl("/bin/date","date","+%s",NULL);
        perror("execl");
        exit(1);
    }
    wait(NULL);
    puts("end");
    exit(0);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值