В настоящее время я работаю над встроенным приложением (работающим на linux 4.14), которое реализует два потока (основной и коммуникационный поток), используя потоки POSIX.
Поток связи создает очередь POSIX, которая обрабатывает запросы команды из основного потока (путем вызова mq_send ()). Он также может обрабатывать входящие данные из последовательной линии, которая генерирует сигнал SIGIO.
Вот пример кода
Основной поток:
pthread_t com_thread;
mqd_t cmd_queue;
void main (void)
{
struct mq_attr attr;
init_serial(); // Does serial line init and set a sigaction() with SIGIO that store serial data
// Create queue
attr.mq_flags = 0;
attr.mq_maxmsg = 100;
attr.mq_msgsize = sizeof(struct Dummy);
attr.mq_curmsgs = 0;
cmd_queue = mq_open(QUEUE_NAME, // Queue name
O_RDWR | O_CREAT, // Flags
S_IRWXU|S_IRWXG|S_IRWXO, // Mode
&attr); // Attributes
// Create thread
pthread_create(&com_thread, NULL, com_fw_handler, NULL);
while(1)
{
// Do some stuff ...
// Send command request
mq_send(cmd_queue, (const char*)cmd_request, sizeof(struct Dummy), 0);
}
}
Com Thread:
static void * com_fw_handler (void * ptr)
{
struct Dummy request_from_queue;
sigset_t sig_set;
int ret = 0;
// Allow SIGIO signal
sigemptyset(&sig_set);
sigaddset(&sig_set, SIGIO);
sigprocmask(SIG_UNBLOCK, &sig_set, NULL);
while(1)
{
// Wait for a command request or SIGIO
do
{
ret = mq_receive(cmd_queue, (char*)request_from_queue, sizeof(request_from_queue), NULL);
printf("mq_received() returned %d\n", ret);
if(ret > 0)
{
// Handle command request
}
}while(ret > 0);
// If mq_receive() exited because SIGIO has been raised
if((ret < 0) && (errno == EINTR))
{
// Handle incoming data from serial
}
}
}
Когда я пытаюсь отладить свое приложение с помощью GDB, все работает нормально, mq_received () завершается каждый раз, когда система получает данные из последовательной линии. Вот пример вывода на консоль:
mq_received() returned 64
mq_received() returned -1
mq_received() returned 64
mq_received() returned -1
......
64 - размер структуры Dummy, -1 - возвращаемое значение при поднятии SIGIO.
Если приложение запускается непосредственно система, SIGIO повышена (я вижу отладочную печать на консоли), но кажется, что mq_receive () никогда не завершается. Только вывод на консоль:
mq_received() returned 64
mq_received() returned 64
.......
Сеанс GDB начинается со следующих «опций»:
handle all nostop pass noprint
Я не могу определить, связано ли наблюдаемое мной поведение с обработкой сигнала GDB или проблема гонки / времени или просто проблема разработчика!
Что-то не так в приведенном мною образце кода?
Спасибо!