![]() |
|
|
![]()
|
|
| fux |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 31 Регистрация: 21.3.2014 Репутация: нет Всего: нет |
Придумал смешной способ передачи сигнала в дочерний процесс.
В родительском процессе вызывается метод объекта QProcess proc.terminate(); В дочернем, методом closeEvent (QCloseEvent *event) перехватывается закрытие процесса и игнорируется, причина прерывания считывается из разделяемой памяти. Может кто посоветует более солидный метод? |
|||
|
||||
| reider |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 49 Регистрация: 18.11.2013 Репутация: нет Всего: нет |
QLocalSocket и QLocalServer
|
|||
|
||||
| Alexeis |
|
|||
![]() Амеба Профиль Группа: Админ Сообщений: 11743 Регистрация: 12.10.2005 Где: Зеленоград Репутация: 1 Всего: 459 |
Есть целая глава в справке, которая говорит как осуществлять межпроцесснрное взаимодействие.
http://doc.qt.io/qt-5/ipc.html -------------------- Vit вечная память. Обсуждение действий администрации форума производятся только в этом форуме гениальность идеи состоит в том, что ее невозможно придумать |
|||
|
||||
| fux |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 31 Регистрация: 21.3.2014 Репутация: нет Всего: нет |
QLocalSocket и QLocalServer - работает только при одноуровневой схеме, при каскаде процессов, нужно писать монстрообразного диспетчера.
QSharedMemory - хорошее решение но читать его таймером, это закапывать ресурсы. Остается сигнал в QProcess заслать, но тут у меня ничего не получается, мозгов не хватает, или QIODevice, но что-то тоже не очень красиво. |
|||
|
||||
| Alexeis |
|
|||
![]() Амеба Профиль Группа: Админ Сообщений: 11743 Регистрация: 12.10.2005 Где: Зеленоград Репутация: 1 Всего: 459 |
Семафор вполне может подойти в качестве сигнала, чтоб не заводить таймер, а читать уже из SharedMemory
-------------------- Vit вечная память. Обсуждение действий администрации форума производятся только в этом форуме гениальность идеи состоит в том, что ее невозможно придумать |
|||
|
||||
| fux |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 31 Регистрация: 21.3.2014 Репутация: нет Всего: нет |
У семафора только один сигнал - destroyed, это не годится.
|
|||
|
||||
| math64 |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2505 Регистрация: 12.4.2007 Репутация: 23 Всего: 72 |
на таймере экономишь, но нить (QThread) всё равно нужна. Она и может эмитить сигнал, если нужно.
|
|||
|
||||
| math64 |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2505 Регистрация: 12.4.2007 Репутация: 23 Всего: 72 |
И вроде как нужно два семафора:
Добавлено @ 15:50 Ещё можно общаться через Clipboard или DragAndDrop. Но это может помешать работе других приложений (не будут работать Ctrl-C Ctrl-V в редакторе, мышка будет бегать сама по себе) Это сообщение отредактировал(а) math64 - 23.10.2015, 07:45 |
|||
|
||||
| Alexeis |
|
|||
![]() Амеба Профиль Группа: Админ Сообщений: 11743 Регистрация: 12.10.2005 Где: Зеленоград Репутация: 1 Всего: 459 |
Да именно в этом и смысл, чтобы поток ждал семафора, как семафор просигналил, поток просыпается и шлет сигнал или совершает некоторое действие. -------------------- Vit вечная память. Обсуждение действий администрации форума производятся только в этом форуме гениальность идеи состоит в том, что ее невозможно придумать |
|||
|
||||
| fux |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 31 Регистрация: 21.3.2014 Репутация: нет Всего: нет |
В данном случае используется не поток, а процесс, который живет в своем адресном пространстве. Поэтому, как я понимаю, все ссылки на объекты родителя для дочки не сушествуют, как впрочем и наоборот. Все обмены должны производиться только через системные вызовы. Ни семафоры, ни разделяемая память, как ни странно, никаких сигналов для своих клиентов не генерируют.
|
|||
|
||||
| Guinness |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 310 Регистрация: 21.6.2009 Где: Зеленоград Репутация: 2 Всего: 10 |
CreateProcess, особое внимание стоит обратить на bInheritHandles. Также было бы неплохо почитать про таблицу хэндлов и объекты ядра. Для *nix систем, я думаю, ситуация будет похожа.
ЗЫ если я правильно понял намёки math64 и Alexeis. |
|||
|
||||
| fux |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 31 Регистрация: 21.3.2014 Репутация: нет Всего: нет |
Что такое math64 и Alexeis я не знаю, но задачка похоже зависит от платформы, или через задний проход как в начале.
|
|||
|
||||
| Guinness |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 310 Регистрация: 21.6.2009 Где: Зеленоград Репутация: 2 Всего: 10 |
||||
|
||||
| fux |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 31 Регистрация: 21.3.2014 Репутация: нет Всего: нет |
А что такое toTerminate?
|
|||
|
||||
| math64 |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2505 Регистрация: 12.4.2007 Репутация: 23 Всего: 72 |
QSystemSemaphore как раз для работы с разными процессами.
Этот кусок
будет включен как в родителя, так и в дочку. hasData контролирует передачу данных от родителя к дочке, answer контролирует считывание данных дочерним процессом. |
|||
|
||||
| math64 |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2505 Регистрация: 12.4.2007 Репутация: 23 Всего: 72 |
Это условие завершения работы QThread. Ты можешь вызвать QThread::terminate(), но [quote=документация Qt]Warning: This function is dangerous and its use is discouraged[/qoute] это может завершить нить в неподходящем месте, без освобождения ресурсов. Вместо этого можно завести в нить флаг, который она будет периодически проверять на необходимость завершения работы. Ещё один способ получения сигналов - QFileSystemWatcher. Он может отслеживать изменние, переименование и удаление файлов или каталогов с их содержимым. В этом случае не нужно использовать QThread: QFileSystemWatcher имеет слоты void directoryChanged ( const QString & path ); и void fileChanged ( const QString & path ); Добавлено через 4 минуты и 46 секунд почему-то не получается отредактировать сообщение. directoryChanged и fileChanged - это конечно сигналы, а не слоты. |
|||
|
||||
| fux |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 31 Регистрация: 21.3.2014 Репутация: нет Всего: нет |
Так что же такое toTerminate?
|
|||
|
||||
| math64 |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2505 Регистрация: 12.4.2007 Репутация: 23 Всего: 72 |
Например так:
Но цивилизованным путем завершить нить в Qt считается вызвать thread->quit(); Но для этого run() не должно крутиться в вечном цикле, а заканчиваться exec(); А в данном случае так не получается. Как альтернатива, можно периодически проверять наличие в очереди сигнала на завершение нити. Для того, чтобы обрабатываться события из очереди, вызывается QCoreApplication::processEvents(); но при этом обрабатываются не все события, в частности не обрабатывается deleteLater(). Это сообщение отредактировал(а) math64 - 26.10.2015, 08:38 |
|||
|
||||
| math64 |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2505 Регистрация: 12.4.2007 Репутация: 23 Всего: 72 |
PS: приведенный выше совмещённый код работать не будет - либо использовать флаг toTerminate, либо QEventLoop, который будет создан только при вызове QThread::exec() (смотрел в исходиники).
|
|||
|
||||
| fux |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 31 Регистрация: 21.3.2014 Репутация: нет Всего: нет |
Во всем этом деле меня одно смущает, циклы типа while(1){} - плохой стиль. Процесс, вместо того чтобы делом заниматься, или отдать свое время другому, висит в бесконечном цикле. Для чего тогда придуман механизм прерываний? Конечно производительность современных машин огромная, но всему есть предел, 1000 процессов в таком цикле завесят любой процессор, или я чего-то не понимаю.
|
|||
|
||||
| Alexeis |
|
|||
![]() Амеба Профиль Группа: Админ Сообщений: 11743 Регистрация: 12.10.2005 Где: Зеленоград Репутация: 1 Всего: 459 |
Вообще-то предполагалось, что внутри цикла поток будет спать до востребования на семафоре, а не работать в спин режиме. -------------------- Vit вечная память. Обсуждение действий администрации форума производятся только в этом форуме гениальность идеи состоит в том, что ее невозможно придумать |
|||
|
||||
| math64 |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2505 Регистрация: 12.4.2007 Репутация: 23 Всего: 72 |
Внутри exec() - такой же цикл. Ждёт получения события и обрабатывает его. При вызове quit() поднимается флажок, аналогичный моему toTerminate и происходит выход из цикла. Но он приватный и до него не добраться, приходится заводить свой. А здесь нить спит, как говорит Alexeis, до востребования на семафоре, и эмитит сигнал, который можно обработать в основной нити. Если ждать на семафоре в основной нити, это завесит GUI. Как альтернатива использованию семафоров и нитей, я уже упоминал QFileSystemWatcher. Создаём временный каталог и ждём в нём создания пустого файла. При его создании получаем сигнал directoryChanged(). Но на это, скорее всего, будет тратится больше ресурсов, чем при использовании QSystemSemaphore. Кстати, судя по документации, в QSharedMemory есть ещё один семафор, см. QSharedMemory::lock()/unlock() . Но воспользоваться для наших целей им не получится - он предназначен для предотвращения одновременного доступа двух процессов к разделяемой памяти. |
|||
|
||||
| fux |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 31 Регистрация: 21.3.2014 Репутация: нет Всего: нет |
Вообщето дочерний процесс (не поток) это полноценная программа, которая живет своей жизнью и решает кучу задач, и только иногда выполняет требования родителя (например, показать свое окно).
|
|||
|
||||
| math64 |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2505 Регистрация: 12.4.2007 Репутация: 23 Всего: 72 |
Это я (и вероятно остальные) поняли из Вашего первого сообщения. И именно для независимого процесса даем советы. Например, использется QSystemSemaphore, а не QSemaphore (который предназначен для работы в потоках одного процесса). |
|||
|
||||
| fux |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 31 Регистрация: 21.3.2014 Репутация: нет Всего: нет |
Печальная картина. Пожалуй проще разделяемую память таймером читать.
Всем спасибо! |
|||
|
||||
| math64 |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2505 Регистрация: 12.4.2007 Репутация: 23 Всего: 72 |
Не забывай в таком случае делать QSharedMemory::lock()/unlock(), чтобы исключить одновременный доступ к ней. Можешь попробовать также QFileSystemWatcher. - похоже, подобным способом QtCreator определяет, что открытый на редактирование файл изменён в другом редакторе. Также, несмотря на то, что у тебя отдельные процессы, каждый процесс может иметь несколько потоков, а потоки могут общаться между собой с помощью сигналом. Остаётся только проблема, как остановить поток, ждущий на семафоре. |
|||
|
||||
| Alexeis |
|
|||
![]() Амеба Профиль Группа: Админ Сообщений: 11743 Регистрация: 12.10.2005 Где: Зеленоград Репутация: 1 Всего: 459 |
Очень легко, просто поток после прохода семафора должен проверять флаг завершения. Завершается такой поток предварительной установкой флага завершения с последующей сигнализацией семафора. Поток проснулся, проверил, что нужно завершаться и завершился. -------------------- Vit вечная память. Обсуждение действий администрации форума производятся только в этом форуме гениальность идеи состоит в том, что ее невозможно придумать |
|||
|
||||
![]()
|
| Правила форума "С/С++: Кроссплатформенное программирование, QT/Gtk+/wxWidgets" | |
|
|
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, Любитель. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | С/С++: Кроссплатформенное программирование, Qt/Gtk+/wxWidgets | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |