pid=fork();
得到返回的值pid,有如下几种情况:
(1) 若pid小于0,则表示fork()出错,相应语句为
if(pid < 0) {
printf(\ exit(0);}
(2) 若pid等于0,则表示当前进程是子进程,继续执行的后面的代码是子进程要做的事,相应的语句可写成 if(pid == 0) {
printf(\ exit(0);}
(3) 若pid大于0,则表示当前进程是父进程,继续执行的后面的代码是父进程要做的事,相应的语句可写成
if(pid > 0) {
printf(\ exit(0);}
由于父进程和子进程分别独立地进入就绪队列等待调度,所以谁会先得到调度是不确定的,这与系统的调度策略和系统当前的资源状态有关。因此谁先从fork()返回,继续执行后面的语句也是不确定的。
2) 父进程和子进程的存放及资源共享
当父进程创建子进程时,首先为子进程分配由task向量数组指向的task_struct结构的内存、所需的堆栈和页表等,创建进程标识号(在系统的进程标识号组中是惟一的),并且将其父进程的进程标识号填入task_struct中的家族信息中。然后将父进程的task_struct的相关内容复制到子进程的task_struct,对一些数据成员进行初始化,如图2所示。
子进程从父进程处继承的资源包括:真实用户标识号和组标识号、有效用户标识号和组标识号、进程组标识号、对话标识号、控制终端、根目录与当前工作目录、设置用户标识号和设置组标识号计位、信号标识、文件描述符、文件默认创建权限掩码、可访问的内存区、线程、环境变量及其他资源分配。
图2 父进程和子进程的内存映像
wait()函数
wait()函数常用来控制父进程与子进程的同步。在父进程中调用wait()函数,则父进程被阻塞,进入等待队列,等待子进程结束。当子进程结束时,产生一个终止状态字,系统会向父进程发出SIGCHLD信号。当接到信号后,父进程提取子进程的终止状态字,从wait()函数返回继续执行原来的程序。
其调用格式为: #include
正确返回:大于0,子进程的进程ID值。
等于0,其他。
错误返回:等于-1,调用失败。
exit()函数
exit()函数是进程结束时最常调用的函数,在main()函数中调用return,最终也是调用exit()函数。这些都是进程的正常终止。在正常终止时,exit()函数返回进程结束状态。
其调用格式为:
#include
kill()函数
kill()函数用于删除执行中的程序或者任务。 其调用格式为: kill(int PID,int IID);
其中,PID是要被杀死的进程号,IID为向将被杀死的进程发送中的中断号。
Signal()函数
signal()函数是允许调用进程控制软中断信号的处理。 其调用格式为:
#include
(1) sig的取值如下:
信号 功能 值 SIGHUP SIGINT 挂起 键盘中断,键盘按Delete键或Break键 1 2 SIGQUIT SIGILL SIGTRAP SIGIOT SIGBUS SIGFPE SIGKILL SIGUSR1 SIGSEGV SIGUSR2 SIGPIPE SIGALRM SIGTERM SIGCHLD SIGCONT SIGPWR 键盘按Quit键 非法指令 跟踪中断 IOT指令 总线错 浮点运算溢出 要求终止进程 用户定义信号#1 段违法 用户定义信号#2 向没有读进程的管道上写 定时器告警,时间到 kill发出的软件结束信号 子进程死 若已停止则继续 电源故障 3 4 5 6 7 8 9 10 11 12 13 14 15 17 18 30 (2)function的解释如下:
SIG_DFL 默认操作。对除SIGPWR和SIGCHLD外所有信号的默认操作是进程终结。对信号SIGQUIT、SIGRAP、SIGLL、SIGFPE、SIGBUS和SIGSEGV,它产生一内存映像文件。
SIG_IGN 忽视该信号的出现。
Function 在该进程中的一个函数地址,在核心返回用户态时,它以软中断信号的序号作为参数调用该函数,对除了信号SIGILL、SIGTRAP、SIGPWAP以外的信号,核心自动地重新设置软中断信号处理程序的值SIG_DFL,一个进程不能捕获SIGKILL信号。
相关推荐: