您好,我在尝试为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;多次,这意味着我们被打断了?我应该可以吗?我原本以为中断会根据某种优先级一个接一个地调用。
谢谢。
答案 0 :(得分:0)
为什么要使用信号?由于它们的异步性质,信号很成问题。信号处理程序可以在最不方便的时候中断您的程序。只有POSIX接口的某个子集才能在信号处理程序中安全使用。
由于您已经在使用Qt,您是否看过QtSerialPort模块? 如果这不是一个选项,你可以使用你使用QtSocketNotifier打开open()调用的FD(忽略名称,它不仅仅是关于套接字)。