crossplatform.ru

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

 
Ответить в данную темуНачать новую тему
> connect и типы
gpepsi
  опции профиля:
сообщение 30.9.2011, 13:48
Сообщение #1


Студент
*

Группа: Участник
Сообщений: 73
Регистрация: 31.3.2010
Пользователь №: 1582

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




Репутация:   0  


Использовал сигнал из потока. Обработчик слота находился в другом потоке.
Заметил, что сигнал не доходит.

Поставил Qt::DirectConnection. Сигнал стал приходить.
Но читая про него обнаружил еще и Qt::BlockingQueuedConnection, про который было написано, что он предназначен для
работы из различных потоков и так же блокирует очередь. Но есть коментарий, что этот сигнал может привести
к deadlock-у.

В чем тогда различае между ними, если оба блокируют, но только второй может зависнуть.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 1.10.2011, 22:55
Сообщение #2


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

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




Репутация:   94  


при работе между потоками нужно использовать Авто (AutoConnection) или Через Очередь (QueuedConnection)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
gpepsi
  опции профиля:
сообщение 1.10.2011, 22:58
Сообщение #3


Студент
*

Группа: Участник
Сообщений: 73
Регистрация: 31.3.2010
Пользователь №: 1582

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




Репутация:   0  


Цитата(Litkevich Yuriy @ 1.10.2011, 23:55) *
при работе между потоками нужно использовать Авто (AutoConnection) или Через Очередь (QueuedConnection)


использовал - не приходят
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
gpepsi
  опции профиля:
сообщение 1.10.2011, 23:33
Сообщение #4


Студент
*

Группа: Участник
Сообщений: 73
Регистрация: 31.3.2010
Пользователь №: 1582

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




Репутация:   0  


[quote name='gpepsi' date='1.10.2011, 23:58' post='53407']
[quote name='Litkevich Yuriy' post='53406' date='1.10.2011, 23:55']при работе между потоками нужно использовать Авто (AutoConnection) или Через Очередь (QueuedConnection)

ну может я что-то не так понял.

Пример 1 - хрена лысово:
#include <QCoreApplication>
#include <QThread>
#include <QDebug>

class Sender : public QThread {
    Q_OBJECT

private:
    virtual void run (void)
    {
        while(true)
        {
            emit send();
            QThread::msleep(1000);
        }
    }

signals:
    void send(void);
};

class Receiver : public QObject{
    Q_OBJECT

        public slots:
            void receive(void)
            {
                qDebug() << "OK";
            }
};

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

    Sender sender;
    Receiver receiver;
    QObject::connect(&sender, SIGNAL(send()), &receiver, SLOT(receive()), Qt::QueuedConnection);

    sender.start();
    sender.wait();

    return 0;
}


Пример 2 - работает:
#include <QCoreApplication>
#include <QThread>
#include <QDebug>

class Sender : public QThread {
    Q_OBJECT

private:
    virtual void run (void)
    {
        while(true)
        {
            emit send();
            QThread::msleep(1000);
        }
    }

signals:
    void send(void);
};

class Receiver : public QObject{
    Q_OBJECT

        public slots:
            void receive(void)
            {
                qDebug() << "OK";
            }
};

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

    Sender sender;
    Receiver receiver;
    QObject::connect(&sender, SIGNAL(send()), &receiver, SLOT(receive()), Qt::DirectConnection);

    sender.start();
    sender.wait();

    return 0;
}


Пример 3 - хрена лысово:
#include <QCoreApplication>
#include <QThread>
#include <QDebug>

class Sender : public QThread {
    Q_OBJECT

private:
    virtual void run (void)
    {
        while(true)
        {
            emit send();
            QThread::msleep(1000);
        }
    }

signals:
    void send(void);
};

class Receiver : public QObject{
    Q_OBJECT

        public slots:
            void receive(void)
            {
                qDebug() << "OK";
            }
};

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

    Sender sender;
    Receiver receiver;
    QObject::connect(&sender, SIGNAL(send()), &receiver, SLOT(receive()), Qt::BlockingQueuedConnection);

    sender.start();
    sender.wait();

    return 0;
}


Или я что-то не понял ?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
MoPDoBoPoT
  опции профиля:
сообщение 2.10.2011, 13:24
Сообщение #5


Участник
**

Группа: Участник
Сообщений: 172
Регистрация: 7.5.2009
Из: Москва
Пользователь №: 738

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




Репутация:   9  


Хм, как интересно)
Наверное, дело в том, что для обработки сигналов испускаемых из другого потока (из метода run()) необходим цикл обработки событий (QThread::exec ()). А с соединением Qt::DirectConnection работает, потому что сигнал испускается самим потоком, а он создан в контексте главного потока.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
gpepsi
  опции профиля:
сообщение 2.10.2011, 15:12
Сообщение #6


Студент
*

Группа: Участник
Сообщений: 73
Регистрация: 31.3.2010
Пользователь №: 1582

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




Репутация:   0  


Цитата(MoPDoBoPoT @ 2.10.2011, 14:24) *
А с соединением Qt::DirectConnection работает, потому что сигнал испускается самим потоком, а он создан в контексте главного потока.


создается сам объект, а run работает в другом потоке
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Гость_lanz_*
сообщение 14.8.2012, 13:49
Сообщение #7





Гости








    


MoPDoBoPoT все правильно говорит.
QObject::connect(&sender, SIGNAL(send()), &receiver, SLOT(receive()), Qt::QueuedConnection);

    sender.start();
    sender.wait();
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Гость_lanz_*
сообщение 14.8.2012, 14:12
Сообщение #8





Гости








    


Прошу прощения, криво отправилось.

MoPDoBoPoT все правильно говорит. Правильный код:
QObject::connect(&sender, SIGNAL(send()), &receiver, SLOT(receive()), Qt::QueuedConnection);

sender.start();
app.exec ();
sender.wait();

run работает в другом потоке, но объект источник сигнала создан в том же, поэтому DirectConnect работает. Принадлежность к треду свойство объекта, а не фрагмента кода. Не уверен что такое использование правильное, я бы делал:
class Sender : public Qbject {
    Q_OBJECT

public:
    void run (void)
    {
         while (true) {
            emit send ();
            QTest::qSleep (1000);
         }
    }

signals:
    void send(void);
};

class SenderThread : public QThread {
    Q_OBJECT
private:
    virtual void run (void)
    {
        Sender my_sender; // Объект создан в новом треде
        connect (...) // Коннектим сигнал сендера к объекту в главном потоке
                          // указатель на приемник можно получить по разному
        my_sender.run ();
    }
};

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

    Receiver receiver;
    SenderThread sender_thread;


    sender_thread.start();
    app.exec ();

    return 0;
}

Правильно запускать в методе run цикл обработки событий.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

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


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




RSS Текстовая версия Сейчас: 26.4.2024, 0:07