linux系统中进程的创建

来源:互联网 发布:零食店推荐知乎 编辑:程序博客网 时间:2024/05/20 13:07

linux系统的进程创建时区别于其他的系统的,它并没有提供spawn机制。而是把一个进程的创建分成了两步:fork和exec();先创建一个进程,再让子进程执行新的程序。

 

首先系统调用fork()函数,若调用成功则产生一个新的进程,值的一提的是该函数会产生两个返回值。当父进程调用的时候返回0,子进程调用的时候返回子进程的id.linux系统执行该函数产生新的进程较其他系统效率要高,因为它采用了copy-on-write(写时拷贝)进制。也就是linux系统并不是在新的进程产生的同时就立即去拷贝一份父进程的空间。而是当需要写入得时候才会去复制。这样fork()的实际开销就是 复制父进程页表及创建唯一的进程描述符。当有新的数据写入得时候,子进程才会拷贝自己单独的数据和堆栈区。这里值得一提的是vfork()函数,次函数不会复制父进程的页表项,并且运行在父进程的空间中的,可以说是专为后面的exec()金蝉脱壳准备的。vfork()执行 会让父进程堵塞直到其exit()或exec()其他程序。

 

但通常我们并不是要子进程执行像父进程那样的程序,而是要执行新的程序。这时候我们就要用到exec*()库函数了。exec()函数族的作用是根据指定的文件名找到可执行文件,并用它来取代调用进程的内容。产生新的代码,数据,堆栈段。次函数调用成功不返回,失败返回-1.

#include <unistd.h>
int execl(const char *path, const char *arg, ...);
int execlp(const char *file, const char *arg, ...);
int execle(const char *path, const char *arg, ..., char *const envp[]);
int execv(const char *path, char *const argv[]);
int execvp(const char *file, char *const argv[]);
int execve(const char *path, char *const argv[], char *const envp[]);
下面是一个实例:
/* exec.c */
#include <unistd.h>
main()
{
char *envp[]={"PATH=/tmp",
"USER=lei",
"STATUS=testing",
NULL};
char *argv_execv[]={"echo", "excuted by execv",NULL};
char *argv_execvp[]={"echo", "executed by execvp", NULL};
char *argv_execve[]={"env", NULL};
if(fork()==0)
if(execl("/bin/echo", "echo", "executed by execl", NULL)<0)
perror("Err on execl");
if(fork()==0)
if(execlp("echo", "echo", "executed by execlp", NULL)<0)
perror("Err on execlp");
if(fork()==0)
if(execle("/usr/bin/env", "env", NULL, envp)<0)
perror("Err on execle");
if(fork()==0)
if(execv("/bin/echo", argv_execv)<0)
perror("Err on execv");
if(fork()==0)
if(execvp("echo", argv_execvp)<0)
perror("Err on execvp");
if(fork()==0)
if(execve("/usr/bin/env", argv_execve, envp)<0)
perror("Err on execve");
}

程序里调用了2个Linux常用的系统命令,echo和env。echo会把后面跟的命令行参数原封不动的打印出来,env用来列出所有环境变量。

由于各个子进程执行的顺序无法控制,所以有可能出现一个比较混乱的输出--各子进程打印的结果交杂在一起,而不是严格按照程序中列出的次序。

编译并运行:

$ cc exec.c -o exec
$ ./exec
executed by execl
PATH=/tmp
USER=lei
STATUS=testing
executed by execlp
excuted by execv
executed by execvp
PATH=/tmp
USER=lei
STATUS=testing

 

参考资料:

 

          《Linux Kernel Developmnt》

           《Advanced Progrmming in the UNIX Enviromont》

 


 

原创粉丝点击