一、system函数-调用shell进程,开启新进程
system函数,是通过启动shell进程,然后执行shell命令进程。
函数原型:
int system(const char *string);
string:shell命令字符串
返回值:成功返回命令退出码,无法启动shell,返回127错误码,其他错误,返回-1。
#include <stdlib.h>
#include <stdio.h>
int main()
{
system("ls");
printf("Done\n");
exit(0);
}
system函数,在启动新进程时,必须先启动shell进程,因此使用system函数的效率不高。
二、exec系列函数-替换进程映像
exec系列函数调用时,启动新进程,替换掉当前进程。即程序不会再返回到原进程,
除非exec调用失败。
exec启动的新进程继承了原进程的许多特性,如在原进程中打开的文件描述符在新进程中仍保持打开。
需要注意的是,在原进程中打开的文件流在新进程中将关闭。原因在于,我们在前面讲过进程间通信的方式,进程之间需要管道才能通信。
int execl(const char *path,const char *arg0,...,(char*)0);
int execlp(const char *file,const char *arg0,...,(char*)0);
int execle(const char *path,const char *arg0,...,(char*)0,char *const envp[]);
int execv(cosnt char *path,char *const argv[]);
int execvp(cosnt char *file,char *const argv[]);
int execve(cosnt char *path,char *const argv[],char *const envp[]);
path/file:进程命令路径/进程命令名
argc:命令参数列表
envp:新进程的环境变量
#include <stdlib.h>
#include <stdio.h>
int main()
{
execlp("ls","ls","-l",(char*)0);
printf("Done\n");
exit(0);
}
三、fork函数-复制进程映像
fork和exec的替换不同,调用fork函数,可复制一个和父进程一模一样的子进程。
执行的代码也完全相同,但子进程有自己的数据空间,环境和文件描述符。
#include<stdio.h>
#include<sys/types.h>
int main()
{
int stat = 0;
pid_t pid = fork();
switch(pid)
{
case -1:
perror("fork failed");
exit(1);
break;
case 0:
printf("\n");
execlp("ls","ls","-l",0);
break;
default:
pid = wait(&stat);
printf("parent,ls done\n");
break;
}
exit(0);
}
四、总结
1)system函数最简单,启动shell进程,并在shell进程中执行新的进程。
效率不高,system函数必须等待子进程返回才能接着执行。
2)exec系列函数用新进程替换掉原进程,但不会返回到原进程,除非调用失败。
该函数继承了许多原进程的特性,效率也较高。
3)fork函数,复制一个子进程,和父进程一模一样,但是拥有自己的内存空间。父子进程执行互不影响。需要注意僵尸子进程的问题。