crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

 
Ответить в данную темуНачать новую тему
> Ошибки в потоках
AltA
  опции профиля:
сообщение 16.2.2015, 17:57
Сообщение #1


Новичок


Группа: Новичок
Сообщений: 3
Регистрация: 16.2.2015
Пользователь №: 4339

Спасибо сказали: 0 раз(а)




Репутация:   0  


Приветствую.
Возникает проблема при работе приложения. Debug пишет:
ASSERT: "!isEmpty()" in file /usr/include/qt4/QtCore/qlist.h, line 282

нагуглил: эта строка значит что я использую элемент qlist'а, в то врема, как qlist пуст.
код выгледит примерно так
void TestThread::run()
{
    ips.clear();
    ports.clear();

    for(;;)
    {
        ok = ports.isEmpty(); // или ips,isEmpty() или и то и другое, ошибка остаётся
        while (!ok && ok1)
        {
            // qDebug() << ips.isEmpty() << ports.isEmpty(); почемуто при пустых листах ports и ips всё равно false

            QTcpSocket* socket;
            socket = new QTcpSocket();
            socket->connectToHost(ips.dequeue(),ports.dequeue());

            if(socket->waitForConnected())
                emit isgood(ips.dequeue(),ports.dequeue());
            //else
               // qDebug()<<"bad"<<ips.first() << this;

            delete socket;
        }


    }


}


Масивы ips и ports пополняются в функции этого класса, в ней же устанавливается ok1 = true; ключевое слово volatile при обьявлении ok и ok1 эфекта не даёт, и судя по всему в моём коде просто некоректно работает функция isEmpty()

знаю что подход к потокам извращенский, пробывал QtConcurrent::run, QThreadPool, в слотах QThread писал проверку, результат - последующий сокет ждёт 30 сек чека предидущего, даже если они чекаются в разных потоках. так вроде работает в несколько потоков.

ps не пинайте по лицу, самоучка, недавно подружился с qt

спасибо




Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
wiz29
  опции профиля:
сообщение 16.2.2015, 18:48
Сообщение #2


Старейший участник
****

Группа: Участник
Сообщений: 600
Регистрация: 7.7.2010
Из: Санкт-Петербург
Пользователь №: 1866

Спасибо сказали: 94 раз(а)




Репутация:   12  


Судя по куску кода: нет потокобезопасного обращения к спискам из разных потоков. Советую сделать хотябы объект синхронизации доступа (QMutex или QReadWriteLock) к ips и ports.
В приведенном куске кода происходит изъятие элементов, где то происходит заполнение этих контейнеров, все это должно быть "обложено" доступом к данным через объект синхронизации.

Сообщение отредактировал wiz29 - 16.2.2015, 18:50
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
AltA
  опции профиля:
сообщение 16.2.2015, 19:34
Сообщение #3


Новичок


Группа: Новичок
Сообщений: 3
Регистрация: 16.2.2015
Пользователь №: 4339

Спасибо сказали: 0 раз(а)




Репутация:   0  


Цитата(wiz29 @ 16.2.2015, 19:48) *
Судя по куску кода: нет потокобезопасного обращения к спискам из разных потоков. Советую сделать хотябы объект синхронизации доступа (QMutex или QReadWriteLock) к ips и ports.

Да тут вообще много чего надо доделать :)
только проблема конкретно в isEmpty()
if(ports.size() > 1)
            {
            qDebug() << ips.isEmpty() << ports.size();
            mutex.lock();
            QTcpSocket* socket;
            socket = new QTcpSocket();
            socket->connectToHost(ips.dequeue(),ports.dequeue());

            if(socket->waitForConnected(1000))
                emit isgood(ips.dequeue(),ports.dequeue());
            else
                qDebug()<<"bad"<<ips.first() << this;

            delete socket;
            mutex.unlock();
            }


вот это работает как надо(точнее нужно ещё добавить один элемент, который, как я понял,остаётся висеть внутри очереди). с 0 в if'е она вылетает с той же ошибкой. цифра 1 означает что в очереди элемент остался? комп получается его не видет. почему?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
wiz29
  опции профиля:
сообщение 16.2.2015, 20:05
Сообщение #4


Старейший участник
****

Группа: Участник
Сообщений: 600
Регистрация: 7.7.2010
Из: Санкт-Петербург
Пользователь №: 1866

Спасибо сказали: 94 раз(а)




Репутация:   12  


потому что вызов метода isEmpty и size тоже должны быть защищены мьютексом.

bool QList::isEmpty () const
Returns true if the list contains no items; otherwise returns false.

Можно и этим методом пользоваться. Проблемы не должно быть.

Да, и рекомендую использовать автоматические объекты для захвата объектов синхронизации (QMutexLocker, QReadLocker/QWriteLocker).

Сообщение отредактировал wiz29 - 16.2.2015, 20:00
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
AltA
  опции профиля:
сообщение 16.2.2015, 21:15
Сообщение #5


Новичок


Группа: Новичок
Сообщений: 3
Регистрация: 16.2.2015
Пользователь №: 4339

Спасибо сказали: 0 раз(а)




Репутация:   0  


Цитата(wiz29 @ 16.2.2015, 21:05) *
потому что вызов метода isEmpty и size тоже должны быть защищены мьютексом.

bool QList::isEmpty () const
Returns true if the list contains no items; otherwise returns false.

Можно и этим методом пользоваться. Проблемы не должно быть.

Да, и рекомендую использовать автоматические объекты для захвата объектов синхронизации (QMutexLocker, QReadLocker/QWriteLocker).


я наверно зря на потоки грешил...
#include <QCoreApplication>


#include <QtGui>
#include <QDebug>
#include <QTcpSocket>

int main(int argc, char **argv)
{
    QCoreApplication app(argc, argv);

    bool ok  = true;
    //bool ok1 = true;

    QQueue<QString> ips;
    QQueue<int> ports;

    ips << "109.122.253.0" << "109.122.253.1" << "109.122.253.2";
    ports << 8080 << 9050 << 1080;

    for(;;)
    {
        ok = ips.isEmpty() || ports.isEmpty();
        while (!ok) //&& ok1)
        {
            qDebug() << ips;
            //qDebug() << ips.isEmpty();
            QTcpSocket* socket;
            socket = new QTcpSocket();
            socket->connectToHost(ips.dequeue(),ports.dequeue());

            if(socket->waitForConnected(1000))
                qDebug() <<ips.first() << ports.first();
            else
                qDebug()<<"bad"<<ips.first();

            delete socket;

        }



    }

    return app.exec();
}
тут то почему вышибает?


#include <QCoreApplication>


#include <QtGui>
#include <QDebug>
#include <QTcpSocket>

int main(int argc, char **argv)
{
    QCoreApplication app(argc, argv);

    bool ok  = false;
    //bool ok1 = true;

    QQueue<QString> ips;
    QQueue<int> ports;

    ips << "109.122.253.0" << "109.122.253.1" << "109.122.253.2";
    ports << 8080 << 9050 << 1080;

    for(;;)
    {
        while (!ok) //&& ok1)
        {
            qDebug() << ips;
            //qDebug() << ips.isEmpty();
            QTcpSocket* socket;
            socket = new QTcpSocket();
            socket->connectToHost(ips.first(),ports.first());

            if(socket->waitForConnected(1000))
                qDebug() <<ips.dequeue() << ports.dequeue();
            else
                qDebug()<<"bad"<<ips.dequeue() << ports.dequeue();

            delete socket;

            ok = ips.isEmpty() || ports.isEmpty();



        }



    }

    return app.exec();
}
мне нужно поспать :mellow: простите за мусор

.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 19.4.2024, 19:44