Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Qt и кроссплатформенное программирование С/С++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 04.07.2017, 09:26   #1
Pavia
Лис
Старожил
 
Аватар для Pavia
 
Регистрация: 18.09.2015
Сообщений: 2,409
По умолчанию События, таймеры и основной цикл

Проблема. Делаю сетевое приложение. При разрыве соединения должны удаляться клиенты из списка пиров. Проблема в том, что если клиент может не закрыть, а принудительно разорвать соединения. Соответственно сервер не получает ни одного сообщения об этом.
Вешаю на пиры таймер. Но проблема в том, что таймер срабатывает только при обращение к пиру. Если клиент перестал обращаться, то таймер перестаёт работать.

Таймер можно засунуть в отдельный поток. Но как за синхронизировать его с основным потоком?

Или придётся делать глобальный таймер от основного объекта и от него сигнал-слотами протаскивать сообщений?

Как лучше поступить?
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
У дзен программиста программа делает то что он хотел, а не то что он написал .
Pavia вне форума Ответить с цитированием
Старый 04.07.2017, 10:04   #2
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,493
По умолчанию

Цитата:
Сообщение от Pavia Посмотреть сообщение
Но как за синхронизировать его с основным потоком
Например посылайте сигнал в основной поток.
Или просто используйте мьютекс.
waleri вне форума Ответить с цитированием
Старый 04.07.2017, 10:24   #3
Pavia
Лис
Старожил
 
Аватар для Pavia
 
Регистрация: 18.09.2015
Сообщений: 2,409
По умолчанию

Цитата:
Сообщение от waleri Посмотреть сообщение
Например посылайте сигнал в основной поток.
И как это сделать?
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
У дзен программиста программа делает то что он хотел, а не то что он написал .
Pavia вне форума Ответить с цитированием
Старый 04.07.2017, 13:09   #4
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,493
По умолчанию

Судя по контексту темы - через какой нибудь сигнал/слот
http://doc.qt.io/qt-5/threads-qobject.html

Edit
А что собственно мешает делать все в основном потоке?
waleri вне форума Ответить с цитированием
Старый 04.07.2017, 14:16   #5
Pavia
Лис
Старожил
 
Аватар для Pavia
 
Регистрация: 18.09.2015
Сообщений: 2,409
По умолчанию

waleri
А всё так просто. У объекта есть поле Thread. Если emit передаёт в объект с отличным thead то используется очередь событий.
И объекта можно сменить поток.
И тип имитирования можно указать последним параметром при создании соединения connect().


Цитата:
Сообщение от waleri Посмотреть сообщение
Edit
А что собственно мешает делать все в основном потоке?
Да ничего не мешает. Проблема в фризах и синхронности. Просто мне работу на будущее надо себе написать.
А то если я скажу поддержку версионности состояния объекта. Вот кто нибудь поймёт, что это такое? Вот я думаю и вы не поняли о чём я. А напиши параллельность всем понятно. Есть СУБД с поддержкой версионности таблиц, это когда каждый клиент к СУБД имеет свою версию таблицы. Хочу организовать такое же только для объектов.
-----------------
На самом деле у меня беда в другом. При закрытие соединения клиентом объект QTcpSocket автоматически уничтожается. В справки про это не написано. И самое главное он при этом ни каких сигналов не испускает и ошибку не пишет.
А у меня всё из-за этого чехардой идёт. А я уже который день бьюсь понять не могу куда таймеры деваются. Сейчас понял буду исправлять.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
У дзен программиста программа делает то что он хотел, а не то что он написал .
Pavia вне форума Ответить с цитированием
Старый 05.07.2017, 13:59   #6
alexzk
Форумчанин
 
Регистрация: 12.04.2017
Сообщений: 889
По умолчанию

connect делать с последним явным параметром Qt::QueuedConnection - это обязательно вызовет слот в потоке, где создавался объект-приемник (т.е. для объекта в главном - вызовется в главном), причем, поток-эмитер может быть и не кт, например std::thread.

Я так часто у себя рабочие std::thread синхронизирую с гуем. Вообще в многопоточной программе, любой коннект к гую желательно явно прописывать Qt::QueuedConnection сразу. Это позволяет в будущем избегать чудных багов.

Последний раз редактировалось alexzk; 05.07.2017 в 14:04.
alexzk вне форума Ответить с цитированием
Старый 05.07.2017, 14:11   #7
alexzk
Форумчанин
 
Регистрация: 12.04.2017
Сообщений: 889
По умолчанию

Вот по сокетам

Код:
 std::map<uint64_t, QPointer<QTcpSocket>> stellarium; //class member
Код:
 connect(server.get(), &QTcpServer::newConnection, this, [this]()
    {
        static uint64_t connCounter = 0;
        auto dumb = connCounter++;
        QPointer<QTcpSocket> tmp = stellarium[dumb] = server->nextPendingConnection();
        connect(tmp, &QAbstractSocket::disconnected, this, [this, dumb, tmp]()
        {
            if (stellarium.count(dumb))
                stellarium.erase(dumb);

            if (tmp)
                tmp->deleteLater();
        }, Qt::QueuedConnection);

        connect(tmp, &QTcpSocket::readyRead, this, [this, tmp]()
        {
            if (tmp)
                onStellariumDataReady(tmp);
        }, Qt::QueuedConnection);

    }, Qt::QueuedConnection);
    server->listen(QHostAddress::Any, 10001);
Здесь одновременно важны оба Qt::QueuedConnection и QPointer, первый гарантирует последовательное исполнение, а второй обнуляется, если объект уже был удален. Без последовательного исполнения, скажем здесь

Код:
 if (tmp)
                onStellariumDataReady(tmp);
в промежутке м-у двумя строками объект может удалиться, тогда нада лепить более сложные вещи.

...а таймеры - эт вообще гиблое дело. Реально применять во всяких обратных отсчетах в гуе и для отвязки, чтоб не попадать в рекурсии (или развязки потока, через SingleShot + QueuedConnection).

Последний раз редактировалось alexzk; 05.07.2017 в 14:29.
alexzk вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Таймеры tools Qt и кроссплатформенное программирование С/С++ 3 30.05.2010 23:12
Таймеры Sergeu Общие вопросы C/C++ 2 25.03.2010 12:13
Таймеры EdNovice Общие вопросы .NET 1 06.03.2009 11:26
Цикл с предусловием. ( цикл while) Цикл с постусловием. (цикл repeat ... until) Mr.User Помощь студентам 9 23.11.2007 01:34