1. 会话
意义
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// 1. 会话的意义
会话的核心确实是 统一管理进程与终端的交互,但它不仅限于前台任务,也会管理后台任务。尤其是在多任务、后台任务、终端断开等场景下。
- 你打开的终端(如 bash)就是一个 会话。
- 在这个终端中运行的所有命令(如 vim, top, ping)都属于这个会话的子进程。
- 会话的作用:将这些进程“捆绑”在一起,方便统一管理(比如终端断开时,内核需要知道哪些进程应该被终止或保留)。
// 2. 前后台任务,如何区分前后台任务?
在同一个终端中,你可能同时运行多个任务:
- 前台任务(如 vim):直接与终端交互。
- 后台任务(如 sleep 100 &):不占用终端输入。
- 通过 进程组(Process Group) 将会话内的进程分组,终端只与前台进程组交互。
// 3. 怎么理解 进程组(Process Group) 将会话内的进程分组,终端只与前台进程组交互。
每个会话在任意时刻,只有一个进程组是“前台进程组”,其他进程组都是后台进程组。
// 4. 如何实现“持久化”任务?
tmux 或 screen 会创建一个 独立的会话,即使终端断开,会话仍存在(因为会话不再绑定到原终端)。
// 5. 如何查看当前进程的后台任务
jobs -l
守护进程
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
// 什么是守护进程
守护进程(Daemon Process) 是 Linux/Unix 系统中的一种特殊后台进程,通常在系统启动时运行,脱离终端控制,长期提供服务(如网络、日志、定时任务等)。它的核心特点是 无终端关联、独立运行、生命周期长。
// 创建守护进程举例
// 关键步骤: fork() → setsid() → 重定向标准流 → 脱离文件系统。
// 现代linux 实践:使用 systemd 控制
int main() {
pid_t pid = fork();
if (pid > 0) exit(0); // 父进程退出
setsid(); // 创建新会话
chdir("/"); // 切换工作目录
umask(0); // 重置文件权限掩码
// 关闭所有文件描述符(可选)
for (int i = sysconf(_SC_OPEN_MAX); i >= 0; i--) close(i);
// 重定向标准流
freopen("/dev/null", "r", stdin);
freopen("/dev/null", "w", stdout);
freopen("/dev/null", "w", stderr);
// 守护进程的主逻辑
while (1) {
// 例如:每隔 10 秒写入日志
system("echo 'Daemon is running...' >> /var/log/mydaemon.log");
sleep(10);
}
return 0;
}
聊聊 systemd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// waf systemd 单元
root>cat /lib64/systemd/system/cneos.service
[Unit]
Description=cneos start service # 服务的描述信息,方便管理员识别。
Before=network.target sshd.service #表示该服务会在 network.target(网络就绪)和 sshd.service(SSH 服务)之前启动。
[Service]
Type=forking # 1. 表示服务启动时会 fork 子进程,并且父进程会退出(传统守护进程行为)。
# 2. start_service.sh 必须 后台化(如使用 & 或 setsid),否则 systemd 会认为服务启动失败。
ExecStart=/bin/bash /bin/start_service.sh # 通过 bash 执行 /bin/start_service.sh
TimeoutStartSec=0 # 禁用启动超时,即允许服务无限期启动(适用于长时间初始化)。
KillMode=none # 当停止服务时,不杀死任何进程(即使主进程退出,子进程仍继续运行)。
[Install]
WantedBy=multi-user.target # 通过 systemctl enable cneos.service 启用后,开机时会自动运行。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 什么是systemctl
1. systemctl 是 Linux 系统和服务管理器(systemd) 的核心命令行工具,用于管理系统服务、守护进程、挂载点、套接字等资源。
2. systemd 是 Linux 的初始化系统
// 常见命令
sudo systemctl start cneos.service # 启动服务
sudo systemctl status cneos.service # 状态检查
sudo systemctl enable cneos.service # 开机自启
journalctl -u cneos.service -f # 实时日志
// 怎么查看 服务是否注册 systemctl
systemctl list-units --type=service // 之前waf串口登录失败可看tty 串口服务是否启动
// 怎么查看对应systemctl 日志
sudo journalctl -u getty@tty0.service
哪些进程在终端终止后会退出
| 命令 | 终端关闭后是否被终止 | 说明 |
|---|---|---|
python xxx.py | ✅ | 前台进程,属于当前会话。 |
python xxx.py & | ✅ | 后台进程,但仍属于当前会话。 |
nohup python xxx.py & | ❌ | 忽略 SIGHUP,进程继续运行。 |
setsid python xxx.py | ❌ | 创建新会话,完全脱离原终端。 |
(python xxx.py &) | ✅ | 子 shell 退出后,进程仍属于原会话(除非配合 disown)。 |
tmux new-session -d 'python xxx.py' | ❌ | 在 tmux 独立会话中运行,脱离原终端。 |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 0. python xxx.py &
不同的终端, 这个表现不一样。 有些终端退出后这个并不会被一起退出。
// 1. 如何查看当前进程的后台任务
jobs -l
// 2. ctl + c && ctl + z 有什么区别?
root>jobs -l
[1] 8640 Stopped tail -f /var/log/wafd.log
8641 | grep ABSORB_STAR (wd: ~)
[2]- 6236 Stopped tail -f /var/log/wafd.log
6237 | grep ABSORB_STAR (wd: ~)
[3]+ 22304 Stopped journalctl -u cneos.service -f
一个是暂停 一个是退出
Ctrl + Z 和 Ctrl + C 是完全不同的操作,它们分别发送不同的信号并产生不同的行为
setsid
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// setsid 是一个 Linux/Unix 命令和系统调用,用于 创建一个新的会话(Session),并让当前进程成为该会话的首进程(Session Leader)。它的核心作用是 脱离原终端的控制,常用于守护进程(Daemon)或需要独立运行的进程
// fork() + setsid() 是创建守护进程的标准方式。
int main() {
pid_t pid = fork();
if (pid == 0) { // 子进程
setsid(); // 创建新会话,脱离原终端
// 守护进程逻辑...
while (1) {
// do something
}
}
return 0;
}
2. 作业调度
| 命令 | 作用描述 | 示例 |
|---|---|---|
jobs | 列出当前Shell会话中的所有作业及其状态 | jobs -l |
fg %n | 将作业n切换到前台运行 | fg %1 |
bg %n | 将作业n切换到后台运行 | bg %2 |
kill %n | 终止作业n | kill %3 |
1
2
3
4
5
6
root>jobs
[3]- 已停止 tail -f /var/log/wafd.log | grep solution
[4]+ 已停止 find / -name "libthread_db*"
root>fg %1
tail -f /var/log/wafd.log | grep solution (wd: /opt/data/engine_coredump)