Linux C++通讯架构【三】:进程与fork

146 阅读3分钟

fork简单认识

进程:程序执行的一个实例

fork速度很快,新的进程复制页表,不复制内存空间(读时共享,写时复制)

fork子进程函数的返回处:开始执行和父进程相同的代码,和父进程一样。返回两次,子进程返回0,父进程返回子进程id,子进程从返回处返回。

fork失败的可能性:

  • 达到最大pid:32727
  • 达到用户最大进程总数(系统设置,代码中通过sysconf(_SC_CHILD_MAX)可获取最大进程数);

僵尸进程

kill -usrl(信号参数) 1090 父进程收到信号; kill -usrl 1091 子进程收到信号

kill命令杀死子进程,但它仍然存在,因为操作系统担心父进程会用到子进程。 此时,父进程会收到子进程通知的 SIGHLD信号 所以,对于源码中有fork()行为的进程,我们应该拦截并处理SIGHLD信号,让父进程(调用wait或waitpid方法)把这个子进程return。

孤儿进程

孤儿进程:父进程没了,子进程会交给爷爷,也就是init进程,init会回收这个孤儿进程

守护进程

对于普通的进程,父进程是bash,终端退出了,该进程也退出了。

长期运行的的进程,在后台运行,通过终端启动后,终端就不理你了,以后也是操作系统启动,他就启动了。

init:系统守护进程,负责开启各层次的系统服务,ppid=0,keral Thread内核进程,是其他守护进程的爹

守护进程共同点:

  • 都是用root权限运行的
  • 没有控制终端,TT列显示?
    • 内核守护进程(cmd列有[])以无控制终端方式启动
    • 普通守护进程可能是调用了setsid的结果,实现无控制端

守护进程编写规则:

  1. 调用umask(),它是一个函数,用来限制(屏蔽)一些文件权限的。比如你从用户A拷贝了一份压缩文件到你的用户下解压,文件的所有者可能还是用户A。

  2. fork() 一个子进程,然后父进程退出;fork的目的是怕父进程是进程组组长(组长不能setid())

守护进程可以通过命令启动,如果想开机启动,则需要借助系统初始化脚本来启动。如cortab定时任务

守护进程不会收到以下信号:

  • SIGHUP:不会收到内核的SIGHUP信号,潜台词就是如果收到用户的SIGHUP信号,一般表示配置文件已经改动,守护进程应该重新读入其配置文件
  • SIGINT(ctrl+c)、SIGWANCH(终端大小改变)

和后台进程的区别 =》 守护进程和终端无关,后台进程仍是终端的子进程

  • 后台能往终端输出内容
  • 终端关系,后台进程也会退出

文件标识符:

就是一个正整数常量,用来标识一个文件,打开一个存在或创建的文件,都会返回这个文件描述符 0:标输入(键盘),1:标准输出(屏幕),2:标准错误(屏幕) 可以理解为指针,因为指针也是数字:write(“STDOUT_FILENO”,”aaa“,0)屏幕就会输出 aaa准