Linux系统下对进程的控制:进程创建/进程终止

进程创建

通常情况下使用 pid_t fork(void) 函数创建一个子进程,返回子进程的pid,创建出来的子进程与父进程代码共享,数据独有。

写时拷贝技术:子进程复制了父进程,一开始与父进程指向同一块物理内存,因此看起来父子进程完全相同;但是进程间具有独立性,意味着当这块物理内存中的数据即将发生变化时会重新给子进程开辟物理空间,将数据拷贝过来,因此子进程拥有自己独立的数据。

代码共享的原因:代码段是只读的。

按理说每个进程都应该有自己独立的内存空间,但是如果创建子进程时直接开辟内存空间进行拷贝,将会比较缓慢,并且拷贝过来的数据有些子进程是不需要,完全用不到的。
创建进程的时候采用写时拷贝技术,目的是为了提高进程的创建效率

早期还有一种进程创建方式
pid_t vfork(void) :创建一个子进程,并且阻塞父进程,知道子进程退出或程序替换后,父进程才会运行。
vfork创建子进程效率很高,因为子进程被创建出来后与父进程共用同一个虚拟地址空间。
Linux系统下对进程的控制:进程创建/进程终止
共用同一个虚拟地址空间,意味着共用代码段,数据段,如果父子进程同时运行会造成栈混乱,因此必须子进程先运行,父进程阻塞,直到子进程退出,所有函数退栈。
在main()函数中的子进程是不能用return退出的,因为return退出会直接释放进程资源。
早期使用vfork()是因为vfork()创建进程效率高,但是fork()实现了写时拷贝技术后,创建效率也变高了,并且使用起来更加灵活,因此vfork()现在已经很少使用了。

那么,为什么要创建一个子进程呢?
创建子进程大多数情况下都不是为了让子进程干跟父进程一样的工作,而是让子进程调度另一个程序运行。

进程终止

退出一个进程:
1.main函数中return --------------------- 退出进程时会刷新缓冲区
2.库函数 exit(int status) ---------------- 退出调用进程,将status作为返回值返回给父进程
3.系统调用接口 _exit(int status) -------退出调用进程,将status作为返回值返回给父进程

①库函数与系统调用接口什么关系?

---- 库函数封装了系统调用接口,系统调用接口对于普通用户来说不太好操作

②return /exit /_exit 这三者有什么区别?

----exit和return在退出时都会刷新缓冲区,_exit退出时直接释放资源,不刷新缓冲区。
----return是在main函数中的时候才会退出进程,然而exit是在任意位置调用都会退出调用进程

除了以上的正常进程退出之外,也有可能异常退出(程序崩溃,程序没有运行完毕突然因为某种错误退出了)