• system函数、fork函数、exec族函数


    如何重命名一个文件?

    如果需要对一个文件进行复制和删除,那么最快的方法是重命名一个文件。所需要时间就在一个cpu周期里面,是原子操作。

    比如,做一个登入登出日志文件管理系统,你需要统计每天的日志文件信息,这时候,你需要复制系统日志文件wtmpx,但是如果你一条数据一条数据或者一个字节一个字节的复制副本,效率会很低,而且这时候可能还有用户登入或者登出系统,需要用到日志文件记录,而这时候由于你又在使用这个日志文件,会照成冲突。这时候是不能用文件锁解决问题的。因为使用日志文件的是系统,你不能跟内核协商使用锁的协议。最好的办法,重命名这个日志文件。

    #include<stdio.h>
    #include<unistd.h>
    #include<sys/stat.h>
    #include<fcntl.h>
    #include<sys/types.h>
    #include<sys/wait.h>
    #include<stdlib.h>
    int main()
    {
    char p[20] = "ttwo.c";
    char pt[20] = "two.c";

    int pid = fork();

    if(pid<0)
    {
    return -1;
    }
    else if(pid==0)
    {
    execl("/bin/mv","mv",pt,p,NULL);
    exit(0);
    }
    int status;
    waitpid(pid,&status,0);
    printf("open ttwo.c\n");
    int fd = open(p,O_RDONLY);
    if(fd>0)
    printf("open success\n");
    close(fd);
    return 0;
    }

    (1)exec函数族说明
    fork 函数是用于创建一个子进程,该子进程几乎拷贝了父进程的全部内容,但是,这个
    新创建的进程如何执行呢?这个exec 函数族就提供了一个在进程中启动另一个程序执行的
    方法。它可以根据指定的文件名或目录名找到可执行文件,并用它来取代原调用进程的数据
    段、代码段和堆栈段,在执行完之后,原调用进程的内容除了进程号外,其他全部被新的进

    程替换了。另外,这里的可执行文件既可以是二进制文件,也可以是Linux 下任何可执行的
    脚本文件。
    在 Linux 中使用exec函数族主要有两种情况:
    · 当进程认为自己不能再为系统和用户做出任何贡献时,就可以调用任何exec 函数族
    让自己重生;
    · 如果一个进程想执行另一个程序,那么它就可以调用fork 函数新建一个进程,然后
    调用任何一个exec,这样看起来就好像通过执行应用程序而产生了一个新进程。(这种情况
    非常普遍)
    (2)exec函数族语法
    实际上,在Linux 中并没有exec()函数,而是有6 个以exec开头的函数族,它们之间语
    法有细微差别,在下面会详细讲解。
    exec 函数族成员函数语法
    所需头文件#include <unistd.h>  
    函数原型      int execl(const char *path, const char *arg, ...)
                 int execv(const char *path, char *const argv[])
                 int execle(const char *path, const char *arg, ..., char *const envp[])
                 int execve(const char *path, char *const argv[], char *const envp[])
                 int execlp(const char *file, const char *arg, ...)
                 int execvp(const char *file, char *const argv[])
    函数返回值-1:出错
    这 6 个函数在函数名和使用语法的规则上都有细微的区别,下面就可执行文件查找方式、
    参数表传递方式及环境变量这几个方面进行比较。
    · 查找方式
    读者可以注意到,表7.3 中的前4 个函数的查找方式都是完整的文件目录路径,而最后
    2个函数(也就是以p结尾的两个函数)可以只给出文件名,系统就会自动从环境变量“$PATH”
    所指出的路径中进行查找。
    · 参数传递方式
    exec函数族的参数传递有两种方式:一种是逐个列举的方式,而另一种则是将所有参数
    整体构造指针数组传递。
    在这里是以函数名的第5 位字母来区分的,字母为“l”(list)的表示逐个列举的方式,
    其语法为char *arg;字母为“v”(vertor)的表示将所有参数整体构造指针数组传递,其语法
    为*const argv[]。读者可以观察execl、execle、execlp的语法与execv、execve、execvp的区别。
    它们具体的用法在后面的实例讲解中会举例说明。
    这里的参数实际上就是用户在使用这个可执行文件时所需的全部命令选项字符串(包括
    该可执行程序命令本身)。要注意的是,这些参数必须以NULL 表示结束,如果使用逐个列
    举方式,那么要把它强制转化成一个字符指针,否则exec将会把它解释为一个整型参数,如
    果一个整型数的长度char *的长度不同,那么exec函数就会报错。
    · 环境变量
    exec 函数族可以默认系统的环境变量,也可以传入指定的环境变量。这里以“e”
    (Enviromen)结尾的两个函数execle、execve 就可以在envp[]中指定当前进程所使用的环境
    变量。
    exec 函数名对应含义
    前4位统一为:execl:
    第5位   l: 参数传递为逐个列举方式execl、execle、execlp
            v:参数传递为构造指针数组方式execv、execve、execvp
    第6位   e:可传递新进程环境变量execle、execve
            p:可执行文件查找方式为文件名execlp、execvp
     
     
     
  • 相关阅读:
    Openssl自签发SSL证书
    营业执照信息识别
    kubernetes容器编排YAML详解
    drf的序列化
    K8S存储
    身份证信息识别
    6.Stream
    11.17个提升开发效率的“轮子”
    1.中台
    8.函数式接口
  • 原文地址:https://www.cnblogs.com/Huayuan/p/2491066.html
Copyright © 2020-2023  润新知