如何为systemd服务生成PID文件,或为动态PID的systemd服务配置CPU亲和性
嘿,我来帮你搞定这个问题!其实你完全不用折腾PID文件——systemd本身就支持直接给服务配置CPU亲和性,比用脚本绕一圈靠谱多了。不过如果你确实需要生成PID文件来做其他操作,我也会告诉你怎么做~
方法一:直接在systemd服务文件中配置CPU亲和性(推荐)
systemd的[Service]段自带了CPUAffinity参数,能直接指定服务进程绑定的CPU核心。不管服务重启多少次、PID怎么变,systemd都会自动帮你把进程绑定到指定核心上,根本不用管动态PID的问题。
修改你的服务文件如下:
[Unit] Description=public 1 run After=network.target [Service] User=steam Group=steam Type=forking ExecStart=/usr/local/bin/server @public1 start Restart=always RestartSec=5 # 配置CPU亲和性,示例:绑定到核心0和1(核心编号从0开始,按需修改) CPUAffinity=0 1 [Install] WantedBy=multi-user.target
举个例子:如果你想把服务绑定到第2、3个物理核心,就写CPUAffinity=1 2(注意是0-based编号)。修改完后,重新加载systemd配置并重启服务:
sudo systemctl daemon-reload sudo systemctl restart public1.service
这样以后每次服务启动或重启,都会自动应用CPU亲和性设置,省心又可靠。
方法二:让systemd生成PID文件,供脚本使用
如果你确实需要PID文件来执行后续操作(比如自定义脚本设置亲和性),可以让systemd帮你生成并管理PID文件。在服务的[Service]段添加PIDFile参数,指定PID文件的存储路径:
修改后的服务文件:
[Unit] Description=public 1 run After=network.target [Service] User=steam Group=steam Type=forking # 指定PID文件路径,要确保steam用户有该路径的读写权限 PIDFile=/run/public1.pid ExecStart=/usr/local/bin/server @public1 start Restart=always RestartSec=5 [Install] WantedBy=multi-user.target
注意:因为你的服务类型是forking,要求启动命令能将主进程的PID写入到指定的PIDFile路径中。如果/usr/local/bin/server本身不支持写入PID文件,你可以用start-stop-daemon来辅助启动并生成PID文件,修改ExecStart如下:
ExecStart=/usr/sbin/start-stop-daemon --start --pidfile /run/public1.pid --exec /usr/local/bin/server -- @public1 start
这样start-stop-daemon会自动帮你管理PID文件的创建和更新。
之后你就可以在自定义脚本中读取这个PID文件,用taskset设置CPU亲和性了,示例脚本:
#!/bin/bash # 读取PID文件中的进程ID PID=$(cat /run/public1.pid) # 绑定到核心0和1(按需修改) taskset -cp 0,1 $PID
为了让脚本在服务启动后自动执行,你可以把脚本路径加到服务的ExecStartPost参数中:
[Service] # ...其他已有参数... ExecStartPost=/path/to/your/affinity-setup.sh
这样每次服务启动完成后,systemd都会自动调用这个脚本设置CPU亲和性。
备注:内容来源于stack exchange,提问作者lostsoul6




