• 忘掉天地
  • 仿佛也想不起自己
bingliaolongBingliaolong  2020-03-28 23:19 Aet 隐藏边栏 |   抢沙发  0 
文章评分 0 次,平均分 0.0

进程的创建

  • system函数
    • system函数通过调用shell程序/bin/sh –c来执行string所指定的命令,该函数在内部是通过调用execve(“/bin/sh”,..)函数来实现的。通过system创建子进程后,原进程和子进程各自运行,相互间关联较少。如果system调用成功,将返回0。

  • fork函数
    • 在linux中fork函数时非常重要的函数,它从已存在进程中创建一个新进程。新进程为子进程,而原进程为父进程。它和其他函数的区别在于:它执行一次返回两个值。其中父进程的返回值是子进程的进程号,而子进程的返回值为0.若出错则返回-1.因此可以通过返回值来判断是父进程还是子进程。
    • fork函数创建子进程的过程为:使用fork函数得到的子进程是父进程的一个复制品,它从父进程继承了进程的地址空间,包括进程上下文、进程堆栈、内存信息、打开的文件描述符、信号控制设定、进程优先级、进程组号、当前工作目录、根目录、资源限制、控制终端,而子进程所独有的只有它的进程号、资源使用和计时器等。通过这种复制方式创建出子进程后,原有进程和子进程都从函数fork返回,各自继续往下运行,但是原进程的fork返回值与子进程的fork返回值不同,在原进程中,fork返回子进程的pid,而在子进程中,fork返回0,如果fork返回负值,表示创建子进程失败。(vfork函数)

  • exec*函数
    • exec*由一组函数组成

add.c

main.c

  • popen函数
    • popen函数类似于system函数,与system的不同之处在于它使用管道工作

进程的控制

  • 用fork函数启动一个子进程时,子进程就有了它自己的生命并将独立运行。
  • 如果父进程先于子进程退出,则子进程成为孤儿进程,此时将自动被PID为1的进程(即init)接管。孤儿进程退出后,它的清理工作有祖先进程init自动处理。但在init进程清理子进程之前,它一直消耗系统的资源,所以要尽量避免。

示例孤儿进程:

  • 通过ps –ef就可以看到此时子进程一直在运行,并且父进程是1号进程。
  • 如果子进程先退出,系统不会自动清理掉子进程的环境,而必须由父进程调用wait或waitpid函数来完成清理工作,如果父进程不做清理工作,则已经退出的子进程将成为僵尸进程**(defunct)**,在系统中如果存在的僵尸(zombie)进程过多,将会影响系统的性能,所以必须对僵尸进程进行处理。
    • wait和waitpid都将暂停父进程,等待一个已经退出的子进程,并进行清理工作
    • wait函数随机地等待一个已经退出的子进程,并返回该子进程的pid
    • waitpid等待指定pid的子进程;如果为-1表示等待所有子进程

示例僵尸进程:

避免僵尸进程:

利用信号处理避免僵尸进程

利用waitpid实现

进程的终止

  • main函数的自然返回
  • 调用exit函数
  • 调用_exit函数
  • 调用abort函数
  • 接收到能导致进程终止的信号ctrl+c SIGINT ctrl+\ SIGQUIT

前3种方式为正常的终止,后2种为非正常终止。但是无论哪种方式,进程终止时都将执行相同的关闭打开的文件,释放占用的内存等资源。只是后两种终止会导致程序有些代码不会正常的执行比如对象的析构、atexit函数的执行等

  • exit和exit函数都是用来终止进程的。
  • _当程序执行到exit和_exit时,进程会无条件的停止剩下的所有操作,清除包括PCB在内的各种数据结构,并终止本程序的运行。
    • 但是它们是有区别的,exit和exit的区别如图所示:
    • _exit函数和_exit函数的最大区别在于exit函数在退出之前会检查文件的打开情况,把文件缓冲区中的内容写回文件,就是图中的“清理I/O缓冲”。
  • 由于linux的标准函数库中,有一种被称作“缓冲I/O”操作,其特征就是对应每一个打开的文件,在内存中都有一片缓冲区。每次读文件时,会连续读出若干条记录,这样在下次读文件时就可以直接从内存的缓冲区中读取;同样,每次写文件的时候,也仅仅是写入内存中的缓冲区,等满足一定的条件(如达到一定数量或遇到特定字符等),再将缓冲区中的内容一次性写入文件。这种技术大大增加了文件读写的速度,但也为编程带来了麻烦。比如有一些数据,认为已经写入文件,实际上因为没有满足特定的条件,它们还只是保存在缓冲区内,这时用_exit函数直接将进程关闭,缓冲区中的数据就会丢失。因此,如想保证数据的完整性,建议使用exit函数。

本文为原创文章,版权归所有,欢迎分享本文,转载请保留出处!

bingliaolong
Bingliaolong 关注:0    粉丝:0 最后编辑于:2021-11-20
Everything will be better.

发表评论

表情 格式 链接 私密 签到
扫一扫二维码分享