fork编程之exec函数详解


基本概念:

用fork函数创建新的子进程后,子进程往往要调用一种exec函数以执行另一个程序。当进程调用一种exec函数时,该进程执行的程序完全替换为新程序,而新程序则从其main函数开始执行。因为调用exec并不创建新进程,所以前后的进程ID并未改变。exec只是用磁盘上的一个新程序替换了当前进程的正文段、数据段、堆段和栈段。


系统调用:

EXECVE(2)                  Linux Programmer's Manual                 EXECVE(2)

NAME
       execve - execute program

SYNOPSIS
       #include <unistd.h>

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

其他函数族:

EXEC(3)                    Linux Programmer's Manual                   EXEC(3)

NAME
       execl, execlp, execle, execv, execvp, execvpe - execute a file

SYNOPSIS
       #include <unistd.h>

       extern char **environ;

       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 execvpe(const char *file, char *const argv[],
                   char *const envp[]);


在执行exec后,进程ID没有改变。但新程序从调用进程继承了下列属性:

1.进程ID和父进程ID

2.实际用户ID和实际组ID

3.附属组ID

4.进程组ID

5.会话ID

6.控制终端

7.闹钟尚预留时间

8.当前工作目录

9.根目录

10.文件模式创建屏蔽字

11.文件锁

12.进程信号屏蔽

13.未处理信号

14.资源限制

15.nice值

16.tms_utime、tms_stime、tms_cutime、tms_cstime值


例子:


被执行的新程序:

------ gcc printf.c -o printf -----

#include <stdio.h>
#include <unistd.h>

int main()
{
    while (1) {
        printf("hello world\n");
        sleep(1);
    }

    return 0;
}


主程序:

----- gcc execve.c -----

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

void Perror(const char *s)
{
    perror(s);
    exit(EXIT_FAILURE);
}

int main()
{
    pid_t pid;

    if ((pid = fork()) < 0) {
    } else if (pid == 0) { /* first child */
        if ((pid = fork()) < 0) {
            Perror("fork error");
        } else if (pid > 0) {
            exit(0); /* parent from second fork == first child */
        }

        sleep(2);
        printf("second child pid = %ld, parent pid = %ld\n",
                (long)getpid(), (long)getppid());

        if (execve("printf", NULL, NULL) == -1) /* 程序的路径要绝对路径或者相对路径 */
            Perror("execl error");

        exit(0);
    }

    if (waitpid(pid, NULL, 0) != pid) /* wait for first child */
        Perror("waitpid error");

    printf("parent for first child exit\n");
    return 0;
}

运行:

./a.out


运行结果:



ps:更好的办法是用system函数,参考文章:system函数详解


参考:《unix环境高级编程》·第3版


End;



  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值