Russian Qt Forum
Ноябрь 23, 2024, 00:43 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: Передача сокета в другой поток  (Прочитано 15669 раз)
qtkoder777
Частый гость
***
Offline Offline

Сообщений: 245


Просмотр профиля
« : Апрель 20, 2016, 17:53 »

Здравствуйте.
Возникла задача написать такой сервер:
Сервер должен получить данные от клиентов, провести над ними некоторые вычисления и вернуть результат клиенту.
В процессе вычислений могут поступать новые запросы.

Пытаюсь сделать так:
Ввёл структуру, в которой запоминаю сокет клиента, которому надо отослать результат работы с data_.
Код
C++ (Qt)
struct ThreadData
{
     Data data_;
     QTcpSocket* socket_;
};
и очередь QQueue этих структур, которая заполняется в основном потоке

Вычисления крутятся в отдельном потоке наследнике QThread.
Данные извлекаются из очереди, обрабатываются, и отправляются клиенту с помощью
Код
C++ (Qt)
socket_->write()
, если очередь пуста, крутится бесконечный цикл.

Фактически, из потока вычислений данные НЕ ДОХОДЯТ до клиента, хотя write завершается без ошибки.
В основном потоке данные по тому же сокету отправляются и доходят.

Читал где то на другом форуме, что сокеты нельзя передавать между потоками.
Так ли это? И как надо поступать?
« Последнее редактирование: Апрель 21, 2016, 00:42 от qtkoder777 » Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #1 : Апрель 21, 2016, 07:47 »

В рабочих нитках можно только обрабатывать, а результат возвращать в нить сетевого обмена, из которой и отправлять ее клиенту.
Записан
qtkoder777
Частый гость
***
Offline Offline

Сообщений: 245


Просмотр профиля
« Ответ #2 : Апрель 21, 2016, 11:18 »

Откуда сокет вообще знает в какой он нитке - это особенность Qt?
Подходит ли вообще Qt для написания таких программ?
Может стоит смотреть в сторону других библиотек, раз в Qt такие сложности.
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #3 : Апрель 21, 2016, 11:24 »

Откуда сокет вообще знает в какой он нитке - это особенность Qt?
Для того, что бы обеспечить правильную работу сигналов в многопоточных программах, в Qt введено понятие контекст потока.
Изменяется он с помощью метода: QObject::moveToThread.

Подходит ли вообще Qt для написания таких программ?
Может стоит смотреть в сторону других библиотек, раз в Qt такие сложности.
Скажем так, такие программы на Qt можно писать. Насколько это будет эффективно вопрос другой.
Я лично использую для этого boost::asio.
Записан
qtkoder777
Частый гость
***
Offline Offline

Сообщений: 245


Просмотр профиля
« Ответ #4 : Апрель 23, 2016, 16:37 »

В рабочих нитках можно только обрабатывать, а результат возвращать в нить сетевого обмена, из которой и отправлять ее клиенту.
А как вернуть результат в нить сетевого обмена?
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #5 : Апрель 23, 2016, 16:59 »

А как вернуть результат в нить сетевого обмена?
Например, можно возвращать готовый для отбравки объект QByteArray.
Записан
qtkoder777
Частый гость
***
Offline Offline

Сообщений: 245


Просмотр профиля
« Ответ #6 : Апрель 23, 2016, 17:32 »

А как вернуть результат в нить сетевого обмена?
Например, можно возвращать готовый для отбравки объект QByteArray.
Как сообщить что данные готовы к отправке? Сигнал-слот?
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #7 : Апрель 23, 2016, 17:58 »

Сигнал-слот?
Как вариант. Улыбающийся
Записан
sergek
Гипер активный житель
*****
Offline Offline

Сообщений: 872


Мы должны приносить пользу людям.


Просмотр профиля
« Ответ #8 : Апрель 23, 2016, 18:00 »

Сигнал-слот?
Как вариант. Улыбающийся
А это не единственно правильный вариант? Улыбающийся
Записан

Qt 5.13.0 Qt Creator 5.0.1
Win10, Ubuntu 20.04
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #9 : Апрель 23, 2016, 18:08 »

А это не единственно правильный вариант? Улыбающийся
Конечно нет. Для передачи результатов, так же как и для передачи заданий, можно использовать самописные очереди, мэилбоксы и другие механизмы межпоточных взаимодействий.
Записан
qtkoder777
Частый гость
***
Offline Offline

Сообщений: 245


Просмотр профиля
« Ответ #10 : Апрель 23, 2016, 18:41 »

Как следует поступать когда потоку "нечего делать"?
Крутиться в бесконечном цикле и проверять, не появилось ли чего в очереди - это правильно или нет?

« Последнее редактирование: Апрель 23, 2016, 18:44 от qtkoder777 » Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #11 : Апрель 23, 2016, 18:46 »

В идеале он должен спать и просыпаться только когда появилась работа. Поищите по форуму, было несколько тем с примерами про очереди и QWaitCondition.
Записан
qtkoder777
Частый гость
***
Offline Offline

Сообщений: 245


Просмотр профиля
« Ответ #12 : Апрель 23, 2016, 19:02 »

Какие параметры должен иметь сигнал для передачи результатов?
Сигнал получат все потоки соединений, надо как-то узнать какому потоку предназначен сигнал.
То есть два параметра - строка результата и this потока?
« Последнее редактирование: Апрель 23, 2016, 19:17 от qtkoder777 » Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #13 : Апрель 23, 2016, 19:16 »

В самом простом случае с Qt-сигналами: сетевая нитка должна передать рабочей какой-то идентификатор клиента/сокета, от которого получен этот запрос и исходные данные для работы. После завершения обработки рабочая нитка должна передать сетевой тот же идентификатор клиента/сокета и результат работы. Сетевая нитка по идентификатору находит нужный сокет и отправляет в результат.
Записан
qtkoder777
Частый гость
***
Offline Offline

Сообщений: 245


Просмотр профиля
« Ответ #14 : Апрель 23, 2016, 19:17 »

Какие особенности у межпоточного connect-a?
Обнаружилось, что после такого connect-a сокет, который в нити thread, перестаёт получать данные (ft - нить вычислений)
Код
C++ (Qt)
connect(&ft, SIGNAL(dataReady(const QString &)), thread, SLOT(slotSendData(const QString &)));
Код
C++ (Qt)
void FortuneThread::slotSendData(const QString &s)
{
tcpSocket_->write(s.toAscii());
}
Есть какой-то загадочный последний необязательный параметр, может там чего надо прописать?
« Последнее редактирование: Апрель 23, 2016, 19:20 от qtkoder777 » Записан
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.118 секунд. Запросов: 23.