进程控制
进程是程序的执行实例,每个进程有唯一的进程id,getpid()返回当前进程id,getppid()返回父进程id
三个用于进程控制的主要函数fork() exec() waited()
fork():
调用fork将创建一个新进程,新进程时调用进程(父进程)的复制品
fork函数在父进程中返回子进程的进程id,在子进程中返回0
如果父进程死亡,则子进程的父进程被置为p1
#include <unistd.h> #include <stdio.h> int main(void) { pid_t fpid; int count = 0; fpid = fork(); if(fpid < 0) printf("error in fork"); else if(fpid == 0) { printf("in the child process,pid is: %d\n",getpid()); count++; } else { printf("in the parent process,pid is: %d\n",getpid()); count++; } printf("count: %d\n",count); return 0; }
程序结果:
in the parent process,pid is 3299
count: 1
in the child process,pid is 3300
count:1
父进程和子进程的环境几乎完全相同,不同的是父进程中fpid=3300(子进程的id),子进程中fpid=0
父进程和子进程中的count初始值都为0且相互不影响
fork()出错返回负值的两种情况:
1)当前进程数已经达到系统规定的上限
2)当前内存不足
exec函数族:
fork创建了子进程后,子进程通常调用exec函数以执行另一个程序,子进程调用exec函数后,该进程完全有新程序代替,新程序从其main开始执行,exec并不创建新的进程
int execl(const char *path,const char *argv,...)
int execlp(const char *file,const char *argv,...,(char *)0)
int execle(const char *path,const char *argv,...,char *const envp[])
int execv(const char *path,cosnt char *argv[])
int execvp(const char *file,const char *argv[],(char *)(0))
int execve(const char *path,const char *argv[],char *const envp[])
这里只举例 int execlp(const char *file,const char* argv,...,(char *)0)
调用这个函数时,从PATH环境变量所指的路径中查找符合file的文件名,找到后执行这个文件,参数是const char *argv,...
执行成功函数不返回,失败则返回-1
例如在pork创建的子进程中想执行ls -al /etc/passwd
if(pid==0)
execlp("ls","ls","-al","/etc/passwd",(char *)0)
需要注意的是,成功执行的话函数并不返回,这时候就需要waitpid进行等待
waitpid():
pid_t waitpid(pid_t pid,int *status,int option)
pid>0时,只等待进程id等于pid的进程直到其结束
pid=-1时,等待当前进程的任一子进程,此时waitpid同wait的作用一模一样
pid=0时,等待同一进程组中的任一进程
pid<-1时,等待指定进程组中的任一子进程,进程组的id等于pid的绝对值
potions可以为WNOHANG WUNTRACED 或0
返回值:正常返回的值时收集到的子进程的id
如果设置了WNOHANG而调用中waitpid发现没有已退出的子进程可以收集,则返回0
出错,返回-1
UNIX高级环境编程中的程序:
#include "apue.h" #include <sys/wait.h> int main(void) { char buf[MAXLINE]; pid_t pid; int status; print("%% "); while((fgets(buf,MAXLINE,stdin) != NULL) { if(buf[strlen(buf)-1] == '\n') buf[strlen(buf)-1] = 0; if(pid=fork() < 0) err_sys("fork error"); else if(pid == 0) { execlp(buf,buf,(char *)0); err_ret("couldn't execute: %s",buf); exit(127); } if((pid = waitpid(pid,&status,0))< 0) err_sys("waitpid error"); printf("%% "); } exit(0); }