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的结果,实现无控制端
守护进程编写规则:
-
调用umask(),它是一个函数,用来限制(屏蔽)一些文件权限的。比如你从用户A拷贝了一份压缩文件到你的用户下解压,文件的所有者可能还是用户A。
-
fork() 一个子进程,然后父进程退出;fork的目的是怕父进程是进程组组长(组长不能setid())
守护进程可以通过命令启动,如果想开机启动,则需要借助系统初始化脚本来启动。如cortab定时任务
守护进程不会收到以下信号:
- SIGHUP:不会收到内核的SIGHUP信号,潜台词就是如果收到用户的SIGHUP信号,一般表示配置文件已经改动,守护进程应该重新读入其配置文件
- SIGINT(ctrl+c)、SIGWANCH(终端大小改变)
和后台进程的区别 =》 守护进程和终端无关,后台进程仍是终端的子进程
- 后台能往终端输出内容
- 终端关系,后台进程也会退出
文件标识符:
就是一个正整数常量,用来标识一个文件,打开一个存在或创建的文件,都会返回这个文件描述符 0:标输入(键盘),1:标准输出(屏幕),2:标准错误(屏幕) 可以理解为指针,因为指针也是数字:write(“STDOUT_FILENO”,”aaa“,0)屏幕就会输出 aaa准