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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: Корректное завершение нескольких клиентских потоков  (Прочитано 3828 раз)
Fregloin
Супер
******
Offline Offline

Сообщений: 1025


Просмотр профиля
« : Май 19, 2011, 17:39 »

Есть несколько потоков (Qt шных), в которых идет прием по клиентским сокетам.
по нажатию кнопки, нужно корректно завершить все потоки, предварительно закрыв соединение в этих потоках.
Корректен ли такой подход, который привожу ниже:
код потока клиента
Код:
void    QMMNClientThread::run()
{
    mmnClient->connectToServer();
    exec();
}

void     QMMNClient::disconnectFromServer()
{
    fmustReconnect = false;
    if(fsocket->state() == QAbstractSocket::ConnectedState)
    {
        fsocket->close();
        fsocket->waitForDisconnected();
    }
}
при дисконекте клиента, выдерживаю паузу в 2 секунды и делаю реконтект и так вечно пока не надо принудительно завершить работу потока

Код:
void    CEC::startClient()
{
    for(int i=0;i<1;i++) //в будущем тут будет несколько потоков
    {
        if(!mmnClientThread[i]) mmnClientThread[i] = new QMMNClientThread(this); //создаем поток
        mmnClientThread[i]->mmnClient->remoteHost = Host[i]; //задаем к кому подключаться
        mmnClientThread[i]->mmnClient->remotePort = Port[i];
        connect(mmnClientThread[i]->mmnClient,SIGNAL(frameReceived(int)),this,SLOT(data_receive(int))); //обработка принятых данных
        connect(mmnClientThread[i]->mmnClient,SIGNAL(connected(int)),this,SLOT(chan_connected(int)));
        connect(mmnClientThread[i]->mmnClient,SIGNAL(disconnected(int)),this,SLOT(chan_disconnected(int)));
        connect(this,SIGNAL(disconnectClient()),mmnClientThread[i]->mmnClient,SLOT(disconnectFromServer())); //тут я буду слать сигнал потоку что бы он отключил сокет
        mmnClientThread[i]->start(); //запускаю поток
    }
}

void    CEC::stopClient()
{
    for(int i=0;i<1;i++)
    {
        if(mmnClientThread[i])
        {
            emit(disconnectClient()); //шлю сигнал сокету в потоке на принудительное отключение
            disconnect(mmnClientThread[i]->mmnClient); //отключаю все сигналы/слоты
            mmnClientThread[i]->quit(); //закрываю поток
            mmnClientThread[i]->wait(); //жду
            delete mmnClientThread[i]; //удаляю поток
            mmnClientThread[i] = NULL;
        }
    }
}
До этого я не слал сигнал в поток клиента, и иногда прога вылетала, так как сокет успевал подать сигнал о приеме данных, но сам поток уже уничтожен.
После внесения этой коррективы вроде бага на наболюдаю. Подскажите с точки зрения Qt грамотно ли я прибиваю сокет/поток?
Записан
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3258


Просмотр профиля
« Ответ #1 : Май 19, 2011, 20:56 »

я не вижу дисконнект клиент
эмит - это макрос, к-ый ничего не делает, просто для красоты.
следовательно, вы вызываете ф-ию напрямую и что-то мне подсказывает что не из того потока
зачем тут вообще больше 1го потока? сокеты все из себя и так асинхронные
Записан
Fregloin
Супер
******
Offline Offline

Сообщений: 1025


Просмотр профиля
« Ответ #2 : Май 20, 2011, 12:45 »

вообще по плану будет 5 подключений к разным машинам, все одновременно будут получать данные с серверов. данные идут потоком, непрерывно каждые 250 мсек кадры по 4-8Кб. помимо того, в основном потоке еще идёт прорисовка в GraphicsScene около 1000 объектов + логика расчета состояний. поэтому резонно хотя бы чтение по сокетам перенести в одельные потоки. В целом пока этот механизм работает нормально.
Записан
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3258


Просмотр профиля
« Ответ #3 : Май 20, 2011, 16:32 »

Данные приходят от сервера, попадают в буфер сокета, Qt кидает сигнал об этом. Вы копируете из буфера в свои структуры. Зачем тут больше 1го потока?
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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