- 本章主要内容:以实现一个shell为例,用fork创建一个子进程,用exec在子进程运行一个程序,用exit结束子进程并返回信息给父进程,父进程通过wait来获取子进程结束的信息。
- Unix通过将可执行代码(即程序)载入进程并执行它来运行一个程序。进程是运行一个程序所需的内存空间和其他资源的集合。
- 每个运行中的程序在自己的进程中运行。每个进程都有一个唯一的PID、所有者、大小及其他属性。
- 系统调用fork()通过复制调用它的进程来建立一个几乎和调用进程完全相同的副本进程。这个新建的进程被称为子进程。
1、当一个进程调用fork之后,就有两个二进制代码相同的进程。而且它们都运行到同一个地方。新的进程是从fork返回的地方开始,而不是从新开始。
2、通过fork返回值可辨别父进程或子进程,父进程调用fork,返回值为子进程的pid,或-1。而子进程从fork返回值开始,fork返回0。
- 一个程序通过调用exec函数族在当前进程中执行一个新的程序。
exec系统调用族从当前进程中把当前程序的机器指令清除,然后在空的进程中载入调用时指定的程序代码,最后运行这个新的程序。exec调整进程的内存分配使之适应新的程序对内存的要求。相同的进程,不同的内容。
- 父进程通过调用wait来等待子进程的结束。
1、wait阻塞调用它的程序来等待子进程调用exit
2、子进程结束,wait返回值是调用exit的子进程的pid,以此来通知父进程子进程结束运行了
3、wait能够告诉父进程子进程是如何结束的。如果进程是正常调用exit,通过exit的返回值传递到wait的参数中告诉的。如果进程是被信号杀死的,则内核会传递信号序号给wait参数。wait的参数是个16bit的整数
4、一个进程以(成功、失败、死亡)之一结束。成功结束调用exit(0)。失败结束,exit时传给它一个非零的值。进程被信号杀死。
- 调用程序能通过exec函数族来将一个字符串列表传给新程序的main函数。新的程序能通过调用exit来回传一个16位长的值。
- Unix shell通过调用fork、exec和wait来运行程序。通过fork建立新进程,用exec在新进程中运行用户指定的程序,最后shell用wait等待新进程结束。wait系统调用同时通过子进程exit从内核取得子进程如何结束。
- fork,exce/exit与call/return
fork,exce/exit是程序之间的调用,call\return是函数之间的调用
- 进程死亡exit和_exit
1、exit是fork的逆操作,进程通过调用exit来停止运行。exit通_exit系统调用终止当前进程并执行所有必须的清理工作。exit的参数是调用进程结束最后的遗言,这个遗言是要父进程调用wait来获取。
2、那些已经死亡但是还没有给exit赋值的进程就称为僵尸进程。因为父进程不知道子进程它们已经死亡了
3、_exit的操作
(1)关闭所有的文件描述符和目录描述符
(2)将该进程pid置为init进程的pid。
(3)如果父进程调用wait或waitpid来等待子进程结束,则通知父进程
(4)向父进程发送SIGCHLD
SIGCHLD是无论父进程有没有调用wait,都会发送。利用这一点,可以用信号机制实现父进程与子进程并行,而无须挂起父进程,也可以通知父进程子进程结束的信息。
- 本章系统调用,命令
1、fork()创建进程
#include
pid_t result = fork(void)
成功返回:父进程返回创建的子进程的pid,子进程返回0
失败:-1
2、exec函数族 进程运行一个程序
#include
result = execvp(const char *file,const char *argv[])
成功执行,没有返回值,当前程序从进程中清除,新的程序在当前进程中运行
3、wait等待进程结束
#include
#include
pid_t result = wait(int *statusptr)
wait系统调用挂起调用它的进程知道得到这个进程的子进程的exit一个结束状态。
成功返回结束子进程的pid
4、exit 结束进程,回收资源,传递进程结束的遗言
5、命令
(1)ps \\查看运行的进程
(2)sh \\命令解释器
(3)在命令后加上&,则命令在后台执行,如ps &
(4)信号ctrl+D 是EOF的意思,关闭shell。ctrl+c 是中断
ctrl+\是结束。
阅读(653) | 评论(0) | 转发(0) |