linux系统编程---进程:exec族和fork配合使用---学习和记录(七)

2023-05-16

为什么要创建子进程:

1、一个父进程希望复制自己,使父,子进程同时执行不同的代码段,这在网络服务进程中是常见的——父进程等待客户端的服务请求。当这种请求到达时,父进程调用fork,使子进程处理此请求。父进程则继续等待下一个服务器请求到达。
2、一个进程要执行一个不同的程序,这对shell是常见的情况,在这种情况下,子进程从fork返回后立即调用exec。
 

exec族函数:execl, execlp, execle, execv, execvp, execvpe

fork函数创建新进程后,经常会在新进程中调用exec函数去执行另外一个程序。当进程调用exec函数时,该进程被完全替换为新程序。因为调用exec函数并不创建新进程,所以前后进程的ID并没有改变。

函数原型:

#include <unistd.h>
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函数族的函数执行成功后不会返回,调用失败时,会设置errno并返回-1,
然后从原程序的调用点接着往下执行

path:可执行文件的路径名字(./a.out,ls, 等一些指令)
arg可执行程序所带的参数,第一个参数为可执行文件名字,没有带路径且arg必须以NULL结束
file:如果参数file中包含/,则就将其视为路径名,否则就按 PATH环境变量,在它所指定的各目录中搜寻可执行文件。

函数例子:execl

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
//int execl(const char *path, const char *arg, ...);
int main(void)
{
    printf("before execl\n");
    if(execl("./execl","execl","abc",NULL) == -1){ //execl(可执行文件)是argv[0],
abc是argv[1],后面必须NULL结尾

        printf("execl failed!\n");
        perron("why");    //打印错误信息
    }
    printf("after execl\n");
    return 0;
}

以上执行失败会返回-1,会打印 execl failed! 并继续往下执行打印 after execl
如果执行成功会从源程序调用点去执行新的程序,不会往下走(不会打印 after execl)

函数例子:打开 ls date 指令

whereis ls //查看ls的路径
date      //获取系统时间

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(void)
{
    printf("before execl\n");
    if(execl("/bin/ls","ls","-l",NULL) == -1){ //打开当前路径 存在的文件
 // if(execl("/bin/date","date",NULL)==-1);    //打开系统时间

        printf("execl failed!\n");
        perror("why:");
    }
    printf("after execl\n");
    return 0;
}

exec族(带p):使用execlp调用ls不再需要添加绝对路径,因为ls的可执行文件在环境变量下,要比execl,少输入一个绝对路径,可直接执行;

函数例子:execlp,如果使用的可执行文件在PATH(环境变量)里面,则使用execlp可以不用详细描述绝对路径-----echo $PATH //将系统PATH路径打出来

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(void)
{
    printf("before execl\n");
    if(execlp("ls","ls","-l",NULL) == -1){
        printf("execl failed!\n");
        perror("why:");
    }
    printf("after execl\n");
    return 0;
}

exec族带v的函数的使用:应先构造一个指向各参数的指针数组,然后将该数组的地址作为这些函数的参数。

如char *arg[]这种形式,且arg最后一个元素必须是NULL,例如char *arg[] = {“ls”,”-l”,NULL};

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(void)
{
    printf("before execl\n");
    char *argv[] = {"ls","-l",NULL};
    if(execvp("ls",argv) == -1){
        printf("execl failed!\n");
        perror("why:");
    }
    printf("after execl\n");
    return 0;
}

 execl和fork的使用:

#include <unistd.h>
#include <stdio.h>
int main()
{
    pid_t pid;
    int data = 0;
    while(1){
        printf("please input a data\n");
        scanf("%d",&data);
        if(data == 1){
        	pid = fork();
            if(pid > 0){
            	wait(NULL);  //等待子进程退出,防止出现僵尸进程
            }
            if(pid == 0){  //在子程序中进行
                execl("./data","data","NULL",NULL); //打开data这个执行文件
            }
       }else{
            printf("wait, do nothing\n");
        }
    }
    return 0;
}

此代码中data 文件是前面的修改函数strstr的程序 此程序最后有 return 退出
execl 减少代码量 看的更清晰明朗,

data文件代码:编译后吧文件定义可执行文件data

#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
int main()
{
    int fd;
    char* Buf = NULL;
    fd = open("./config",O_RDWR);
    int size = lseek(fd,0,SEEK_END);
    lseek(fd,0,SEEK_SET);
    Buf = (char *)malloc(sizeof(char) * size);
    int n_read = read(fd,Buf,size);
    char *p = strstr(Buf,"leng=");
    if(p == NULL){
        printf("NO “leng=”\n");
        exit(-1);
    }
    p = p + strlen("leng=");
    *p = '8';
    lseek(fd,0,SEEK_SET);
    int n_write = write(fd,Buf,strlen(Buf));
    close(fd);
    return 0;
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

linux系统编程---进程:exec族和fork配合使用---学习和记录(七) 的相关文章

  • 超详细讲解Java的数据类型与变量

    超详细讲解Java的数据类型与变量 字面常量数据类型变量整型变量长整型变量短整型变量字节型变量 浮点型变量双精度浮点型单精度浮点型 字符型变量布尔型变量 转换自动类型转换 隐式 强制类型转换 显式 类型提升 字面常量 在System Out
  • java.lang.instrument ASSERTION FAILED ***: “error

    java lang instrument ASSERTION FAILED error 61 61 JVMTI ERROR NONE at Reentrancy c line 161 问题记录 应该是jdk版本更新的问题 第一次运行代码时出
  • C语言实现汉诺塔问题(保姆式讲解)

    前言 大家好 xff0c 又是再一次分享文章 xff0c 我十分感谢各位能够点开这篇花费我颇多时间才解决的汉诺塔问题 xff0c 接下来我就要分享一下自己的所思所想 xff0c 希望能给各位带来一些不一样的收获吧 提醒 汉诺塔问题的本质是函
  • Ubuntu20.04下基于ROS和PX4的无人机仿真平台的基础配置搭建(我所遇到的问题)

    写在前面 xff1a 我目前也处于学习阶段 xff0c 当时按照ROS教程安装的20 04 xff0c 随后搭建XTDrone阶段因为版本问题出现了很多问题 xff0c 这是我根据问题 xff0c 检索后汇总的一些解决措施 本文中提到的问题
  • for 循环无限循环ing....

    题目没思路 xff0c 有思路无法各种错误 xff0c 基础不牢 xff0c 程序的本质理解不透彻 头疼
  • ER图学习笔记(附各个图型的举例,实战案例)

    ER图常用图形如下 xff1a ER图图形含义详解 实体 xff08 长方体 xff09 xff1a 实体字面意思就是实际存在的 xff0c 例如商品 xff0c 货物 xff0c 用户 属性 xff08 椭圆 xff09 xff1a 属性
  • Visual Stdio 2022 C语言源文件调试教程

    下面是一个简单的C语言程序 xff0c 我将以它为例说明如何进行VS2022调试 include lt stdio h gt int main int a b sum a float x y sum b scanf s 34 d d 34
  • 选择排序法和冒泡排序法的比较

    本篇以对元素从小到大有序排列为例 xff0c 比较了选择排序法和冒泡排序法的相同点和不同点 同 xff1a 1 循环结构相同 xff1a 均采用了与i有关的for循环和与j有关的for循环的双层嵌套模式 2 最后结果相同 xff1a 均实现
  • Npm包管理版本机制

    Npm是什么 npm是世界上上 xff0c 使用最广泛的软件管理工具 xff0c 是运行时 Node js 的默认程序包管理器 NPM版本机制 版本号规范 npm是通过版本机制来解决的依赖机制 npm的规范的标准版本号采用 X Y Z 的格
  • to String语句的作用和用法

    在 Java 中 xff0c toString 方法是 Object 类中的一个方法 xff0c 用于返回对象的字符串表示 当我们打印一个对象时 xff0c 实际上是调用了该对象的 toString 方法 如果没有重写该方法 xff0c 将
  • KVM 环境搭建(Base on Ubuntu)

    Kernel based Virtual Machine的简称 xff0c 是一个开源的系统虚拟化模块 xff0c 自Linux 2 6 20之后集成在Linux的各个主要发行版本中 Use the latest kernel of the
  • 为什么这里的int型指针变量为8字节

    include lt stdio h gt void test1 int main test1 return 0 void test1 int num 61 100 取变量地址用 amp amp num代表标量的num的起始地址 print
  • C语言字符查找

    include lt string h gt include lt stdio h gt int main void char string 101 gets string char ptr c scanf 34 c 34 amp c pt
  • 使用vs2022遇到的一些问题

    小白的C语言之路 目录 前言 一 vs2022是什么 xff1f 二 我遇到的几个问题 1 字体调整在哪呢 xff1f 2 同一个项目中练习 xff0c 建立了多个源文件怎么办 xff1f 3 不小心关掉了错误列表 xff0c 解决方案资源
  • strtok函数的模拟实现

    本篇文章属于C语言初阶内容 xff0c 请各位读者选择阅读 目录 1 strtok函数 1 1 strtok函数的说明 1 2 strtok函数的模拟实现 1 strtok函数 1 1strtok函数的说明 首先我们来看strtok函数的定
  • Linux权限 - 概念与管理 | 文件权限的修改与转让 【详解】

    目录 Linux权限 Linux权限的概念 Linux权限的基础操作 1 实现用户账号的切换 2 仅提升当前指令的权限 Linux权限管理 1 文件访问者的分类 xff08 人 xff09 2 文件类型和访问权限 xff08 事物属性 xf
  • acwing蓝桥杯 - 数学知识【上】

    目录 质数 试除法判定质数 分解质因数 筛质数 约数 试除法求约数 约数个数 约数之和 最大公约数 质数 试除法判定质数 这个算法广为人知 xff0c 这里就不证明了 xff0c 解释一下 i lt 61 n 的写法 1 不推荐写成i lt
  • 蓝桥杯AcWing 题目题解 - 递归与递推

    目录 AcWing 92 递归实现指数型枚举 AcWing 93 递归实现组合型枚举 AcWing 94 递归实现排列型枚举 AcWing 1209 带分数 AcWing 1208 翻硬币 AcWing 92 递归实现指数型枚举 从1 xf
  • 蓝桥杯AcWing 题目题解 - 二分与前缀和、差分

    目录 AcWing 789 数的范围 整数二分 AcWing 790 数的三次方根 实数二分 AcWing 730 机器人跳跃问题 二分应用 AcWing 1227 分巧克力 AcWing 795 前缀和 AcWing 796 子矩阵的和
  • acwing蓝桥杯 - 数学知识【下】

    目录 欧拉函数 快速幂 求组合数 I 博弈论 Nim游戏 欧拉函数 在数论 xff0c 对正整数n xff0c 欧拉函数是小于n的正整数中与n互质的数的数目 xff0c 记作 n 1 61 1 1 分解质因子 xff0c 求出质因子p 2

随机推荐