Linux下如何暂停进程组内所有进程但排除调用进程自身?
解决方法:暂停进程组内其他进程但保留自身运行
刚好之前做并发程序时碰到过一模一样的问题,killpg(0, SIGSTOP)连自己也停确实坑人,给你几个实用的Linux下的解决方案:
方案1:临时移出进程组(适合非组组长的进程)
这个思路很直接——先把自己从目标进程组里挪出去,发完暂停信号再回来:
- 先拿到当前的进程组ID:
pid_t old_pgid = getpgrp(); - 给自己建个临时进程组:
setpgid(0, 0);(这会让你成为新组的组长,自动脱离原组) - 给原来的进程群发暂停信号:
kill(-old_pgid, SIGSTOP);(现在你不在原组里,自然不会被波及) - 完事之后再归队:
setpgid(0, old_pgid);
⚠️ 注意:如果你本身就是原进程组的组长,这个方法行不通——因为进程组组长不能加入其他进程组,这时候得用方案2。
方案2:让子进程代发信号(通用所有场景)
不管你是不是组组长,这个方法都能稳用,核心就是让一个“工具人”子进程来发信号:
- 先fork一个子进程:
pid_t child = fork(); - 子进程里做这几件事:
- 先把自己移出原进程组:
setpgid(0, 0); - 给原进程组发暂停信号:
kill(-getppid(), SIGSTOP);(父进程在原组里,所以-getppid()就是原进程组的ID) - 任务完成直接退出:
exit(0);
- 先把自己移出原进程组:
- 父进程这边只要等子进程干完活就行:
waitpid(child, NULL, 0);
等子进程退出后,原进程组里除了你自己,其他进程都已经被暂停了,完美解决问题。
方案3:遍历/proc筛选进程(适合需要精细控制的场景)
如果不想折腾进程组或者fork,也可以直接读/proc文件系统来找目标进程:
- 先拿到当前进程组ID:
pid_t target_pgid = getpgrp(); - 遍历/proc下的所有数字命名的目录(每个目录对应一个进程的PID)
- 对每个PID,读取
/proc/[pid]/stat文件的第4个字段(这个字段就是进程组ID) - 如果该PID的进程组ID等于
target_pgid,而且PID不等于你自己的PID(getpid()),就给它发SIGSTOP:kill(pid, SIGSTOP);
这个方法的缺点是要遍历文件系统,性能不如前两个,但胜在灵活——比如你想额外排除某个特定进程的话,直接加判断就行。
内容的提问来源于stack exchange,提问作者Micrified
相关产品推荐
相关产品推荐

