Linux下CPP创建子进程并获取PID后杀掉进程

用到的系统调用:

pid_t fork(void);
int execl(const char * path, const char * arg, ...);
int kill(pid_t pid, int sig);

fork 1创建一个子进程,一般情况子进程的PID和父进程的PID相差1,所在头文件#include <unistd.h>
这个函数的返回值很重要,在父进程中返回子进程的PID,在子进程中返回0,大多都是以这样的方式来判断是否是子进程和父进程。
重要的事情:
如果使用GDB时,断点只会在父进程中生效
pid_t 的类型,从下面代码可以看出来大部分情况应该pid_t类型为int, 就算不一样也应该为长整形等可以隐式转换的类型,大部分情况也不会损失精度。可以直接用int保存返回值。

#define	__S32_TYPE		int
# define __STD_TYPE		typedef
#define __PID_T_TYPE		__S32_TYPE
__STD_TYPE __PID_T_TYPE __pid_t;	/* Type of process identifications.  */
typedef __pid_t pid_t;

execl2是执行文件函数,所在头文件#include <unistd.h>
网上大多数的参数说明都是说:第一个参数是Executable Path,后面跟着若干个入参。
实际情况:
参数一 : Executable Path + Executable File Name。
参数二 : Executable的第一个入参,也就是 agrs[0],一般第一个入参就是可执行文件名。
参数三~N-1: 多个入参。
参数N : 需要最后一个入参为空标识结束位置,C语言用NULL,C++ 用nullptr。
重要的事情:
第一个入参即为进程名字,如用ps aux |grep <executable name> 查看进程时,并非是execl的第一个参数,第一个参数只表示可执行文件的路径和名字,第一个入参才是进程名。
该系统调用是用新的可执行程序进程替换当前进程,如果失败会返回到调用进程,成功则调用进程销毁,新的执行线程执行。

kill3发送一个信号到一个程序,因为这里是要结束进程,所以这里就使用SIGKILL发生让程序结束的信号到操作系统。
参数一 : PID
参数二 : Linux Signal

简单的测试代码:

#include <iostream>
#include <sys/types.h>
#include <unistd.h>
#include <vector>
#include <thread>
#include <chrono>
#include "common.h"

#include<signal.h>

//父进程

enum class ProcessType{
    kMain = 0,
    kSubprocess = 1
};


void SwitchProcess(ProcessType type, tint32 pid)
{
    if (type == ProcessType::kMain)
    {
        for (int i = 0; i < 5; i++)
        {
            railog("This is Main %d", pid);
            std::this_thread::sleep_for(std::chrono::seconds(2));
        }
    }
    else if(type == ProcessType::kSubprocess)
    {
        execl("subprocess","subprocess","2","testtest",nullptr);
    }
}

int main()                        
{
    pid_t id = fork();
    if(id == 0)
    {
        SwitchProcess(ProcessType::kSubprocess,id);
    }else
    {
        SwitchProcess(ProcessType::kMain,id);
    }
    tint32 ret = kill(id, SIGKILL);
    railog("kill subprocess %d, result :%d",id,ret);

    for (int i = 0; i < 5; i++)
    {
        railog("I am Main.");
        std::this_thread::sleep_for(std::chrono::seconds(2));
    }
    return 0;
}

//子进程
#include <thread>
#include <chrono>
#include "common.h"


int main(tint32 n, tint8** args)
{
    while (1)
    {   
        railog("This is subprocess,receive %d agrs.",n);
        for(int i = 0; i < n; i++)
        {
            railog("agre[%d] :%s",i, args[i]);
        }
        std::this_thread::sleep_for(std::chrono::seconds(1));
    }
    return 0;
}

//CMakeFile
cmake_minimum_required( VERSION VERSION 3.16 )
project(test-create-subprocess)

set (CMAKE_CXX_STANDARD 17)

add_definitions(-g -Wall)
add_executable( testfork
	testfork.cpp
    )
add_executable( subprocess
	subprocess.cpp
    )

  1. fork(2) - Linux man page . ↩︎

  2. execl(3) - Linux man page. ↩︎

  3. kill(2) - Linux man page. ↩︎

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值