C语言进程与系统调用

execl,execlp,execle

第一个参数是exec系列函数告诉将要运行什么程序(区别就是execlp可以就是命令的名字,而execl和execle需要完整路径名)
第一个命令行的参数必须是程序名,因此第二个参数和第一个参数是一致的
中间都被当做脚本所需要的参数
最后一个参数是NULL,告诉函数没有其他参数了
如果是以e结尾的exec系列函数(例如execle),还可以传递环境变量数组

例子:
execl('/tmp/test', '/tmp/test', 'param1', 'param2', 'param3', NULL);
execlp('test', 'test', 'param1', 'param2', 'param3', NULL);
execle('/tmp/test', '/tmp/test', 'param1', 'param2', 'param3', NULL, env_vars);

execv,execvp,execve

参数类型,只是把后面的参数传递给了数组

例子:
execv('/tmp/test', my_args);
execvp('test', my_args);

错误信息的一些规定

不允许操作               1
没有该文件或目录          2
没有改进程               3
错误                    -1
正常返回                 0

例子

#include <stdio.h>
/*
    为了使用exec函数
*/
#include <unistd.h>
/*
    为了使用errno变量
*/
#include <errno.h>
#include <string.h>

int main()
{
    if (execl("/sbin/ifconfig", "/sbin/ifconfig", NULL) == -1)
    {
        if (execlp("ipconfig", "ipconfig", NULL) == -1)
        {
            fprintf(stderr, "Cannot run ipconfig: %s", strerror(errno));

            return 1;
        }
    }

    return 0;
}

fork

fork会向子进程返回0,父进程返回非0值

copy-on-write

为了让fork进程变快,操作系统做了很多技巧,比如操作系统不会真的复制父进程的数据,而是让父子进程共享数据,当子进程需要修改存储器,就会为他复制一份数据

重点

exec系列函数执行的时候会启动一个进程,后面的代码不会运行
伪代码:
    code1
    exec系列函数
    code2
    此例中的code2代码不会再运行

如果需要运行获取多个exec系列函数的结果需要使用fork进行
伪代码:
    code1
    pid_t pid_t = fork();
    exec系列函数
    pid_t pid_t = fork();
    exec系列函数

事例(此事例中需要安装python环境,下载rss gossip脚本https://github.com/dogriffiths/rssgossip/zipball/master)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>

 int main(int argc, char *argv[])
 {
    char *feeds[] = {"http://wwww.cnn.com/rss/celebs.xml",
                    "http://www.rollingstone/rock.xml",
                    "http://eonline.com/gossip.xml"
                    };
    int times = 3;
    char *phrase = argv[1];
    int i;
    for(i = 0; i< times; i++) {
        char var[255];
        sprintf(var, "RSS_FEED=%s", feeds[i]);
        char *vars[] = {var, NULL};
        /*
            pid_t是可以理解成一种int的类型
        */
        pid_t pid_t = fork();
        if (pid_t == -1) {
            fprintf(stderr, "can't fork process:%s\n", strerror(errno));
            return 1;
        }

        if (!pid_t && execle("/usr/bin/python", "/usr/bin/python", "./rssgossip.py", phrase, NULL, vars) == -1) {
            fprintf(stderr, "can't run script:%s\n", strerror(errno));
            return 1;
        }
    }

    return 0;
 }
坚持原创技术分享,您的支持将鼓励我继续创作!