守护进程即后台运行的服务进程,它独立于控制终端,原因是为了避免被任何终端产生的信息打断,在执行过程中信息也不会在终端显示,关于控制终端可以参考其他资料
### 查看守护进程
```bash
ps axj
```
### 实现过程
- fork创建子进程,父进程退出
- 子进程继续调用setsid创建新会话,此时子进程会成为新会话的首进程,并脱离从父进程继承过来的会话,控制终端
- 再次fork,退出父进程,目的是确保daemon进程不是会话首进程,因为当会话首进程open一个终端设备时会建立控制终端,守护进程不需要控制终端
- unmask(0),确保daemon有足够创建文件和目录的权限
- 修改当前工作目录
- 关闭文件描述符
- 重定向标准输出,标准输入,错误输出到/dev/null
### demo
```c
int daemon()
{
pid_t pid;
int fd, maxfd;
// fork
switch(fork())
{
case -1:
return -1
case 0:
break;
default:
_exit(0);
}
// setsid, create new session
if (setsid() == -1)
{
return -1;
}
// fork
switch(fork())
{
case -1:
return -1;
case 0:
break;
default:
_exit(0);
}
// umask
umask(0);
// chdir
chdir("/");
// close all file descriptor
maxfd = sysconf(_SC_OPEN_MAX);
if (maxfd)
{
for (int i = 0; i < maxfd; ++i)
{
close(i);
}
}
// dup to /dev/null
fd = open("/dev/null", O_RDWR);
if (fd < 0)
{
return -1;
}
if (dup2(fd, STDIN_FILENO) < 0 || dup2(fd, STDOUT_FILENO) < 0 || dup2(fd, STDERR_FILENO) < 0)
{
close(fd);
return -1;
}
close(fd);
return 0;
}
```
- php
- 编译安装
- 基本概念
- 垃圾回收机制
- 生命周期
- zval底层实现
- c扩展开发
- gdb调试工具
- 自定义扩展简单demo
- 钩子函数
- 读取php.ini配置
- 数组
- 函数
- 类
- yaf扩展底层源码
- swoole扩展底层源码
- memoryGlobal内存池
- swoole协程使用记录
- 单点登录sso原理
- compser使用
- session实现机制
- c & linux
- gcc
- 指针
- 结构体,联合和位字段
- 宏定义井号说明
- printf家族函数和可变参数
- 共享函数
- 静态库和动态库
- makefile自动化构建
- 信号一
- 信号二
- inotify监控文件事件
- socket编程
- 简介
- UNIX DOMAIN
- Internet DOMAIN
- TCP/IP
- 文件IO多路复用
- 内存管理
- 进程组,会话和控制终端
- daemon守护进程
- 多进程
- 多线程
- 常用进制转换
- go
- 入门知识
- 字节和整数装换
- python
- redis
- 应用场景
- 消息队列
- 热点数据
- 扫码登录
- 订阅发布
- 次数限制
- 抢购超卖
- 持久化机制
- mysql
- 工作流程
- MyISAM和InnoDB区别
- 用户和权限管理
- 执行计划
- sql优化
- 事务和锁
- 慢查询日志
- case...when...then...end用法
- sql
- 参考
- linux
- 内核参数优化
- 防火墙设置
- docker
- docker入门知识
- 算法
- 多维数组合
- DFA算法
- 红包金额分配