1.exec函数
例8.2 设计一个程序,使该程序在运行时,能执行vim程序,即创建一个新的进程。并用ps命令查看程序的进程号与vim的进程号。
源程序代码:
编译、运行该程序,系统会出现运行结果:先显示Linux系统分配的进程号(PID),接着运行vim程序,创建新的进程。
再打开一个终端,用ps查看原进程和新创建进程的进程号(PID)。可以看到,在新进程创建后,原来的进程已经终止了。
在用execve函数创建新进程后,会以新的程序取代原来的进程,然后系统会从新进程运行,但是新进程的PID值会与原来进程的PID值相同。一般情况下,程序在运行execve函数后是不会返回原进程的,只有在错误时才会返回-1,所以在原进程中的execve函数下方,加入perror函数,输出错误信息,并返回1,表示有错误发生。
实际上,Linux中并没有exec函数,而是有6个以exec开头的函数族。
exec函数族的6个成员函数的语法如表8.5所示。
表8.5 exec函数族
事实上,这6个函数中真正的系统调用函数只有execve,其他5个都是库函数,它们最终都会调用execve这个系统调用函数。
execv函数的应用:要在程序中执行命令:ps -ef,命令ps在“/bin”目录下。在这个函数中,参数argv表示参数传递(命令),为此构造指针数组:
char *arg[]={"ps","-ef",NULL};
execlp 函数的应用:要在程序中执行命令:ps -ef,命令ps在“/bin”目录下。在这个函数中,参数l表示命令或参数逐个列举,参数p为文件查找方式(不需要给出路径)。因而此函数的调用形式为:
execlp("ps","ps","-ef",NULL);
execl 函数的应用:要在程序中执行命令:ps -ef,命令ps在“/bin”目录下。在这个函数中,参数l表示命令或参数逐个列举,文件需给定路径。因而此函数的调用形式为:
execl("/bin/ps","ps","-ef",NULL);
2.system函数
system函数是一个和操作系统紧密相关的函数。用户可以使用它在自己的程序中调用系统提供的各种命令。
用户使用system函数时不需要预处理头文件“unistd.h”。
例8.3 设计一个程序,要求测试到LUPA社区的网络连通状况。
编辑源程序代码:
ping是Windows、Unix和 Linux系统下的一个命令,该命令也属于一个通信协议,是TCP/IP协议的一部分。利用ping命令可以检查网络是否连通,可以很好地帮助用户分析和判定网络故障。该命令还可以加许多参数使用,具体请键入ping按回车即可看到详细说明。
编译、运行上面程序,系统会出现运行结果:先显示Linux系统分配的进程号(PID),接着运行ping程序,创建新的进程。(www.xing528.com)
再打开一个终端,用ps查看原进程和新创建进程的进程号(PID),可以看到,原来6-3的进程(PID)值和新进程的父进程号(PPID)值相同,在新进程创建后,原来的进程并没有终止。
注意:在第二个终端的时候,第一个终端中的ping不能结束。
system函数说明如表8.6所示。
表8.6 system函数
3.fork函数
使用fork函数创建进程时,新的进程叫作子进程,原来调用fork函数的进程则称为父进程。
子进程会复制父进程的数据和堆栈空间,并继承父进程的用户代码、组代码、环境变量、已经打开的文件代码、工作目录及资源限制等,但是子进程和父进程使用不同的内存空间。
例8.4 设计一个程序,要求先显示当前目录下的文件信息,然后测试到LUPA社区的网络连通状况。
编辑源程序代码:
编译、运行程序,观察结果。
可以看到,程序使用fork函数创建了一个子进程,子进程的返回值是0,父进程的返回值是子进程的进程号(PID),而子进程的父进程号(PPID)和父进程的进程号(PID)相同。可见,子进程由父进程派生出来。
注意:fork函数使用一次就创建一个进程,因此若把fork函数放在if else判断语句或for循环语句中则要小心,不能多次使用fork函数。
如:
sleep函数说明如表8.7所示。
表8.7 sleep函数
fork函数说明如表8.8所示。
表8.8 fork函数
函数应用1:此例中,为什么用sleep等待10秒钟?
函数应用2:设计一个程序,在子进程中调用函数execl("/bin/ps","ps","-ef",NULL),而在父进程中调用函数execle("/bin/env","env",NULL,envp),其中有定义:char*envp[]={"PATH=/tmp","USER=liu",NULL};
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。