查看进程信息与设置进程优雅退出

以下是如何在Linux/Unix系统中查看进程信息以及设置进程优雅退出的方法,使用常用命令和工具,结合C++编程示例。

1. 查看进程信息

方法1:使用 ps 命令

ps 命令用于显示进程信息,常用选项如下:

  • ps aux:显示所有用户的所有进程。
    • a:显示所有用户的进程。
    • u:显示详细用户信息。
    • x:显示无终端的进程。
  • ps -ef:显示所有进程,包含完整命令行。
  • ps -p <PID>:查看指定进程ID(PID)的详细信息。

示例
查看所有进程的PID、用户、CPU/内存使用情况:

1
ps aux

输出示例:

1
2
3
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root 1 0.0 0.1 123456 7892 ? Ss Jun28 0:01 /sbin/init
alice 1234 1.2 0.5 987654 12345 pts/0 S 10:00 0:10 myapp

筛选特定进程(如名为 myapp):

1
ps aux | grep myapp

方法2:使用 tophtop

  • top:实时显示进程信息,按CPU/内存使用排序。
    • q 退出,k 输入PID终止进程。
  • htop:更友好的交互式工具(需安装)。
    • 示例:htop,然后用箭头选择进程,按 F9 选择信号终止。

方法3:使用 /proc 文件系统

Linux下,/proc/<PID> 目录包含进程详细信息:

  • /proc/<PID>/status:进程状态、内存使用等。
  • /proc/<PID>/cmdline:进程启动命令。

示例
查看PID为1234的进程状态:

1
cat /proc/1234/status

输出示例:

1
2
3
4
Name:   myapp
State: S (sleeping)
Pid: 1234
VmSize: 987654 kB

方法4:使用 pidstat(需安装 sysstat

查看进程资源使用情况:

1
pidstat -p 1234

输出CPU、内存、I/O等详细信息。

2. 设置进程优雅退出

优雅退出(Graceful Shutdown)是指进程在接收终止信号后,完成当前任务、释放资源(如关闭文件、网络连接)后安全退出。通常通过捕获信号(如SIGTERM)实现。

方法1:使用信号终止进程

Linux常用信号:

  • SIGTERM(15):请求进程优雅退出(默认信号)。
  • SIGKILL(9):强制终止(不推荐,可能导致资源未释放)。
  • SIGHUP(1):常用于重新加载配置或优雅退出。

命令行终止进程

  • 优雅退出:
    1
    2
    3
    kill -SIGTERM <PID>
    # 或
    kill <PID> # 默认发送SIGTERM
  • 强制终止:
    1
    2
    3
    kill -SIGKILL <PID>
    # 或
    kill -9 <PID>

查找并终止特定进程
杀死名为 myapp 的进程:

1
pkill -SIGTERM myapp

方法2:编程实现优雅退出(C++示例)

在程序中捕获 SIGTERM 信号,执行清理操作后退出。

示例代码

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
31
32
#include <iostream>
#include <csignal>
#include <unistd.h>
#include <atomic>

std::atomic<bool> running(true);

// 信号处理函数
void signalHandler(int signum) {
std::cout << "Received signal " << signum << ", shutting down gracefully...\n";
running = false; // 设置标志,通知程序退出
}

int main() {
// 注册SIGTERM信号处理
signal(SIGTERM, signalHandler);
signal(SIGHUP, signalHandler);

std::cout << "Process running (PID: " << getpid() << "). Press Ctrl+C or send SIGTERM to exit.\n";

// 模拟工作循环
while (running) {
std::cout << "Working...\n";
sleep(1); // 模拟工作
}

// 清理资源
std::cout << "Cleaning up resources...\n";
// 关闭文件、网络连接等
std::cout << "Process exited gracefully.\n";
return 0;
}

说明

  • signal(SIGTERM, signalHandler):注册 SIGTERM 信号处理函数。
  • std::atomic<bool>:确保线程安全的标志变量。
  • 程序收到 SIGTERM 后,设置 running = false,退出循环,执行清理后退出。

编译与运行

1
2
g++ -o myapp graceful_shutdown.cpp
./myapp

在另一个终端发送 SIGTERM

1
kill -SIGTERM <PID>

程序将打印清理信息并退出。

方法3:使用 systemd 管理服务优雅退出

若进程作为 systemd 服务运行,可通过 systemd 配置优雅退出。

示例服务文件/etc/systemd/system/myapp.service):

1
2
3
4
5
6
7
8
9
10
11
12
13
[Unit]
Description=My Application
After=network.target

[Service]
ExecStart=/path/to/myapp
Restart=always
KillMode=process
KillSignal=SIGTERM
TimeoutStopSec=10

[Install]
WantedBy=multi-user.target
  • KillSignal=SIGTERM:发送 SIGTERM 信号请求优雅退出。
  • TimeoutStopSec=10:等待10秒后若未退出,强制终止。

控制服务

1
2
3
4
5
6
# 启动服务
sudo systemctl start myapp
# 停止服务(发送SIGTERM)
sudo systemctl stop myapp
# 查看服务状态
sudo systemctl status myapp

3. 注意事项

  • 查看进程信息
    • 使用 pstop 快速查看,/proc 适合脚本化处理。
    • 定期监控避免遗漏(如 watch ps aux)。
  • 优雅退出
    • 优先使用 SIGTERM,避免 SIGKILL 导致数据丢失或资源泄漏。
    • 程序设计时需处理信号,确保释放文件句柄、网络连接等资源。
    • 对于复杂应用,考虑超时机制(如 TimeoutStopSec)。
  • 测试信号处理
    • 在开发时,测试程序对 SIGTERMSIGHUP 的响应,确保清理逻辑正确。

4. 综合示例

查看进程并优雅终止:

1
2
3
4
5
6
7
# 查找myapp进程
ps aux | grep myapp
# 输出:alice 1234 ... myapp
# 发送SIGTERM
kill -SIGTERM 1234
# 验证进程已退出
ps -p 1234

若使用C++程序,结合上述代码,进程会捕获信号并安全退出。

总结

  • 查看进程:使用 pstophtop/proc 获取进程信息。
  • 优雅退出:通过 SIGTERM 信号或 systemd 配置触发,程序需实现信号处理逻辑。
  • 编程实现:捕获信号,清理资源后退出,确保数据完整性和资源释放。

如需更具体场景或代码示例,请提供进一步细节!