第八节 在进程中执行新程序的三种方法
来源:互联网 发布:大众网络报手游推荐 编辑:程序博客网 时间:2024/06/03 19:11
进程和人类一样,都有产生、生长、睡眠和死亡等各种生命形态。其中,函数fork创建新的进程,函数exec执行新的程序,函数sleep休眠正在执行的进程,函数wait同步进程, exit结束进程,进程就死亡了。
(1) fork - exec
调用fork创建的子进程,将共享父进程的代码空间,复制父进程的进程数据空间, 如堆栈等。调用exec函数后,将会使用新程序的代码覆盖进程中原来的程序代码,并使进程使用函数提供的命令行参数和环境变量去执行新的程序。
exec函数族有六个函数如下:
#include <unistd.h>
int execl(const char *path, const char *arg0, ..., (char *)0);
int execle(const char *path, const char *arg0, ..., (char *)0, char *const envp[]);
int execlp(const char *file, const char *arg0, ..., (char *)0);
int execv(const char *path, const char *argv[]);
int execve(const char *path, const char *argv[], const char *envp[]);
int execvp(const char *file, const char *argv[]);
extern char **environ;
如何用fork-exec方式执行程序'uname -a?
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
int main()
{
pid_t pid;
if((pid = fork()) == 0){
fprintf(stderr, "---- begin ----/n");
// sleep(3); // 睡眠3秒会导致子进程成为僵死进程
execl("/bin/uname", "uname", "-a", 0);
fprintf(stderr, "---- end ----/n");
}
else if(pid > 0)
fprintf(stderr, "fork child pid = [%d]/n", pid);
else
fprintf(stderr, "Fork failed./n");
return 0;
}
[bill@billstone Unix_study]$ gcc exec1 -o exec1
[bill@billstone Unix_study]$ ./exec1
---- begin ----
Linux billstone 2.4.20-8 #1 Thu Mar 13 17:18:24 EST 2003 i686 athlon i386 GNU/Linux
fork child pid = [13276]
[bill@billstone Unix_study]$ ./exec1
---- begin ----
fork child pid = [13278]
[bill@billstone Unix_study]$ Linux billstone 2.4.20-8 #1 Thu Mar 13 17:18:24 EST 2003 i686 athlon i386 GNU/Linux
(2) vfork-exec
vork比起fork函数更快,二者的区别如下:
(a) vfork创建的子进程并不复制父进程的数据,在随后的exec调用中系统会复制新程序的数据到内存。
(b) 父进程以vfork方式创建子进程后将被阻塞,直到子进程推出或执行exec调用后才能继续运行。
当进程只用来执行新程序时,vfork-exec模型比fork-exec模型具有更高的效率,这种方法也是shell创建新进程的方式。
//exec2.c
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
int main()
{
pid_t pid;
if((pid = vfork()) == 0){
fprintf(stderr, "---- begin ----/n");
sleep(3);
execl("/bin/uname", "uname", "-a", 0);
fprintf(stderr, "---- end ----/n");
}
else if(pid > 0)
fprintf(stderr, "fork child pid = [%d]/n", pid);
else
fprintf(stderr, "Fork failed./n");
return 0;
}
[bill@billstone Unix_study]$ gcc exec2.c -o exec2
[bill@billstone Unix_study]$ ./exec2
---- begin ----
fork child pid = [13293]
[bill@billstone Unix_study]$ Linux billstone 2.4.20-8 #1 Thu Mar 13 17:18:24 EST 2003 i686 athlon i386 GNU/Linux
(3) system
在UNIX中,我们也可以使用system函数完成心程序的执行。
nt system(const char * string); 函数说明 system()会调用fork()产生子进程,由子进程来调用/bin/sh-c string来执行参数string字符串所代表的命令,此命>令执行完后随即返回原调用的进程。在调用system()期间SIGCHLD 信号会被暂时搁置,SIGINT和SIGQUIT 信号则会被忽略。 返回值 =-1:出现错误 =0:调用成功但是没有出现子进程 >0:成功退出的子进程的id 如果system()在调用/bin/sh时失败则返回127,其他失败原因返回-1。若参数string为空指针(NULL),则返回非零值>。如果system()调用成功则最后会返回执行shell命令后的返回值,但是此返回值也有可能为 system()调用/bin/sh失败所返回的127,因此最好能再检查errno 来确认执行成功。 附加说明 在编写具有SUID/SGID权限的程序时请勿使用system(),system()会继承环境变量,通过环境变量可能会造成系统安全的问题。
//exec3.c
#include <unistd.h>
#include <stdio.h>
int main()
{
char cmd[] = {"/bin/uname -a"};
system(cmd);
return 0;
}
[bill@billstone Unix_study]$ gcc exec3.c -o exec3
[bill@billstone Unix_study]$ ./exec3
Linux billstone 2.4.20-8 #1 Thu Mar 13 17:18:24 EST 2003 i686 athlon i386 GNU/Linux
[bill@billstone Unix_study]$
- 第八节 在进程中执行新程序的三种方法
- 第八节:在定时中断函数里执行独立按键的扫描程序。
- 第八节:在定时中断函数里执行独立按键的扫描程序。
- Python调用shell命令的几种方法(在新进程中执行shell命令)
- C++第八节:子类的三大件
- 在一个程序中执行另一个程序的方法
- 启动新进程执行程序
- C# 执行cmd命令,以进程的形式执行应用程序,在新的线程中执行耗时的功能逻辑
- 在程序中执行命令行命令的方法
- Android应用程序在新的进程中启动新的Activity的方法和过程分析
- Android应用程序在新的进程中启动新的Activity的方法和过程分析
- Android应用程序在新的进程中启动新的Activity的方法和过程分析
- Android应用程序在新的进程中启动新的Activity的方法和过程分析
- Android应用程序在新的进程中启动新的Activity的方法和过程分析
- 1.[Python]使用subprocess在新的进程中执行命令
- 在服务程序中创建用户进程的方法
- 在服务程序中创建用户进程的方法(C++)
- MFC学习第八节:在数据库的数据在窗口中显示(显示一个学生时)
- html自动换行代码
- 5.5 系统调用_系统调用上下文
- javascript获取label控件的值
- MTK task 小结 补充
- 5.6 系统调用_系统调用小结
- 第八节 在进程中执行新程序的三种方法
- javascript获取div中信息
- erlang学习笔记二 ---精悍的语法
- Intent详解
- [经验总结]解决MFC 进度条无响应的问题
- 父子窗口间传值
- 使用Java操作CSV文件
- javascript之document.open()参数说明
- Tinyxml使用入门