如何让Qt的QProcess与嵌入式LINUX上的signal_handler很好地协同工作

时间:2018-04-03 05:38:57

标签: qt thread-safety signals embedded-linux

您好,我在尝试为candump运行QProcess时遇到嵌入式Linux设备的问题。

正在发生的事情是,当我运行QProcess时,我的用于通信端口的signal_handler被多次触发。

发起信号:

...
...
/* open the device to be non-blocking (read will return immediatly) */
UString portName = PortName(portNo);
int fd = open(portName, O_RDWR | O_NOCTTY);
if(fd < 0) {
  hCom = 0;
  perror(portName);
  return(false);
}
hCom = fd;

/* install the signal handler before making the device asynchronous */
saio.sa_handler = UCommManager::signal_handler_IO;
UUtility::MemClear(&saio.sa_mask, sizeof(saio.sa_mask));
saio.sa_flags = 0;
saio.sa_restorer = NULL;
sigaction(SIGIO, &saio, &oldSigSettings);
...
...

和QProcess:

// Runs system candump to record all CANBUS messages into connected USB
QProcess *CANLogger = new QProcess();
QStringList arg;
arg << "-l" << "can0";
CANLogger->setWorkingDirectory("/disk/usbsda1/");
CANLogger->start("candump", arg);

信号处理程序:

signal_handler_IO(int status)
{
  static bool tempLock = false;
  if(tempLock){
    qDebug() << "1. Blocked";
    return;
  }
  tempLock = true;

  for(ubyte no = 0; no < UComm_Manager.Count(); no++) {
    UComm *dev = UComm_Manager[no].dev;
    if(!dev || !dev->IsOpen()) continue;
    dev->signal_handler_IO(status);
  }
  tempLock = false;
}

没有运行QProcess&#34;阻止&#34;永远不会打印,但是当它正在运行时#34;被阻止&#34;多次打印。

如果我没有tempLock,那么我在dev-&gt; signal_handler_IO(状态)中读取的字符串就会出现故障。

接收字符串,例如&#39; abcdefghijklmnopqrstuvwxyz&#39;会给我一些看起来像

的线条

bacdefghijklmnopqrstuvwxyz

lmnoabcdefghijkpqrstuvwxyz

等。

一切都在那里,但是没有秩序。

我试过的是用以下方法禁用和启用信号中断:

bool UCommManager::BlockSig(sigset_t *orig_mask)
{
  sigset_t mask;
  sigemptyset (&mask);
  sigaddset (&mask, SIGIO);
  if (sigprocmask(SIG_BLOCK, &mask, orig_mask) < 0)   // set blocked and saved the old mask to orig_mask
  {
    return false;
  }
  return true;
}

bool UCommManager::UnblockSig(sigset_t *orig_mask)
{
  if (sigprocmask(SIG_SETMASK, orig_mask, NULL) < 0)
  {
    return false;
  }
  return true;
}

但他们没有解决问题。

我需要注意一些线程问题吗?

修改 因为我们正在打击&#34;阻止&#34;多次,这意味着我们被打断了?我应该可以吗?我原本以为中断会根据某种优先级一个接一个地调用。

谢谢。

1 个答案:

答案 0 :(得分:0)

为什么要使用信号?由于它们的异步性质,信号很成问题。信号处理程序可以在最不方便的时候中断您的程序。只有POSIX接口的某个子集才能在信号处理程序中安全使用。

由于您已经在使用Qt,您是否看过QtSerialPort模块? 如果这不是一个选项,你可以使用你使用QtSocketNotifier打开open()调用的FD(忽略名称,它不仅仅是关于套接字)。