将SIGINT发送到QProcess

时间:2018-01-02 14:33:20

标签: linux qt qt4 ubuntu-16.04 qprocess

我想将SIGINT发送到使用QProcess启动的程序。

我正在研究ubuntu。

我的流程的源代码如下:

#include <iostream>
#include <csignal>
#include <stdlib.h>
#include <unistd.h>

void int_handle(int sig)
{
   std::cout<<"Received SIGINT\n";
   exit(0);
}

int main()
{
    std::cout<<"Main called\n";
    signal(SIGINT, int_handle);
    while(1)
    {
        std::cout<<"Sleeping.....\n";
        sleep(1);
    }

    return 0;
}

编译了这个程序并生成了可执行的my_prog 我的Qprocess看起来如下所示

QProcess* process= new Qprocess();
QString command = "my_prog";
process->start(command);
process->waitForStarted();

基于某些事件,我尝试以下列方式发送SIGINT

process->kill();
process->close();
process->write("0x03");
process->terminate();
kill(process->pid(), SIGINT);

QString command = kill -9 <PID>;
QByteArray ba = command.toLatin1();
system(ba.data());

即使尝试了所有这些事情,我也无法在程序中收到SIGINT。

请帮助我找到实现此目的的正确方法。

EDIT1:更新了示例程序。        我试图解释这个问题并忽略了示例中的语法错误。        对不起。

提前致谢。

2 个答案:

答案 0 :(得分:1)

除了你的例子中的几个语法错误/拼写错误,这将阻止代码甚至编译,你尝试杀死的程序有两个半问题:

  1. 信号处理程序具有错误的签名,它接收整数参数shown in the manpage。这甚至无法使用g++编译。
  2. main中,没有启动事件循环或类似事件。因此,当您执行二进制文件时,它会注册信号处理程序,并在此之后立即退出,因为signal()是非阻塞的。
  3. 来自signal() manpage
      

    避免使用:改为使用sigaction(2)。

  4. 修改

    第1点和第2点被OP的 EDIT1 淘汰,第3点仍然存在。

答案 1 :(得分:1)

正如Murphy所指出的,QProcess捕获stdout / stderr并通过QIODevice接口使其可用。如果不将子进程输出转发到父进程,则不会看到任何输出。

转发过程通道后,如果要调用信号处理程序,还必须发送正确的信号。 process->kill()发送SIGKILL而不是SIGINT,因此不会调用您的信号处理程序。杀死子进程的大多数示例都发送了错误的信号。

最后,确保您的命令实际上正在启动。我必须指定相对本地路径./my_prog才能使流程成功启动。

以下是一些基于您的不完整示例的代码,对我有用:

#include <QProcess>
#include <QDebug>
#include <unistd.h>
#include <csignal>

int main(int argc, char *argv[])
{
  QProcess *process = new QProcess();

  // Start process from local directory
  QString command = "./my_prog";

  // Forward output of process to parent stdout/stderr
  process->setProcessChannelMode(QProcess::ForwardedChannels);
  process->start(command);

  // Ensure process starts successfully; wait indefinitely
  if(process->waitForStarted(-1))
  {
    qDebug() << "Process started.";

    // Wait a little before sending signal
    sleep(1);

    // Send the correct signal
    kill(process->pid(), SIGINT);

  } else {
    qDebug() << "Failed to start process.";
  }
}