qt中通过fork创建进程,杀死进程

参考链接:

通过fork创建进程:https://my.oschina.net/u/4582090/blog/4378629
多进程服务:https://www.bilibili.com/read/cv7289333

1.子进程循环处理事件,父进程结束子进程

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private slots:
    void on_start_processBtn_clicked();

    void on_stop_processBtn_clicked();

private:
    Ui::MainWindow *ui;

    int m_childProcessId;
};
#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <QThread>
#include <QDebug>
#include <signal.h>
#include <sys/types.h>
#include <unistd.h>    //close head file
#include <sys/wait.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

void sigalConn(int);
void sigalConn(int signal){
    if(SIGINT == signal){
        qDebug() << "DADDY is Killing me!!!" << getpid();
        _exit(0);
    }
}

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    m_childProcessId = -1;
}

MainWindow::~MainWindow()
{
    delete ui;
}


void MainWindow::on_start_processBtn_clicked()
{
    pid_t pid;
    pid = fork();
    if(pid < 0)
    {
        qDebug() << "creat process faild!";
    }
    else if((pid_t)0 == pid)  //child process,pid is child pid
    {
        signal(SIGINT, sigalConn);
        qDebug() << "this is client proccess!";
        while(1)
        {
            qDebug() << "test send in process-----pid:"<< getpid();
            QThread::sleep(2);
        }
    }
    else                  // parent process
    {
        m_childProcessId = pid;
        qDebug() << "child process pid is " << m_childProcessId<< "---patient pid:" << getpid();

    }
}

void MainWindow::on_stop_processBtn_clicked()
{
    if(-1 != m_childProcessId)
    {
        pid_t pidClear = -1;
        kill(m_childProcessId, SIGINT);
        QThread::usleep(500);
        int ig = 0;
        qDebug() <<  "pid:---" << getpid();
        do{
            pidClear = waitpid(m_childProcessId,NULL,WNOHANG);
            qDebug() << "pidClear:" << pidClear;
            qDebug() << "childProcessId:" << m_childProcessId;
            if(-1 == pidClear)
            {
                qDebug() << "clear  error!!!";
            }
            if(m_childProcessId == pidClear)
            {
                qDebug() << "clear   success!!!";
            }
            QThread::sleep(2);
            ig++;
        }while(0 == pidClear);//0 == pidClear
        m_childProcessId = -1;
    }
}

2.子进程处理事件结束后,通知父进程结束它(通过信号实现进程通讯)

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

#include <QtCore/QObject>
#include <QtCore/QList>
#include <QtCore/QByteArray>

QT_FORWARD_DECLARE_CLASS(QWebSocketServer)
QT_FORWARD_DECLARE_CLASS(QWebSocket)

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
private slots:
    void on_start_processBtn_clicked();

    void on_stop_processBtn_clicked();

private:
    Ui::MainWindow *ui;

    //int m_childProcessId;
};
#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <QThread>
#include <QDebug>
#include <signal.h>
#include <sys/types.h>
#include <unistd.h>    //close head file
#include <sys/wait.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

int m_childProcessId;

void exitProcess(int processId);

void sigalConn(int);
void sigalConn(int signal){
    if(SIGINT == signal){
        qDebug() << "DADDY is Killing me!!!" << getpid();
        _exit(0);
    }
}

void sigalClose(int);
void sigalClose(int signal){
    if(SIGINT == signal){
        qDebug() << "receive child exit sigal--" << getpid();
        exitProcess(m_childProcessId);
    }
}


MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    m_childProcessId = -1;
}

MainWindow::~MainWindow()
{
    delete ui;
}


void MainWindow::on_start_processBtn_clicked()
{
    pid_t pid;
    pid = fork();
    if(pid < 0)
    {
        qDebug() << "creat process faild!";
    }
    else if((pid_t)0 == pid)  //child process,pid is child pid
    {
        signal(SIGINT, sigalConn);
        qDebug() << "this is client proccess!";
        //while(1)
        {
            qDebug() << "test send in process-----pid:"<< getpid();
            QThread::sleep(2);
        }
        qDebug() << "begin exit process -- pid:" << getpid();
        kill(getppid(),SIGINT);
    }
    else                  // parent process
    {
        signal(SIGINT, sigalClose);
        m_childProcessId = pid;
        qDebug() << "child process pid is " << m_childProcessId<< "---patient pid:" << getpid();

    }
}

void MainWindow::on_stop_processBtn_clicked()
{
    exitProcess(m_childProcessId);
}

void exitProcess(int processId)
{
    if(-1 != processId)
    {
        pid_t pidClear = -1;
        kill(processId, SIGINT);
        QThread::usleep(500);
        int ig = 0;
        qDebug() <<  "pid:---" << getpid();
        do{
            pidClear = waitpid(processId,NULL,WNOHANG);
            qDebug() << "pidClear:" << pidClear;
            qDebug() << "childProcessId:" << processId;
            if(-1 == pidClear)
            {
                qDebug() << "clear  error!!!";
            }
            if(processId == pidClear)
            {
                qDebug() << "clear   success!!!";
            }
            QThread::sleep(2);
            ig++;
        }while(0 == pidClear);//0 == pidClear
        processId = -1;
    }
}

3.多进程服务

记得下载C语言技术网(www.freecplus.net)提供的freecplus文件

服务端 server.cpp

#include "../_freecplus.h"

void FathEXIT(int sig);
void ChldEXIT(int sig);

CTcpServer TcpServer;   // 创建服务端对象。

int main(int argc,char *argv[])
{
    // 关闭全部的信号
    for (int ii=0;ii<100;ii++){
     signal(ii,SIG_IGN);
    }
    signal(SIGINT,FathEXIT);
    signal(SIGTERM,FathEXIT);

    if (TcpServer.InitServer(5858)==false) // 初始化TcpServer的通信端口。
    {
        printf("TcpServer.InitServer(5858) failed.\n");
        return -1;
    }

    while (true) {
        // 等待客户端连接。
        if (TcpServer.Accept()==false)
        {
            printf("TcpServer.Accept() failed.\n");
            return -1;
        }
        if(fork() > 0){
            TcpServer.CloseClient();
            continue;
        }
        signal(SIGINT,ChldEXIT);
        signal(SIGTERM,ChldEXIT);
        TcpServer.CloseListen();

        printf("客户端(%s)已连接。\n",TcpServer.GetIP());
        char strbuffer[1024];  // 存放数据的缓冲区。
        while (true)
        {
            memset(strbuffer,0,sizeof(strbuffer));
            if (TcpServer.Read(strbuffer,300)==false) break; // 接收客户端发过来的请求报文。
            printf("接收:%s\n",strbuffer);

            strcat(strbuffer,"ok");      // 在客户端的报文后加上"ok"。
            printf("发送:%s\n",strbuffer);
            if (TcpServer.Write(strbuffer)==false){
                break;     // 向客户端回应报文。
            }
        }
        printf("客户端已断开。\n");    // 程序直接退出,析构函数会释放资源。
        ChldEXIT(0);
    }
}

// 父进程退出时调用的函数

void FathEXIT(int sig){
  if (sig > 0)
  {
    signal(sig,SIG_IGN); signal(SIGINT,SIG_IGN); signal(SIGTERM,SIG_IGN);
    printf("catching the signal(%d).\n",sig);
  }
  kill(0,SIGTERM);
  printf("父进程退出。\n");
  // 编写善后代码(释放资源、提交或回滚事务)
  exit(0);
}

// 子进程退出时调用的函数

void ChldEXIT(int sig){
  if (sig > 0)
  {
    signal(sig,SIG_IGN); signal(SIGINT,SIG_IGN); signal(SIGTERM,SIG_IGN);

  }
  printf("子进程退出。\n");
  // 编写善后代码(释放资源、提交或回滚事务)
  exit(0);
}


客户端 client.cpp
#include "../_freecplus.h"

int main(int argc,char *argv[])
{
  CTcpClient TcpClient;   // 创建客户端的对象。
  
  if (TcpClient.ConnectToServer("192.168.122.128",5858)==false) // 向服务端发起连接请求。
  {
    printf("TcpClient.ConnectToServer(\"172.21.0.3\",5858) failed.\n"); return -1;
  }

  printf("pid=%d\n",getpid());
  char strbuffer[1024];    // 存放数据的缓冲区。

  for (int ii=0;ii<6;ii++)   // 利用循环,与服务端进行5次交互。
  {
    memset(strbuffer,0,sizeof(strbuffer));
    snprintf(strbuffer,50,"这是第%d个超级女生,编号%03d。",ii+1,ii+1);
    printf("发送:%s\n",strbuffer);
    if (TcpClient.Write(strbuffer)==false) break;    // 向服务端发送请求报文。

    memset(strbuffer,0,sizeof(strbuffer));
    if (TcpClient.Read(strbuffer,20)==false) break;  // 接收服务端的回应报文。
    printf("接收:%s\n",strbuffer);

    sleep(2);
  }

  // 程序直接退出,析构函数会释放资源。
}

编译文件:

g++ -g -o serverTest server.cpp _freecplus.cpp
g++ -g -o clientTest client.cpp _freecplus.cpp

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

努力减肥的小胖子5

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值