Я пишу многопоточную программу для цели Linux, где один поток должен запускаться только при поступлении сигнала SIGIO из UART. Я проверил код без потоков и только обработчик сигнала, который работает нормально, но когда я делаю это поток, что-то идет не так.
Основное создает два потока: GNSSThread и TestThread.
TestThread - это просто время (1), которое печатает предложение раз в секунду.
Я пытался играть с другими сигналами, и я могу успешно заставить код исходить из sigwaitinfo () с помощью ввода с клавиатуры ^ C. Я думаю, что это может быть в том, как дескриптор файла UART настроен?
Надеюсь, кто-нибудь может помочь.
Код ниже.
main.c
int main(int argc, char **argv) {
cout << endl << "Process "<< argv[0] << " started with PID: " << getpid() << endl << endl;
InitConfig();
InitThreads();
return 0;
}
ThreadFn.cpp
sigset_t SigSet;
void InitThreads() {
pthread_t GNSSThreadID, TestThreadID;
//Configuring serial port to send SIGIO signal when I/O data ready to this process
fcntl(Config.GNSSDataLinkLayer->GetFD(), F_SETSIG, SIGIO);
fcntl(Config.GNSSDataLinkLayer->GetFD(), F_SETFL, O_ASYNC);
fcntl(Config.GNSSDataLinkLayer->GetFD(), F_SETOWN, getpid());
//Config thread to receive SIGIO
sigemptyset(&SigSet);
sigaddset(&SigSet, SIGIO);
sigprocmask(SIG_UNBLOCK, &SigSet, NULL);
pthread_create(&GNSSThreadID, NULL, GNSSThreadFn, NULL);
pthread_create(&TestThreadID, NULL, TestThreadFn, NULL);
pthread_join(TestThreadID, NULL);
}
void *GNSSThreadFn(void *param) {
cout << "Configuring GNSS Thread" << endl;
siginfo_t SigInfo;
mutex mtx;
cout << "Entering GNSS Thread while loop" << endl;
while(1){
//Thread suspended until signal arrives
cout << "Before sigwait" << endl;
sigwaitinfo(&WaitSet, &SigInfo);
cout << "After sigwait" << endl;
//checking for correct file descriptor and if signal caused by send or receive
if(SigInfo.si_fd == Config.GNSSDataLinkLayer->GetFD() && SigInfo.si_code == POLL_IN){
cout << "GNSSThreadMaster::ThreadLoop: Serial port read" << endl;
//Locking mutex while reading talker
mtx.lock();
Config.NMEATransportLayer->ReadTalker();
mtx.unlock();
}else if(SigInfo.si_fd == Config.GNSSDataLinkLayer->GetFD() && SigInfo.si_code == POLL_OUT){
tcdrain(Config.GNSSDataLinkLayer->GetFD());
//Magic sleep to make it work
usleep(20000);
}else
cout << "ThreadLoop: Signal error" << endl;
}
return NULL;
}