Russian Qt Forum

Qt => Многопоточное программирование, процессы => Тема начата: kuzmich от Декабрь 02, 2010, 14:28



Название: Доставка данных из потока Canfestival в главный поток GUI
Отправлено: kuzmich от Декабрь 02, 2010, 14:28
Есть Qt приложение для отображения данных, полученных по CAN-интерфейсу. И есть С-библиотека, реализующая обмен. В приложении создаю QThread, который запускает поток run() в котором для работы с библиотекой устанавливаются callback-и на прием пакетов. Проблемы: 1. для оповещения главного потока о приходе новых данных не могу использовать сигналы, т.к. в callback-ах не катит emit signal. А копировать в них новые данные в данные класса, а потом как-то отслеживать в потоке флаг, что они есть, вроде коряво. 2. Метод класса callback-ом сделать тоже нельзя. Прототип void (*)(void).
Что-то не пойму, как это сделать без корявости тотальной глобальности переменных-данных :) ???


Название: Re: Доставка данных из потока Canfestival в главный поток GUI
Отправлено: sadhu от Декабрь 02, 2010, 22:55
Похоже в твоём случае без извращений никак : http://forum.sources.ru/index.php?showtopic=270220 (http://forum.sources.ru/index.php?showtopic=270220), бьются над этой задачей лучшие умы человечества  ;D
Хотя корявости глобальных переменных можно избежать корявостью статических переменных или членов класса.
Почти уверен что не прокатит но, возможно поможет вызов в run() метода exec(), а в callback'e  статической функции
currentThread().


Название: Re: Доставка данных из потока Canfestival в главный поток GUI
Отправлено: sadhu от Декабрь 02, 2010, 23:49
Похоже последнее предлагаемое мной решение попало в цель по крайней мере в примере во вложении оно работает.


Название: Re: Доставка данных из потока Canfestival в главный поток GUI
Отправлено: kuzmich от Декабрь 03, 2010, 09:10
Либо я чего-то не понял в примере, либо у меня немного другая ситуация :)
Суть в том, что вспомогательный инструмент библиотеки генерирует с, h - пару файлов, в которых объявлена структура. Часть которой заполняется уже мною моими пользовательскими callback-ами. Сигнатура определена и главное, вызов этих callback-ов выполняется где-то её самой. Единственное событие, которое мне нужно(оно сигнализирует, что произошел прием) это этот дурацкий callback. В примере же нужно вызывать библиотечную функцию самому.
До этого у меня был сделан проект, где было два процесса. Один - Qt, второй программулька работы с этой библиотекой. Обмен происходил посредством UnixSocket-ов. Просто захотел уйти от переключения процессов к одному многопоточному приложению. Т.к. каждые 100мс примерно 10 раз надо было отсылать порцию данных. Сейчас данных может быть больше.


Название: Re: Доставка данных из потока Canfestival в главный поток GUI
Отправлено: kuzmich от Декабрь 03, 2010, 09:34
возможно поможет вызов в run() метода exec(), а в callback'e  статической функции
currentThread().
Можно поподробней? Разве получится послать сигнал используя возвращаемый QThread?


Название: Re: Доставка данных из потока Canfestival в главный поток GUI
Отправлено: Waryable от Декабрь 03, 2010, 10:45
Не знаю правильно ли я тебя понял... Но может попробовать поиграться с переопределением <мой_widget_класс>::winEvent(MSG *message, long *result). Таким способом я решал задачу постирования событий м/у моим приложением и библиотекой. Если у твоей библиотеки есть подробная спецификация погляди, возможно она шлет postmessage по своим событиям. Если да, то можно решать таким способом.


Название: Re: Доставка данных из потока Canfestival в главный поток GUI
Отправлено: kuzmich от Декабрь 03, 2010, 11:09
Не знаю правильно ли я тебя понял... Но может попробовать поиграться с переопределением <мой_widget_класс>::winEvent(MSG *message, long *result). Таким способом я решал задачу постирования событий м/у моим приложением и библиотекой. Если у твоей библиотеки есть подробная спецификация погляди, возможно она шлет postmessage по своим событиям. Если да, то можно решать таким способом.
Это вроде не подойдет. У меня Linux  и QtEmbedded.
Кстати, вроде нашел, что может разрешить проблему callback-ов в Qt. Это передавать свою статическую функцию, а в ней записывать принятые данные в какой-нибудь qt specific объект, который сгенерирует сигнал. Наткнулся в http://doc.crossplatform.ru/qt/4.5.0/unix-signals.html
Сейчас буду пробовать...


Название: Re: Доставка данных из потока Canfestival в главный поток GUI
Отправлено: Авварон от Декабрь 03, 2010, 11:22
Хоспаде, ведь и правда
void f()
{
    MyThread* t = qobject_cast<MyThread*>(getCurrentThread());
    t->emitMySignal();
}


Название: Re: Доставка данных из потока Canfestival в главный поток GUI
Отправлено: sadhu от Декабрь 03, 2010, 11:49
Цитировать
Хоспаде, ведь и правда
Ато  ;D.
Ведь у каждого потока свой стек и именно эту фичу и юзает QThread::currentThread(), т.к функция вызывающая callback функцию вызываеться уже на стеке конкретного потока, то любой код вызываемый из неёё путем не сложных манипуляций, в данном случае кроссплатформенных и обернутых в красивую обертку, может узнать все что пожелает о потоке вызвавшем её.