我们写一个应用程序,可以调用以下对象共同合作来完成一个功能:
其他可执行程序:系统本身的可执行程序、同事写的、各种解释器(python、shell)
调用单个可执行程序完成简单的功能
调用各种解释器运行各种脚本完成复杂功能(因为脚本里可以再调用不同程序)
公用函数库
系统调用
可以总结为:简单功能(简单的程序) vs 复杂功能(脚本组合不同程序)
简单函数(系统调用) vs 复杂函数(对系统调用的封装)

1 apue里的源代码里有个例子,稍微改一下proc/echoall.c:
#include "apue.h"
int
main(int argc, char *argv[])
{
int i;
char **ptr;
extern char **environ;
for (i = 0; i < argc; i++) /* echo all command-line args */
printf("argv[%d]: %s\n", i, argv[i]);
//for (ptr = environ; *ptr != 0; ptr++) /* and all env strings */
//printf("%s\n", *ptr);
exit(253);
}
单独调用:
root@L-R91239GL-1157:~/study/apue.3e/intro# ./echoall para1 para2
argv[0]: ./echoall
argv[1]: para1
argv[2]: para2
2 shell脚本app.sh
#!/bin/bash
echo "执行的文件名:$0";
echo "第一个参数为:$1";
echo "第二个参数为:$2";
exit 254
单独调用
root@L-R91239GL-1157:~/study/apue.3e/intro# ./app.sh para1 para2
执行的文件名:./app.sh
第一个参数为:para1
第二个参数为:para2
3 python脚本app.py
#!/usr/bin/python
import sys
print("执行的文件名: ",sys.argv[0])
print("第一个参数为: ",sys.argv[1])
print("第二个参数为: ",sys.argv[2])
exit(255)
单独调用
root@L-R91239GL-1157:~/study/apue.3e/intro# ./app.py para1 para2
执行的文件名: ./app.py
第一个参数为: para1
第二个参数为: para2
测试程序app.c:
#include "apue.h"
#include <stdlib.h>
#include <sys/wait.h>
int main(void)
{
pid_t pid1,pid2,pid3;
int stat1,stat2,stat3;
//本程序怎么使用操作系统的服务呢?
//外包给同事:可执行程序,或者各种解释器(shell.python)
printf("程序:\n");
//简单功能
pid1 = vfork();if (pid1 == 0) execl("echoall","not ignore","para1","para2",(char *)0);
//复杂功能
pid2 = vfork();if (pid2 == 0) execl("app.sh","ignore...","para1","para2",(char *)0);
pid3 = vfork();if (pid3 == 0) execl("app.py","ignore...","para1","para2",(char *)0);
waitpid(pid1, &stat1, 0);
waitpid(pid2, &stat2, 0);
waitpid(pid3, &stat3, 0);
printf("父进程等到返回值%d__%d__%d\n",WEXITSTATUS(stat1),WEXITSTATUS(stat2),WEXITSTATUS(stat3));
//调用直接下属:库(为什么叫直接下属呢,因为用标准库更多,很少直接调用系统调用吧)
//复杂函数
printf("\n库\n\n");
//调用间接下属:系统调用
//简单函数
write(1, "系统调用\n", strlen("系统调用\n"));
printf("\n");
exit(0);
}
运行结果:
程序:
argv[0]: not ignore
argv[1]: para1
argv[2]: para2
执行的文件名:app.sh
第一个参数为:para1
第二个参数为:para2
执行的文件名: app.py
第一个参数为: para1
第二个参数为: para2
父进程等到返回值253__254__255
库
系统调用
本文讨论了如何通过应用程序调用不同类型的可执行程序(如系统本身的程序、同事编写的、以及shell和Python解释器)实现简单和复杂功能。文中给出了使用vfork和execl进行功能调用的例子,以及通过系统调用来完成库操作。

被折叠的 条评论
为什么被折叠?



