1.什么是进程?
"进程是可并发执行的程序在一个数据集合上的运行过程"。进程是一个程序的一次执行的过程。它和程序是有本质区别的,程序是静态的,它是一些保存在磁盘上的指令的有序集合,没有任何执行的概念;而进程是一个动态的概念,它是程序执行的过程,包括了动态创建、调度和消亡的整个过程。它是程序执行和资源管理的最小单位。因此,对系统而言,当用户在系统中键入命令 执行一个程序的时候,它将启动一个进程。
2._exit()与exit()的区别?
#include <stdlib.h>
#include <unistd.h>
viod exit(int status)
viod _exit(int status)
_exit()函数的作用是直接促使进程停止运行,清楚其使用的内存空间,并清除其在内核中的各种数构;而exit()函数则在执行退出之前加了若干道工序,它要检查文件的打开状况,把文件缓冲区中的内容写回文件,即“清理I/O缓冲”。例如,程序最后存在printf("buffer");而_exit()会直接退出,在缓冲区的”buffer“将不会输出,而exit()函数则会打印出来。如果子进程正常退出,一般status为0,异常退出为非0。
3.wait和waitpid的区别?
#include <sys/types.h>
#inlcude <sys/wait.h>
pid_t wait(int *status)
pid_t wait(pid_t pid,int *status,int options)
其中,status是一个整形指针,是该子进程退出时的状态,若status为空,则代表任意状态结束的子进程;如status不为空,则代表指定状态结束的子进程。
pid用来设置等待进程,其含义如下:
pid>0 只等待进程ID等于pid的子进程,不管已经有其他子进程运行结束退出了,只要指定的子进程还没结束,waitpid就会一直等下去。
pid=-1 等待任何一个子进程退出,此时和wait作用一样
pid=0 等待其组ID等于调用进程的组ID的任一子进程函数传入值;
pid<-1 等待其组ID等于pid的绝对值的任一子进程。
options可选项,通常有如下可选项:
WNOHANG 若由pid指定的子进程不立即可用,则waitpid不阻塞,此时返回值为0;
WUNTRACED 若实现某支持作业控制,则由pid指定的任一子进程状态已暂停,且其状态自暂停以来还没报告过,则返回其状态函数传入值。
如果一个父进程终结,而它的子进程还在,则这些子进程就会被init进程回收。在父进程中调用wait()函数,父进程会处于阻塞状态,等待任一子进程退出;而调用waitpid()函数可以设置为非阻塞状态,即调用waitpid时,如果options参数中指定WNOHANG,则可以使父进程不阻塞而立刻返回0。
处理子进程退出状态值的宏:
WIFEXITED(status) 如果子进程正常退出,则该宏为真
WEXITSTATUS(status) 如果子进程正常退出,则该宏将获取子进程的退出值
WIFSIGNALED(status) 如果子进程被信号杀死,则该宏为真
WTERMSIG(status) 如果子进程被信号杀死,则该宏将获取导致它死亡的信号值
WCOREDUMP(status) 如果子进程被信号杀死且生成核心转储文件,则该宏为真
WIFSTOPPED(status) 如果子进程被信号暂停,且option中WUNTRACED已经被设置时,该宏为真
WSTOPSIG(status) 如果WIFSTOPPED(status)为真,则该宏将获取导致子进程暂停的信号值
WIFCONTINUED(status) 如果子进程被信号SIGCONT重新置为就绪态,则该宏为真
4.什么是Zombie进程?
如果一个进程已经终止,但它的父进程尚未调用wait或waitpid对它进行清理,则这时的进程状态成为僵尸(Zombie)进程。一个进程在终止时会关闭所有文件描述符,释放在用户空间分配的内存,但它的PCB还保留着,内核在其中保存了一些信息:如果是正常终止,则保存这退出状态;如果是异常终止,则保存着导致该进程终止的信号是哪个。这个进程的父进程可以调用wait或waitpid获取这些信息,然后彻底清楚掉这个进程。大家知道,一个进程的退出状态可以在shell中用特殊变量“$?”查看,因为shell是它的父进程,当它终止时,shell调用wait或waitpid得到它的退出状态,同时彻底清除这个进程。
5.编写守护进程的步骤?
(1)创建子进程,父进程退出
pid=fork();
if(pid>0) exit(0);
(2)在子进程中创建新会话
这里使用的是系统函数setsid()
#include <sys/types.h>
#include <unistd.h>
pid_t setsid(void)
(3)改变当前目录为根目录:chdir("/");
(4)重设文件权限掩码:umask(0);
(5)关闭文件描述符
for(i=0;i<getdtablesize();i++)
{
close(i);
}