一) 创建进程
1. fork系统调用
fork调用创建一个新进程。新的进程或者说子进程是调用进程或者说父进程的副本。fork语法是:
#include <unistd.h>
pid_t fork(void);
如果fork执行成功,就向父进程返回子进程的PID,并向子进程返回0。这意味着你只调用fork一次,它也返回两次。
Fork创建的新进程是和父进程一样的副本,包括真实和有效UID和GID、进程组和会话ID、环境、资源限制、打开的文件以及共享内存段。
如下程序清单展示一个使用fork的简单示例程序。
/************************ child.c ***************************/
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
pid_t child;
if((child=fork())==-1)
{
perror("fork");
exit(EXIT_FAILURE);
}
else if(child==0)
{
puts("in child");
printf("/tchild pid = %d/n",getpid());
printf("/t child ppid = %d/n",getppid());
exit(EXIT_SUCCESS);
}
else
{
puts("in parent");
printf("/t parent pid = %d/n",getpid());
printf("/t parent ppid = %d/n",getppid());
}
exit(EXIT_SUCCESS);
}
执行命令编译该程序。这个程序的输出应该和下面类似:
$./child
in parent
in child
child pid = 14091
child ppid = 14090
parent pid = 14090
parent ppid = 1549
二)控制进程
1. 等待进程--------wait函数族
一旦你用fork创建一个子进程,为了收集新进程的退出状态并防止出现僵进程,父进程应该等待子进程结束。
使用wait或waitpid函数可以收集子进程的退出状态。它们的原形如下:
#include <sys/wait.h>
#include <sys/types.h>
pid_t wait(int *status);
pid_t waitpid(pid_t pid,int *status,int options);
status保存子进程的退出状态。Pid是等待进程的PID。
Options规定wait调用的行为应该如何。它可以使WNOHANG,导致waitpid在没有子进程退出进程时立即返回,也可以是WUNTRACED,意味着它应该因为存在没有报告状态的进程而返回。你也可以对它们执行逻辑“或”(OR)操作,取得两种行为(也就是说,给options参数传送WHOHANG||WUNTRACED)。
1. 杀死进程
一个进程由于以下5个原因中的一个而终止。
。它的main函数调用了return
。它调用了exit
。它调用了_exit
。它调用了abort
。它被一个信号终止
前3个理由是正常终止,而后2和则是非法正常终止。但是无论进程为何终止,最后都执行相同的内核代码、关闭打开的文件、释放内存资源,并且执行其他要求的清理工作。
exit函数
这个函数在<stdlib.h>中声明的原型如下:
int exit(int status);
exit导致程序正常并且返回父进程的状态(status)。
_exit函数在<unistd.h>中声明。它立即终止调用它的进程。
使用abort函数
如果你需要异常地终止一个程序,可以使用abort函数。在Liux下,abort还可以让程序产生内存转储(core dump),这是大多数调式器用于分析程序崩溃时的文件。虽然任何打开的文件都被关闭了,但abort函数仍然是个粗暴的调用,应该作为最后的手段来使用,比如你碰到类似严重内存不足这样的错误,无法用程序的方法处理时再用。Abort也是一个标准库函数,它原型为
#include <stdlib.h>
void abort(void);
下面的程序显示了abort函数如何运行。
/*********************** abort.c ************************/
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
abort();
/*shouldn’t get here*/
exit(EXIT_SUCCESS);
}
使用gcc编译这个程序,并如下执行:
$./abort
Aborted
Sulimit –c unlimited
$./abort
Aborted(core dumped)
注意你的系统可能不能生成一个core文件。如果它没有生成core文件,则按照上面的示范运行来使用shell的命令ulimit。
使用kill函数
一个进程能调用kill函数杀死另一个进程,它的原型如下:
#include <signal.h>
#include <sys/types.h>
int kill(pid_t pid,int sig);
pid指定了要杀死的进程,而sig是要发送的信号,如:SIGTERM,SIGKILL。
三)其它
1. 睡眠函数
#include <stdlib.h>
int sleep(int sec);
sec 指示要睡眠的时间(秒)。