首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

用linux系统调用杀死c++中的sh -c及其所有子进程。

在 Linux 系统中,如果你在 C++ 程序中使用 sh -c 启动了一个进程,并且希望杀死该进程及其所有子进程,可以使用以下方法:

  1. 获取进程 ID (PID):首先,你需要获取 sh -c 命令启动的进程的 PID。
  2. 获取子进程:然后,你需要获取该进程的所有子进程。
  3. 杀死进程及其子进程:最后,杀死这些进程。

以下是一个示例代码,展示了如何在 C++ 中实现这一过程:

示例代码

代码语言:javascript
复制
#include <iostream>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <signal.h>
#include <vector>
#include <cstring>
#include <sstream>
#include <fstream>

// 获取给定进程的所有子进程
std::vector<pid_t> getChildProcesses(pid_t pid) {
    std::vector<pid_t> childPids;
    std::ifstream proc("/proc/" + std::to_string(pid) + "/task/" + std::to_string(pid) + "/children");
    if (proc) {
        std::string line;
        std::getline(proc, line);
        std::istringstream iss(line);
        pid_t childPid;
        while (iss >> childPid) {
            childPids.push_back(childPid);
        }
    }
    return childPids;
}

// 递归杀死进程及其所有子进程
void killProcessTree(pid_t pid) {
    std::vector<pid_t> childPids = getChildProcesses(pid);
    for (pid_t childPid : childPids) {
        killProcessTree(childPid);
    }
    kill(pid, SIGKILL);
}

int main() {
    pid_t pid = fork();
    if (pid == 0) {
        // 子进程
        execl("/bin/sh", "sh", "-c", "sleep 100", (char *)NULL);
        // 如果 execl 失败
        std::cerr << "execl failed: " << strerror(errno) << std::endl;
        return 1;
    } else if (pid > 0) {
        // 父进程
        std::cout << "Started process with PID: " << pid << std::endl;
        sleep(5); // 等待一段时间,模拟一些操作

        // 杀死进程及其所有子进程
        killProcessTree(pid);
        std::cout << "Killed process tree with root PID: " << pid << std::endl;

        // 等待子进程结束
        waitpid(pid, NULL, 0);
    } else {
        // fork 失败
        std::cerr << "fork failed: " << strerror(errno) << std::endl;
        return 1;
    }

    return 0;
}

解释

  1. 获取子进程
    • getChildProcesses 函数读取 /proc/[pid]/task/[pid]/children 文件来获取给定进程的所有子进程。
  2. 递归杀死进程树
    • killProcessTree 函数递归地获取并杀死所有子进程,然后杀死自身。
  3. 主程序
    • 使用 fork 创建一个子进程,并使用 execl 执行 sh -c "sleep 100" 命令。
    • 父进程等待一段时间后,调用 killProcessTree 函数来杀死子进程及其所有子进程。

注意事项

  • 权限:确保你的程序有足够的权限来读取 /proc 文件系统和杀死进程。
  • 错误处理:在实际应用中,添加更多的错误处理代码是一个好习惯。
  • 信号处理:在某些情况下,你可能需要处理不同的信号(如 SIGTERM)而不是直接使用 SIGKILL
页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

golang子进程的启动和停止,mac与linux的区别

简单调试后就找到了原因,在系统中启动的子进程,发出终止信号之后居然仍在运行,导致父进程也一直无法退出,尴尬了。...这段代码启动子进程和关闭子进程在mac电脑的原有系统上工作都很正常,但是到了linux,启动子进程仍然没有问题,关闭子进程不成功。...检查了一下在linux的工作过程,发现启动子进程之后,实际上是启动了两个进程,一个进程是/bin/sh,随后sh又启动了一个子进程自身的子进程sleep。...所以有的时候我们是为了省事,也有的时候是顺手移植了别的语言的代码,就使用/bin/sh来启动需要的命令行程序,就如同上面示例代码一样,这样情况下,除了-c参数要单独占用一个字符串,我们原本要启动的字符串程序及其参数...sh启动了另外一个子进程,这种方法就无效了(指在linux无效,mac测试是一样可以用的,关键区别同样是在mac,/bin/sh进程不会保留并等待我们启动的子进程退出,所以退出消息可以正常的发送到正常的子进程

4.7K50

Linux进程管理详细解读

背景 Linux系统为多用户多任务系统 生物软件运行时要能够查看运行状态 实时监控软件运行状态 例如 CPU 内存使用情况等 当运行出现错误时 要能够及时杀死任务 以及任务前后台切换 是否挂起等操作...Linux系统中时刻运行着许多进程,如果能够合理地管理它们,则可以优化系统的性能。在Linux 系统中有 5 种常见的进程状态,分别为运行、中断、不可中断、僵死与停止,其各自含义如下所示。...R(运行):进程正在运行或在运行队列中等待。 S(中断):进程处于休眠中,当某个条件形成后或者接收到信号时,则脱离该状态。 D(不可中断):进程不响应系统异步信号,即便用kill命令也不能将其中断。...Z(僵死):进程已经终止,但进程描述符依然存在, 直到父进程调用wait4()系统函数后将进程释放。 T(停止):进程收到停止信号后停止运行。...nohup sh scripts.sh & 3.2切换为非关起 disown disown命令可以从当前 shell 的作业列表中移除全部作业,也可移除指定的一到多个作业;正在运行的作业也可以移除

96530
  • Linux进程控制——Linux进程程序替换

    本篇主要内容: 替换原理 替换函数 实现简易shell 我们所创建的所有的子进程,执行的代码,都是父进程代码的一部分,如果我们想让子进程执行新的程序,执行全新的代码和访问全新的数据,不在和父进程有瓜葛这就要用到我们的进程替换了...操作系统在调用exec函数时,只要将整个进程的代码和数据用新程序的代码和数据进行替换。...实现简易shell 我们用程序替换是可以用C语言把C++调用起来的 // test.c int main() { printf("pid: %d, exec command begin\n...因为我们要同时编译两个程序,所以我们要对Makefile进行一下调整 我们通过程序替换将C++用C语言调用起来了 那我们除了调用C++还能调用别的嘛?...return 0; } 当然除了我们讲的这两个,其实所有语言都能通过进程程序替换来调用,因为我们用任意语言写的程序都会变成进程,只要是进程就都可以用exec*来替换——系统大于一切 4.

    9910

    Linux 进程后台运行的几种方式(screen)

    Ctrl+z/bg/nohup/setsid/& 在Linux中,如果要让进程在后台运行,一般情况下,我们在命令后面加上&即可,实际上,这样是将命令放入到一个作业队列中了: ..../rsync.sh & # jobs 但是如上方到后台执行的进程,其父进程还是当前终端shell的进程,而一旦父进程退出,则会发送hangup信号给所有子进程,子进程收到hangup以后也会退出。...新建一个名叫docker-d的session,但暂不进入,可用于系统启动脚本里 # screen -ls 列出当前所有session # screen -r docker-d 恢复到zhouxiao这个...另一个关闭窗口的方法是使用C-a k,这个快捷键杀死当前的窗口,同时也将杀死这个窗口中正在运行的进程。 在每个screen session 下,所有命令都以 ctrl+a(C-a) 开始。...C-a w 显示所有窗口列表 C-a k 这个快捷键杀死当前的窗口,同时也将杀死这个窗口中正在运行的进程。

    3.9K00

    Android 进程保活 的两种实现方式

    (或者用360手机卫士进行清理操作), 如果服务的onStartCommand返回START_STICKY, 在进程管理器中会发现过一小会后被杀死的进程的确又会出现在任务管理器中,貌似这是一个可行的办法...-----SIGLE信号 思路 利用am命令,启动主进程的一个service SIGLE信号,通过SIGLE信号来判断程序是否被杀死 在Linux系统下,如果使用sigaction将信号SIGCHLD...Android手机进程查看.png uid Android用户id 号 pid 当前的进程号 ppid 当前进程的父进程号 开始撸码 由于上面讲的内容都是在c++实现的,所以搞个jni工程...,运行中 i = "+i); i++; } }, 0, 3000); } ......省略其他代码 } C++的实现 const char *_user_id...(String.valueOf(Process.myUid())); watcher.connect(); C++的实现:子进程创建socket的服务单,主进程进行连接 int m_child; const

    6.5K20

    你真的了解 pod 的 cpumemory 吗?

    Pod 本身并不是一个单独的进程,但容器运行在该 Pod 中,容器内的进程可以相互通信。 在Linux 中,一个进程的cpu/memory 使用量是由cgroups 控制的。...如果容器超过了这个限制,Linux 内核的 OOM(Out-Of-Memory)管理器可能会杀死该容器中的进程,以释放内存。...cAdvisor 是一个运行在每个节点上的工具,它能自动监控所有容器的 CPU、内存、文件系统和网络使用情况。...cAdvisor 通过读取 Linux 系统中的 cgroups(控制组)来获取资源使用的详细信息。 K8s/OpenShift 通过 cgroups 来限制和隔离容器的资源使用。...这种问题在使用语言如 C 或 C++ 时更为常见。 进程创建的每个线程都有自己的堆栈空间。随着线程数量的增加,堆栈内存的需求也会增大。

    12010

    DevOps: 进程管理工具 supervisor简介

    一、简介 Supervisor是用Python 开发的一个client/server服务,是 Linux /Unix系统下的一个进程管理工具,不支持Windows系统。...用Supervisor管理的进程,当一个进程意外被杀死,supervisort监听到进程死后,会自动将它重新拉起,很方便的做到进程自动恢复的功能,不再需要自己写shell脚本来控制。...二、安装部署配置 1、安装 Supervisort是基于python开发的,需要检测系统是否具有python2.4以上的版本。一般centos7的系统都是基于python2.7以上了。...及其应用程序(即我们要管理的程序)。 首先来看supervisord 的配置文件。...-c /etc/supervisor/supervisord.conf 2、查看日志 脚本执行,并标准输出到对应设置的日志文件中 3、测试终止进程 通过以上操作,可以看到supervisor可以进行进程的管理

    14310

    【Linux探索学习】第十七弹——进程终止:深入解析操作系统中的进程终止机制

    本文将详细讲解操作系统中的进程终止相关知识,包括终止的原因、类型、实现方式、Linux系统中的具体操作,以及其影响和管理策略,并配以表格和代码示例,帮助全面掌握这一主题。 一、什么是进程终止?...代码异常终止 下面我们会对上面的内容做出讲解 四、Linux中的进程终止实现 在Linux操作系统中,进程终止主要通过以下系统调用和信号实现: 4.1 运行完毕且正常终止 4.1.1 使用return...C/C++中其实还定义了一个叫errno的常量来记录错误码 所以我们就可以将errno常量与strerror函数结合使用,用errno来记录进程的错误码,然后传给strerror函数得到错误信息,比如下面的例子...kill指令杀死进程 4.4 子进程资源回收:wait 和 waitpid 进程等待与回收我们会在下一篇详细讲解 当子进程终止后,其状态会保留在系统中,直到父进程回收。...文件描述符:关闭该进程打开的所有文件。 CPU时间:释放进程的时间片。 5.2 僵尸进程 当子进程终止但父进程未调用wait或waitpid回收其状态时,子进程会变成僵尸进程。 如何避免僵尸进程?

    20810

    强大的strace命令用法详解

    strace怎么用? 既然strace是用来跟踪用户空间进程的系统调用和信号的,在进入strace使用的主题之前,我们的先理解什么是系统调用。...-f 跟踪目标进程,以及目标进程创建的所有子进程 -e 控制要跟踪的事件和跟踪行为,比如指定要跟踪的系统调用名称 -o 把strace的输出单独写到指定的文件 -s 当系统调用的某个参数是字符串时...实际上,通过分析,我们发现机器上别的服务有个监控脚本,它监控一个也叫做run.sh的进程,当发现run.sh进程数大于2时,就会把它杀死重启。结果导致我们这个run.sh脚本被误杀。...3、 性能分析 假如有个需求,统计Linux 4.5.4 版本内核中的代码行数(包含汇编和C代码)。这里提供两个Shell脚本实现: poor_script.sh: !...我们通过strace的-c选项来分别统计两种版本的系统调用情况和其所花的时间(使用-f同时统计子进程的情况) 从两个输出可以看出,good_script.sh 只需要2秒就可以得到结果:19613114

    2K31

    清理linux中的僵尸进程

    什么是僵尸进程 Linux 中的僵尸进程有时也称为失效或死进程。它们是已完成执行的进程,但它们的条目并未从进程表中删除。 进程状态 Linux 维护着所有正在运行的进程及其状态的进程表。...停止(T):我们可以通过发送适当的信号来停止Linux 进程。 僵尸(Z):当一个进程完成它的任务时,它会释放它正在使用的系统资源并清理它的内存。...然后父进程执行wait()系统调用来读取子进程的状态并获取退出代码。这也会从进程表中清除子进程的条目,此进程结束。 如果父进程没有被编程为在创建子进程时执行wait()系统调用,则不会发生清理。...因此,它会通知父进程触发wait()系统调用,这将从进程表中清除已失效的子进程。...杀死父进程 如果上面无法清除已失效的进程,我们应该考虑杀死其父进程: kill -9 103 103是已失效进程的父 ID 但是,杀死父进程会影响其所有子进程。

    3.5K20

    linux进程管理:进程,程序,线程 & 9个进程管理工具 & 作业控制

    程序 程序:一组指令以及参数集合,按照相应的逻辑控制计算机完成特性任务 (一个程序可以产生多个进程) linux程序:系统,用户,固件 (包含指令,参数) 程序 ------》系统调用-------》缓存...如果这时子进程还有子进程还存在,就变成僵尸进程 父子进程的关系 子进程是由一个进程所产生的进程,产生这个子进程的进程称为父进程 在linux系统中,使用系统调用fork创建进程。...检测各种服务(service)的启动状态 该命令主要用于管理Linux操作系统中各种服务,它是一个脚本命令,会调用/etc/init.d/下面的各种服务启动程序。...中的kill命令用来终止指定的进程的运行,是linux下进程管理的常用命令。...倒转排序顺序 s 选择某进程,按s:用strace追踪进程的系统调用 F1:显示帮助信息 ?

    3.5K10

    网络安全溯源指南

    $ kill -9 `lsof -t -u user` # 杀死指定用户运行的所有进程$ lsof -u user -i @ip       # 显示用户user连接到指定IP所做的一切2.2线程查看进程执行时的系统调用和所接收的信号,可跟踪用户进程与 Linux内核之间的交互>$ strace -p `pidof AliYunDun`  # 依据pid跟踪进程正在进行的系统调用$ strace...#对当前正在跟踪的进程创建的任何子进程进行跟踪$ strace -e open ls testdir   #使用-e标志跟上系统调用的名称$ strace -e write,getdents ls testdir... #查看多个系统调用$ strace -t ls testdir/    #查看所有的系统调用的时间戳$ strace -r ls testdir/    #显示执行每个系统调用所花费的时间进程的栈跟踪...-ltpe | more   # 查看监听中的网络连接并显示进程ID、进程所有者用户名$ sudo netstat -antp | grep "ESTABLISHED''  # 查看正在通信中的连接信息

    58130

    正确的使用python调用shell的姿势

    python天生的优势,用它来开发一些devops的自动化作业是非常方便的,当然在linux上,一般我们用shell就能写一些简单的自动化脚本,但如果自动化作业复杂的话,使用shell脚本就很难搞定了,...终端上执行 python -c "import os; myCmd = 'ls '; os.system(myCmd)" 这种方式是最原始的方式,能直接调用shell命令,但是没法获取输出结果,所以仅仅适合一些简单的场景...,后面就又有了最强大的subprocess模块,subprocess模块的出现是用来替代OS模块中的system()和popen()方法的,官方推荐的是只用subprocess模块来执行系统命令,subprocess...terminate(): 停止子进程,也就是发送SIGTERM信号到子进程。kill(): 杀死子进程。发送 SIGKILL 信号到子进程。...脚本:test.sh for i in `seq 1 4`dosleep 2echo ${i}done 这个脚本每输出一个数字都会sleep 2秒,用ptyhon调用这个脚本,能够实时在终端上看到和shell

    7.5K20

    系统进程管理查看

    ,查看系统中所有进程,杀死进程. fuser 命令 描述:用于报告进程使用的文件和网络套接字,还可以用指定的文件或者文件系统显示进程进程号,默认情况下每一个文件名后会跟着一个字母来表示类型,那些本地进程使用..... -4 IPv4 -6 IPv6 -a:显示命令行中指定的所有文件; -k:杀死访问指定文件的所有进程; -i:杀死进程前需要用户进行确认; -l:列出所有已知信号名; -m:指定一个被加载的文件系统或一个被加载的块设备...home #注意使用啊,貌似会关闭终端 fuser -km /www #快速停止占用(根据挂载的目录) ps 命令 描述:在Linux系统中PS(Process Status的缩写)命令常常用来用来列出系统中当前运行的进程...命令 - 进程杀死 描述:用来在Linux杀死执行中的程序或工作进程的命令, kill可将指定的信息送至程序,预设的信息为SIGTERM(15),可将指定程序终止,若仍无法终止该程序,可使用SIGKILL...0x03 进程切换 unshare 命令 描述:/usr/bin/unshare是Linux自带的命令实际通过unshare()系统调用实现的,调用的主要作用就是不启动一个新进程就可以起到隔离效果,简单的说就是跳出原先的

    89720

    运维利器之万能的 strace

    strace 怎么用? 既然 strace 是用来跟踪用户空间进程的系统调用和信号的,在进入 strace 使用的主题之前,我们的先理解什么是系统调用。...-f 跟踪目标进程,以及目标进程创建的所有子进程 -e 控制要跟踪的事件和跟踪行为,比如指定要跟踪的系统调用名称 -o 把strace的输出单独写到指定的文件 -s 当系统调用的某个参数是字符串时,最多输出指定长度的内容...实际上,通过分析,我们发现机器上别的服务有个监控脚本,它监控一个也叫做 run.sh 的进程,当发现 run.sh 进程数大于2时,就会把它杀死重启。结果导致我们这个 run.sh 脚本被误杀。...3.性能分析 假如有个需求,统计Linux 4.5.4 版本内核中的代码行数(包含汇编和C代码)。这里提供两个Shell脚本实现: poor_script.sh: #!...我们通过strace的-c选项来分别统计两种版本的系统调用情况和其所花的时间(使用-f同时统计子进程的情况)。

    2.5K10

    NDK--双进程守护之利用线程轮询实现APP保活

    (或者用360手机卫士进行清理操作), 如果服务的onStartCommand返回START_STICKY, 在进程管理器中会发现过一小会后被杀死的进程的确又会出现在任务管理器中,貌似这是一个可行的办法...导致大部分双进程不能真正开启起来 手机厂商针对于Android系统源码容易修改,但是针对于Linux内核却无能为力 终极解决方案: 使用Jni,在 c端 fork进程,检测Service是否存活,若Service.../wucz122140729/article/details/105112504 今天利用守护进程开启线程,不断轮询自身的父进程pid是否为1(父进程死亡后,子进程会被系统进程管理,即子进程的父进程pid...为1),来实现进程被杀死后,守护进程重新拉起进程 首先在java中启动一个服务,并调用native方法开启守护进程 package com.aruba.processdaemonapplication;...+ i); i++; } }, 0, 1000 * 3); } } 在c+

    1.7K20

    Kubernetes 运维遇到的问题记录(4)

    ,往往是因为采用了 /bin/sh -c my-app 这样的启动入口。...或者使用 /entrypoint.sh 这样的脚本文件作为入口,在脚本中再启动业务进程。容器主进程是 shell,业务进程是在 shell 中启动的,成为了 shell 进程的子进程。...这时候只能等到 K8S 优雅停止超时时间 (terminationGracePeriodSeconds,默认 30s),发送 SIGKILL 强制杀死 shell 及其子进程。...init 系统 (或 supervisor) 来管理所有子进程,只不过它的逻辑很简陋,仅仅简单的透传指定信号给子进程,其实社区有更完善的方案,dumb-init 和 tini 都可以作为 init 进程...,作为主进程 (PID 1) 在容器中启动,然后它再运行 shell 来执行我们指定的脚本 (shell 作为子进程),shell 中启动的业务进程也成为它的子进程,当它收到信号时会将其传递给所有的子进程

    96720

    Linux 学习必杀技:从菜鸟到高手的蜕变密码

    2.3 编写第一个 C++ 程序: 在 Linux 系统中,我们可以使用任何文本编辑器(如 Vim、Emacs 或 VS Code)来编写 C++ 代码: 将上述代码保存为 hello.cpp,然后使用...四、Linux 进程管理: 4.1 进程的概念: 在 Linux 系统中,进程是程序在操作系统中的一次执行实例。每个进程都有自己独立的内存空间、程序计数器、寄存器等。.../myprogram & 4.3 使用 C++ 创建和管理进程: 在 C++ 中,我们可以使用 fork() 和 exec() 系列函数来创建和管理进程。...6.2 线程编程: 在 Linux 系统中,线程是轻量级的进程,多个线程可以共享同一个进程的资源。在 C++ 中,我们可以使用  头文件来进行线程编程。.../list_files.sh 9.2 使用 C++ 调用 Shell 脚本: 在 C++ 中,可以使用 system() 函数来调用 Shell 脚本。

    11400
    领券