Qt下使用fork创建进程并使用socket通信

栏目: C++ · 发布时间: 4年前

把最近工作总结下。

之前在嵌入 python 解释器的过程中,我们没有处理这样一种情况:当 Python 解释器正在执行一个阻塞操作 ( 比如 socket server 在监听一个客户端连入 ) ,这时我们需要终止解释器的运行,该如何操作呢?

在Qt线程中不容易实现该功能,如果在 socket 监听时终止 python 解释器,那么再次运行时端口就会显示被占用,因为资源没有清理。为了解决这种情况,我们让解释器运行在一个进程中。这样在需要停止时,我们可以发送 kill 信号终止进程。

老规矩,接下来上码:

#include "mainwindow.h"

#include "ui_mainwindow.h"

#include

#include

#include

#include

#include    //close head file

#include

#include

#include

#include

int childProcessId = -1;

int client_sockfd;

void sigint(int);

void sigint(int signal)

{

if(SIGINT == signal)

{

qDebug() << "My DADDY has Killed me!!!";

exit(0);

}

}

MainWindow::MainWindow(QWidget *parent) :

QMainWindow(parent),

ui(new Ui::MainWindow)

{

ui->setupUi(this);

//tcp server

processServer = new QTcpServer();

connect(processServer, SIGNAL(newConnection()),

this, SLOT(slot_recvClientConnect()));

if(!processServer->listen(QHostAddress::Any, 8866))

{

// 监听本地主机的 88 66 端口,如果出错就输出错误信息,并关闭

qDebug() <<"error message"<errorString();

processServer->close();

}

///////////////client

struct sockaddr_in remote_addr; // 服务器端网络地址结构体

memset(&remote_addr,0,sizeof(remote_addr)); // 数据初始化 -- 清零

remote_addr.sin_family=AF_INET; // 设置为 IP 通信

remote_addr.sin_addr.s_addr=inet_addr("127.0.0.1");// 服务器 IP 地址

remote_addr.sin_port=htons(8866); // 服务器端口号

/* 创建客户端套接字 --IPv4 协议,面向连接通信, TCP 协议 */

if((client_sockfd=socket(PF_INET,SOCK_STREAM,0))<0)

{

perror("socket");

return;

}

/* 将套接字绑定到服务器的网络地址上 */

if(::connect(client_sockfd,(struct sockaddr *)&remote_addr,sizeof(struct sockaddr))<0)

{

perror("connect");

return;

}

}

MainWindow::~MainWindow()

{

processServer->close();

delete ui;

delete processServer;

}

void MainWindow::slot_recvClientConnect()

{

qDebug() << "accept connect";

clientConnect = processServer->nextPendingConnection();

connect(clientConnect, SIGNAL(readyRead()),

this, SLOT(slot_readClientData()));

}

void MainWindow::slot_readClientData()

{

QString str;

str = clientConnect->readAll();

clientConnect->write("hello");

qDebug() << "client data>>:" << str  ;

}

void MainWindow::on_pbn_start_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, sigint);

qDebug() << "this is client proccess!";

char buf1[] = "socket client";

while(1)

{

send(client_sockfd,buf1,strlen(buf1),0);

QThread::sleep(3);

}

}

else                  // parent process

{

childProcessId = pid;

qDebug() << "child process pid is " << childProcessId;

}

}

void MainWindow::on_pbn_stop_clicked()

{

if(-1 != childProcessId)

{

pid_t pidClear;

kill(childProcessId, SIGINT);

QThread::usleep(500);

do{

pidClear = waitpid(childProcessId,NULL,WNOHANG);

if(-1 == pidClear)

{

qDebug() << "clear  error!!!";

}

if(childProcessId == pidClear)

{

qDebug() << "clear   success!!!";

}

QThread::usleep(500);

}while(0 == pidClear);

childProcessId = -1;

}

}

程序环境是ubuntu + Qt。

简单介绍下程序的主体构成:构造函数中使用c创建客户端,使用 Qt 的类创建服务器。

界面点击 start 按钮时,使用 fork 创建子进程,在进程中客户端向服务器发送数据。点击 stop 按钮时,父进程向子进程发出 kill 信号,由于子进程注册了中断信号,所以会执行信号函数中的操作。之后父进程使用  waitpid(childProcessId,NULL,WNOHANG) 等待清理子进程,之后进程资源被释放。如果 python 解释器运行在进程中,那么 python 解释器也会被中断,资源被清理故而不会被占用。 Python 重定向信息输出也可通过 socket 发送出来。

程序运行效果:

Qt下使用fork创建进程并使用socket通信

在子进程被中断前,先进入信号函数。之后由父进程清理子进程资源。

如果大家觉得还阔以,欢迎大家后台留言交流。

Qt下使用fork创建进程并使用socket通信


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

编程珠玑

编程珠玑

Jon Bentley / 黄倩、钱丽艳 / 人民邮电出版社 / 2008-10 / 39.00元

本书是计算机科学方面的经典名著。书的内容围绕程序设计人员面对的一系列实际问题展开。作者Jon Bentley 以其独有的洞察力和创造力,引导读者理解这些问题并学会解决方法,而这些正是程序员实际编程生涯中至关重要的。本书的特色是通过一些精心设计的有趣而又颇具指导意义的程序,对实用程序设计技巧及基本设计原则进行了透彻而睿智的描述,为复杂的编程问题提供了清晰而完备的解决思路。本书对各个层次的程序员都具有......一起来看看 《编程珠玑》 这本书的介绍吧!

JS 压缩/解压工具
JS 压缩/解压工具

在线压缩/解压 JS 代码

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具