Linux下C进程管理(fork,wait,exec)
在我们编程中用的最多是函数,也就是如何函数调用。那我们如何调用函数呢?
一:我们必须要知道函数的功能是什么?
二:再看这个函数需要哪些参数?
三:最后看返回值是什么?
当我们面对一个函数时,既不知道函数的功能也不参数以及返回值时,我们该如何下手呢?
必须得动手查询呗,可以使用函数手册,终端,以及书本资料等、
现在就用fork,wait,exec来举例说明:
fork
功能:创建一个新的进程
一个现存进程调用fork函数是linux内核创建一个新进程的唯一方法(交换进程、init进程和页精灵进程并不是这样,这些进程是由内核作为自举过程的一部分以特殊方式创建的)。
参数:pid_t fork(void);返回值:一个是子进程返回0,第二个是父进程的返回值大于0.错误返回-1.
头文件:include<unistd.h>
wait
功能:等待进程
参数:pid_t wait(int*status);返回值:调用成功,返回子进程的PID,发生错误返回-1。错误原因放在全局变量errno中
头文件:
#include<sys/types.h>
#include<sys/wait.h>
waitpid
函数说明:
在一个子进程结束之前,wait使其调用者阻塞,waitpid使用WNOHANG参数以非阻塞方式等待子进程,waitpid可以指定所需要等待的子进程。
pid == - 1 等待任一子进程。于是在这一功能方面waitpid与wait等效。
pid > 0 等待其进程 I D 与 p i d 相等的子进程。
pid == 0 等待其组 I D 等于调用进程的组 I D 的任一子进程。
pid < - 1 等待其组 I D 等于 p i d 的绝对值的任一子进程。
函数原型:
pid_twaitpid(pid_t pid, int *status, int options);
返回值:执行成功,返回PID为状态改变的子进程。如果指定了WNOHANG,pid参数所代表的子进程没有发生状态变化,0会被返回。执行失败返回-1。错误原因存放在errno中。
头文件:
#include<sys/types.h>
#include <sys/wait.h>
exec功能:在用f o r k函数创建子进程后,子进程往往要调用一个e x e c函数以执行另一个程序
当进程调用一种e x e c函数时,该进程完全由新程序代换,而新程序则从其m a i n函数开始执行。因为调用e x e c并不创建新进程,所以前后的进程I D并未改变。e x e c只是用另一个新程序替换了当前进程的正文、数据、堆和栈段。函数原型:
int execl( constchar *path, const char *arg, ...);
int execlp(const char *file, const char *arg, ...);
int execle( const char *path, const char *arg ,..., char * const envp[]);
int execve(constchar * pathname char *const a rgv [], char *const envp []);
int execv( constchar *path, char *const argv[]);
int execvp(const char *file, char *const argv[]);
巧记:
E:指可以传递环境变量表
L:单独的参数传递,最后要有一个NULL
V:传一个指针数组名
P:按照环境变量来查找
范例:
char*ps_argv[]={“ps”,”ax”, NULL};
char*ps_envp[]={“PATH=/bin:/usr/bin”,”TERM=console”, NULL}
execl(“/bin/ps”,“ps”, “ax”, NULL);
execv(“/bin/ps”,ps_argv);
execle(“/bin/ps”,“ps”, “ax”, NULL, ps_envp);
execve(“/bin/ps”,ps_argv, ps_envp);
execlp(“ps”,“ps”, “ax”, NULL);
execvp(“ps”,ps_argv);
execl(“/bin/ps”,“ps”, “ax”, NULL);
execlp(“ps”,“ps”, “ax”, NULL);
execv(“/bin/ps”,ps_argv);
execvp(“ps”,ps_argv);
返回值:成功了没返回值,失败了返回-1.
头文件:
#include<unistd.h>
代码如下:
#include<stdio.h>
#include<unistd.h>
#include<time.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<stdlib.h>
#include<string.h>
#define BUFSIZE 256
int main(void)
{
pid_t pid;
int i=0,j=0,m=0;
char buf[BUFSIZE],cmd[BUFSIZE];
char *argv[10]={NULL};
char *gete=getenv("HOSTNAME");
printf("%s",gete);
while(1)
{
while(gete[m]!='.')
{
buf[m++]=gete[m];
}
printf("%s@%s%s",getenv("USER"),buf,getenv("PWD"));
fgets(cmd,BUFSIZE,stdin);//stdin表示终端
*strchr(cmd, '\n') = ' ';//strchr查找字符串中第一个出现的指定字符
pid=fork();
if(pid==-1)
{
perror("error!\n");
//perror打印出错误原因信息字符串
exit(-1);
}
else if(pid==0)
{
while (i < BUFSIZE && cmd[i] != '\0')
{ if (cmd[i] != ' ') { argv[j++] = &cmd[i];
i = strchr(&cmd[i], ' ') - cmd; cmd[i] = '\0'; } i++; }
//通过while循环来截取需要的字符,字符串是以'\0' 结束的。
execvp(argv[0], argv);
perror("exec:");
exit(0);
}
else
{
waitpid(pid,NULL,0);
}
}
return 0;
}