C 语言 系统调用 fork 函数
上面的例子的问题就是 exec()
函数通过运行新程序来替换当前程序,那原来的程序去哪儿了?它终止了,而且是立刻终止,这就是为什么程序只为第一条 RSS 源运行了 rssgossip.py 脚本。程序在第一次调用 execle() 以后 rss 程序就终止了。
如果你想在启动另一个进程的同时让原进程续运行下去,就应该使用 fork()
克隆进程。
fork()
会克隆当前进程。新建副本将从同一行(要知道 exec()
是最后一行,因为执行后会退出)开始运行相同程序,变量和变量中的值完全一样,只有进程标识符(PID) 和原进程不同。
原进程叫父进程,而新建本叫子进程。
注意:windows 不支持 fork
解决上面问题的方案就是:用 fork()+exec() 运行子进程,这样父进程就能保持运行了,步骤如下:
- 第一步:fork() 复制当前进程,进程需要以某种方式区分自己是父进程还是子进程,为此 fork() 函数向子进程返回 0,向父进程返回非零值。
- 第二步:子进程调用 exec()
我们修改下:
#include <stdio.h> #include <string.h> #include <errno.h> #include <unistd.h> int main(int argc, char *argv[]) { char *feeds[] = { "http://rss.news.sohu.com/rss/guoji.xml", "http://rss.news.sohu.com/rss/shehui.xml", "http://rss.news.sohu.com/rss/focus.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}; //系统调用 //用参数列表和环境变量,所以用 execle 函数 //./rssgossip.py 脚本位置 //phrase:搜索关键字,以命令行参数传递 //vars:以参数传递环境变量 pid_t pid = fork(); if (pid == -1) { // 如果 pid 为-1 则克隆出了问题 fprintf(stderr, "Can't fork process: %s\n", strerror(errno)); return 1; } if (pid == 0) { // 或 !pid, 运行在子进程 if (execle("/usr/bin/python", "/usr/bin/python", "./rssgossip.py", phrase, NULL, vars) == -1) { fprintf(stderr, "Can't run scrpit:%s\n", strerror(errno)); return 1; } } } return 0; }
那么运行的时候这三个进程同时运行
./rss sohu www.sohu.com www.sohu.com www.sohu.com
一些重要的知识:
- 为了让 fork 更快,操作系统不会真的复制父进程的数据,而是 共享数据
- 如果操作系统发现子进程要修改存储器,则为为它赋值一份数据(写时复制 copy_on_write)
- pid_t 不一定是 int,要取决平台,肯能是 short、long,但一定是整型
- 系统调用时内核中的函数
- exec() 比 system() 提供了更多控制权
- exec() 替换 当前进程
- fork() 复制 当前进程
- 系统调用失败通常返回 -1
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论