Russian Qt Forum

Qt => Кладовая готовых решений => Тема начата: Denjs от Октябрь 13, 2010, 15:48



Название: Синхронное обращение через сигнал слоты и возврат результата расчета после emit
Отправлено: Denjs от Октябрь 13, 2010, 15:48
  • Как проверить что твой сигнал получен и обработан?
  • Как дождаться момента когда твой сигнал обработан?
  • Как получить значения, рассчитанные в приемном слоте, к которому подключен твой сигнал? (ведь ты не знаешь куда он даже подключен?)
  • Как избавиться от "лишнего груза знаний" о том, кто должен рассчитывать нужные тебе параметры?
Эти и похожие проблемы решает класс t_returnSyncObject.
У вас есть класс-компонента которая рассчитывает по запросу какие-то значения, а есть классы которым необходимы данные параметры. При этом ни первые ни вторые не желают ничего знать друг о друге. Сигнал-слоты с дополнительным объектом в сигнатуре сигнала помогут связать такие объекты.

В каком-то смысле, это "внутрипрограммная" реализация идей SOA - "через сигнал-слот вызывается расчет каких-либо значений, и ни источник ни приемник не знают друг о друге ничего".

применение и описание - см в коде.

PS: Все вроде потоко-безопасно и подходит для межпоточного взаимодействия, но, признаться пока специально не проверял ))))

PS: В качестве бонуса - "кроссплатформенный Sleep" - static void SleepMS_qt( unsigned int time)

------------------------------------------------
Исходный код класса:
t_returnSyncObject.h
Код:
/*
           UTF-8 encoded file !!!!
*/
#ifndef T_RETURNSYNCOBJECT_H
#define T_RETURNSYNCOBJECT_H

#include <QObject>
#include <QMutexLocker>
#include <QVariant>

/*
@Denjs 2010
Public Domain licensed ("Общественное достояние")
QT 4.6 tested
*/

/*
Класс презназначенный для реализации
синхронного взаимодействия
через сигнал-слоты.

Может использоваться для передачи параметров расчетов обратно к вызывающей стороне,
для подтверждения получения сигнала.
Может приостановить исходный поток до момента пока сигнал не будет обработан.


Экземпляр класса передается с сигналом,
а на приемной стороне вызывается метод
bool t_returnSyncObject::done()
для сигнализации того, что обработка закончена.
для отслеживания случая, когда сигнал подключен
к более чем 1 слоту, вызывается
bool t_returnSyncObject::done()


На исходной стороне, после испускания сигнала,
вызывается
bool t_returnSyncObject::waitForDone(int timeOut);
метод задерживает управление до момента,
пока не вызван .done() или истечения таймаута.

Для передачи параметров используется
t_returnSyncObject::set_result(QVariant retult)

*/


class t_returnSyncObject : public QObject
{
    Q_OBJECT

public:
    explicit t_returnSyncObject(QObject *parent = 0);

signals:

public slots:
    bool done();
    bool isDone();

    bool reset();
    bool waitForDone(int _timeOut);
    bool setResult(QVariant __result);
    QVariant result();

private:
    mutable QMutex mutex;
    bool    _done;
    QVariant _result;
};

//================================================================================
//--------------------------------------------------------------------------------
// Linux :
#if defined (Q_WS_X11)
        /* nothing needs to be included here yet...*/
// Win :
#elif defined (Q_WS_WIN)
        // for Sleep() :
        #include <windows.h>
// Mac:
#elif defined (Q_WS_MAC)
        /* NOT SUPPORTED THIS VERSION */
#else
        /* NOT SUPPORTED THIS VERSION */
#endif
//--------------------------------------------------------------------------------

static void SleepMS_qt( unsigned int time)
{
        // Linux:
        #if defined (Q_WS_X11)
                        usleep(time*1000);//sleep in millisecinds
        // Win:
        #elif defined (Q_WS_WIN)
                        Sleep(time);//WIN  2008.02.19
        // Mac:
        #elif defined (Q_WS_MAC)
                        // NOT SUPPORTED THIS VERSION
        #else
                        // NOT SUPPORTED THIS VERSION
        #endif
        return;
};


#endif // T_RETURNSYNCOBJECT_H

t_returnSyncObject.cpp
Код:
/*
           UTF-8 encoded file !!!!
*/
#include "t_returnSyncObject.h"

//============================================================================
t_returnSyncObject::t_returnSyncObject(QObject *parent) :
    QObject(parent)
 {
    reset();
 };

//============================================================================
bool t_returnSyncObject::done()
 {
    QMutexLocker locker(&mutex);
    _done=true;
    return _done;
 };

//============================================================================
bool t_returnSyncObject::isDone()
 {
    QMutexLocker locker(&mutex);
    return _done;
 };

//============================================================================
bool t_returnSyncObject::waitForDone(int _timeOut)
 {
    int timePassed=0;
    int stepTimeout=200;
    if ( (!isDone()) && (timePassed<_timeOut) )
        {
            SleepMS_qt(stepTimeout);
            //sleep
            timePassed += stepTimeout;
        };
    return isDone();
 };

//============================================================================
bool t_returnSyncObject::setResult(QVariant __result)
 {
    QMutexLocker locker(&mutex);
    _result = __result;
    return _done;
 };

//============================================================================
QVariant t_returnSyncObject::result()
 {
    return _result;
 };

//============================================================================
bool t_returnSyncObject::reset()
 {
    QMutexLocker locker(&mutex);
    _result = QVariant();
    _done = false;
    return true;
 };




------------------------------------------------
Исходный код приложения:

код вызывающей стороны,
у вызывающей стороны есть сигнал
void mySignal(t_returnSyncObject *syncResultObject)
который подключен к слоту, который описан в последнем листинге.
Код:
            t_returnSyncObject *syncResultObject=new t_returnSyncObject(this);

            emit mySignal(syncResultObject);
            bool rez=syncResultObject->waitForDone(5000);// ждем не более 5 секунд
            if (rez==false) //таймаут...
                {
                    qDebug() << "Таймаут получения ответа от приемной стороны..";
                    return -1;
                };
            //теперь проверим что нам ответил слот-сервис
            QString rezStr=syncResultObject->result().toString();

код слота:
Код:
void myClass2::mySlot(t_returnSyncObject *syncResultObject)
{
    if (syncResultObject==0) return;
    if (syncResultObject->isDone()) return;

    QString rez="Обработано!";

    syncResultObject->setResult(QVariant(rez));
    syncResultObject->done();
    return;
}

Обсуждаем, комментируем, в меру ругаем, улучшаем ?  :)

PS: из улучшений я пока могу предложить только добавить обработку сообщений в цикле ожидания (bool t_returnSyncObject::waitForDone(int _timeOut)) - что бы не "замирать" в случае чего...

PS: также можно попытаться развить возврат множества значений в класс-источни-сигнала. Но это на личное усмотрение)


Название: Re: Синхронное обращение через сигнал слоты и возврат результата расчета после emit
Отправлено: Akon от Октябрь 13, 2010, 19:08
похоже на visitor.

методы isDone() и result() должны быть const.
поле _done должно быть volatile.
waitForDone() в общем случае должен принимать callback - пользователь твоего класса сам решит чем нагрузить. обработка цикла сообщений это частный случай.

Ну и стиля Qt лучше придерживаться, имхо.













 


Название: Re: Синхронное обращение через сигнал слоты и возврат результата расчета после emit
Отправлено: Denjs от Октябрь 13, 2010, 22:20
2 Akon : ээээ.... вы кажется не поняли зачем нужен класс или как я его применяю.

методы isDone() и result() должны быть const.
эти методы нужны для возврата данных именно в тот экземпляр объекта который испустил слот, именно в то место и время, где он был испущен. И относятся они именно к тому экземпляру t_returnSyncObject, ссылка на который нам прислана с сигналом.


Название: Re: Синхронное обращение через сигнал слоты и возврат результата расчета после emit
Отправлено: spectre71 от Октябрь 13, 2010, 22:47
  • Как проверить что твой сигнал получен и обработан?
  • Как дождаться момента когда твой сигнал обработан?
  • Как получить значения, рассчитанные в приемном слоте, к которому подключен твой сигнал? (ведь ты не знаешь куда он даже подключен?)
  • Как избавиться от "лишнего груза знаний" о том, кто должен рассчитывать нужные тебе параметры?

1) Например Qt::DirectConnection, или выставить флаг, или послать обратный сигнал, или ...
2) Например Qt::DirectConnection, или выставить флаг, или послать обратный сигнал, или ...
3) поскольку ты где-то делаешь прямое подключение, легко сделать там и обратное подключение - самое примтивное. Или ...
4) Интерфейсы, менеджеры интерфейсов и прочая паттерная хрень :) Или ...


Название: Re: Синхронное обращение через сигнал слоты и возврат результата расчета после emit
Отправлено: Denjs от Октябрь 14, 2010, 00:10
1) Например Qt::DirectConnection, или выставить флаг, или послать обратный сигнал, или ...
2) Например Qt::DirectConnection, или выставить флаг, или послать обратный сигнал, или ...
3) поскольку ты где-то делаешь прямое подключение, легко сделать там и обратное подключение - самое примтивное. Или ...
4) Интерфейсы, менеджеры интерфейсов и прочая паттерная хрень :) Или ...
Qt::DirectConnection при межпотоковом взаимодействии всегда(!) становится Qt::QuotedConnection;

выставлять флаг? где? и куда смотреть? связанные объекты даже ссылок не имеют друг на друга....;

обратное подключение?! и что? отправив сигнал-запрос, я должен ловить результат в другом слоте, а в итоге - "одну простую функцию" разносить на несколько слотов и фактически - "делать громоздкую реализацию машины состояний" вместо одного простого линейного алгоритма который должен запросить несколько фнешних параметров?? не-не-нееее)

"Интерфейсы, менеджеры интерфейсов и прочая паттерная хрень"? дада) именно хрень. тем более в условиях когда сигнатура функции фактически и является описанием мини-интерфейса.


Название: Re: Синхронное обращение через сигнал слоты и возврат результата расчета после emit
Отправлено: Kolobok от Октябрь 14, 2010, 00:29
Qt::DirectConnection при межпотоковом взаимодействии всегда(!) становится Qt::QuotedConnection;

В этом случае можно использовать Qt::BlockingQueuedConnection.


Название: Re: Синхронное обращение через сигнал слоты и возврат результата расчета после emit
Отправлено: voral от Октябрь 14, 2010, 00:31
Хм.. Может у меня такой особой необходимости не возникало идти таким путем....

А почему не через sender()?


Название: Re: Синхронное обращение через сигнал слоты и возврат результата расчета после emit
Отправлено: Denjs от Октябрь 14, 2010, 00:42
Qt::DirectConnection при межпотоковом взаимодействии всегда(!) становится Qt::QuotedConnection;

В этом случае можно использовать Qt::BlockingQueuedConnection.
Цитировать
This connection type should only be used where the emitter and receiver are in different threads. Note: Violating this rule can cause your application to deadlock.
т.е. в таком случае - я должен постоянно следить за тем, что в каком потоке у меня находится и куда я обращаюсь? не хочу. геморно. "тут так напиши, а тут так"...
(кстати, спасибо за инфу - не залазил в данную часть ассистанта со времен 4.3 - тогда этого типа соединения не было)))

А почему не через sender()?
мне не надо обращаться к объекту-источнику. Мне надо вернуть ему результат.

Далее - попытка использовать sender() требует от меня знать класс объекта который меня вызывает. и даже не говоря о том, что поэтому sender() "нарушает" "сигнал-слотовую парадигму"(?)(см замечания троллей в ассистанте), - он работает только в рамках соединений типа QT::QuotedConnection - т.е. в рамках одного потока.
(или в новых версиях QT уже это поменяли??))))


Название: Re: Синхронное обращение через сигнал слоты и возврат результата расчета после emit
Отправлено: spectre71 от Октябрь 14, 2010, 01:44
1) Например Qt::DirectConnection, или выставить флаг, или послать обратный сигнал, или ...
2) Например Qt::DirectConnection, или выставить флаг, или послать обратный сигнал, или ...
3) поскольку ты где-то делаешь прямое подключение, легко сделать там и обратное подключение - самое примтивное. Или ...
4) Интерфейсы, менеджеры интерфейсов и прочая паттерная хрень :) Или ...
Qt::DirectConnection при межпотоковом взаимодействии всегда(!) становится Qt::QuotedConnection;

выставлять флаг? где? и куда смотреть? связанные объекты даже ссылок не имеют друг на друга....;

обратное подключение?! и что? отправив сигнал-запрос, я должен ловить результат в другом слоте, а в итоге - "одну простую функцию" разносить на несколько слотов и фактически - "делать громоздкую реализацию машины состояний" вместо одного простого линейного алгоритма который должен запросить несколько фнешних параметров?? не-не-нееее)

"Интерфейсы, менеджеры интерфейсов и прочая паттерная хрень"? дада) именно хрень. тем более в условиях когда сигнатура функции фактически и является описанием мини-интерфейса.


Я не зря написал везде или ... Вариантов много... Для разных ситуаций - свой.
А про "хрень", интерфейсы в большинстве случаев более оптимальное решение для твоего пункта (4).
Теперь про это: "обратное подключение?! и что? отправив сигнал-запрос, я должен ловить результат в другом слоте"
Ты хочешь всегда! - отправил запрос - ждем результата? А как же асинхронная работа потоков. Используй тогда  DirectConnection.


Название: Re: Синхронное обращение через сигнал слоты и возврат результата расчета после emit
Отправлено: SASA от Октябрь 14, 2010, 10:21
  • Как проверить что твой сигнал получен и обработан?
  • Как дождаться момента когда твой сигнал обработан?
  • Как получить значения, рассчитанные в приемном слоте, к которому подключен твой сигнал? (ведь ты не знаешь куда он даже подключен?)
  • Как избавиться от "лишнего груза знаний" о том, кто должен рассчитывать нужные тебе параметры?
1. Это противоречит идеи сигнал/слот.
2. Уже есть - Qt::ConnectionType.
3. Это противоречит идеи сигнал/слот. (но сам грешен, получаю  :'()
4. Шаблон - стратегия.

Можно продумать идею "Единичный сигнал". Т.е. сигнал соединяется всегда с одним слотом. Т.е. упростить идею до непрямого вызова функции. Это уже есть QMetaObject::invokeMethod. Но нужно знать у кого вызывать, что не всегда удобно.

З.Ы. Можно прикрепить  архив со всем проектом, что изучать код в любимой IDE.


Название: Re: Синхронное обращение через сигнал слоты и возврат результата расчета после emit
Отправлено: Denjs от Октябрь 14, 2010, 11:51
Используя термины SASA, полагаю можно сказать, что :

... назначение класса t_returnSyncObject - обеспечить механизм непрямого синхронного "потоко-безопасного" вызова функций, через сигнал-слотовый механизм, с возвратом рассчитываемого значения.

По сравнению с QMetaObject::invokeMethod, данный механизм лучше тем, что объекту-пользователю нет необходимости знать кто именно обслуживает его обращение.

По сравнению различными типами подключения (Qt::DirectConnection/Qt::BlockingQueuedConnection/QT::QuotedConnection) - данный механизм обеспечивает "псевдо-синхронное взаимодейтсвие" не требующее специального типа подключения в зависимости от нахождения объектов в одном или разных потоках.

и расскажите подробнеее - почему вы считаете что желание "проверить что твой сигнал получен и обработан?" - это "противоречит идеи сигнал/слот."? разве, скажем TCP противоречит UDP? )))))


Название: Re: Синхронное обращение через сигнал слоты и возврат результата расчета после emit
Отправлено: navrocky от Октябрь 14, 2010, 12:55
PS: В качестве бонуса - "кроссплатформенный Sleep" - static void SleepMS_qt( unsigned int time)

Как вариант могу предложить следующий хак:

Код
C++ (Qt)
#include <QThread>
 
class QThreadHack : public QThread
{
public:
   using QThread::sleep;
   using QThread::msleep;
   using QThread::usleep;
};
 
...
// using
QThreadHack::msleep(5000);
 

Кстати для меня загадка, зачем тролли сделали эти методы protected  ???


Название: Re: Синхронное обращение через сигнал слоты и возврат результата расчета после emit
Отправлено: Denjs от Октябрь 14, 2010, 16:58
PS: В качестве бонуса - "кроссплатформенный Sleep" - static void SleepMS_qt( unsigned int time)
Как вариант могу предложить следующий хак:
гы! да это же реализация (анти)паттерна Паблик Морозов!


Название: Re: Синхронное обращение через сигнал слоты и возврат результата расчета после emit
Отправлено: BRE от Октябрь 14, 2010, 17:19
Кстати для меня загадка, зачем тролли сделали эти методы protected  ???
Потому что нет никакой необходимости усыплять главный поток.


Название: Re: Синхронное обращение через сигнал слоты и возврат результата расчета после emit
Отправлено: SASA от Октябрь 14, 2010, 17:20
и расскажите подробнеее - почему вы считаете что желание "проверить что твой сигнал получен и обработан?" - это "противоречит идеи сигнал/слот."? разве, скажем TCP противоречит UDP? )))))

Сигнал - это способ сообщить всем, что с объектом что-то случилось. Параметры - подробности случившегося. Этот сигнал могут принять любое (включая ноль) количество заинтересованных.

Например. Нажали кнопку  "Выход". Кнопки нет дела, до того, что она делает. Но она говорит "Меня нажали". Приложение ловит сигналы от кнопки и отрабатывает реакцию - закрывается.

З.Ы. Это в идеале. Но злостные хукеры, типа нас с Вами, используют этот механизм в своих низменных целях ;D

З.З.Ы. Пошел учить паттерны.


Название: Re: Синхронное обращение через сигнал слоты и возврат результата расчета после emit
Отправлено: SASA от Октябрь 14, 2010, 17:23
Кстати для меня загадка, зачем тролли сделали эти методы protected  ???
Потому что нет никакой необходимости усыплять главный поток.


И чтоб нельзя было усыпить поток из вне.


Название: Re: Синхронное обращение через сигнал слоты и возврат результата расчета после emit
Отправлено: Denjs от Октябрь 15, 2010, 00:11
Сигнал - это способ сообщить всем, что с объектом что-то случилось. Параметры - подробности случившегося. Этот сигнал могут принять любое (включая ноль) количество заинтересованных.
мой класс дает направление уникального нового способа получить сразу кучу разных результатов при попытке обратиться к обшественности.
типа "кто тут?" и тебе в ответ хох голосов.. ну класно же)

мульти вызов функции))) позволяет например одним сигнлом промониторить состояние десятка обхектов - надо только переписать методо setResult() таким образом что бы он добавлял новое значение в массив. ))))
согласитесь - наступать на грабли одновременно и неизвестно с кем - веселее)


Название: Re: Синхронное обращение через сигнал слоты и возврат результата расчета после emit
Отправлено: Igors от Октябрь 15, 2010, 01:21
Ладно, поругаем  :)

1) Какие преимущества по сравнению с BlockingConnection? Вижу одно: можно отвалиться по таймауту - ну значит на это надо упирать (подчеркивать) в описании ф-циональности. И вопрос: а что делать с эти объектом
Код:
 t_returnSyncObject *syncResultObject=new t_returnSyncObject(this);
если отвалились? Нет никакой гарантии что слот не проснется и этот момент непредсказуем. Бодрое
Цитировать
return -1;
есть утечка, нужно зачищать с блокировками.

2)
В каком-то смысле, это "внутрипрограммная" реализация идей SOA - "через сигнал-слот вызывается расчет каких-либо значений, и ни источник ни приемник не знают друг о друге ничего".
Ну так уж и ничего?  :)  Как минимум оба знают t_returnSyncObject. Возможности взаимодействия определяются тем что умеет/понимает этот (интерфейсный) класс. Потребуется больше параметров - и придется доливать т.к. одним QVariant уже не обойтись (ну или раздувать QVariant что по сути то же). Я против этого ничего не имею, но не вижу что тут нового/выгодного.


Название: Re: Синхронное обращение через сигнал слоты и возврат результата расчета после emit
Отправлено: navrocky от Октябрь 15, 2010, 09:45
Кстати для меня загадка, зачем тролли сделали эти методы protected  ???
Потому что нет никакой необходимости усыплять главный поток.


И чтоб нельзя было усыпить поток из вне.

Ну иногда все-таки надо усыплять главный поток, не все же гуёвые приложения.. А во вторых усыпить поток извне этими функциями не возможно.


Название: Re: Синхронное обращение через сигнал слоты и возврат результата расчета после emit
Отправлено: BRE от Октябрь 15, 2010, 10:55
Ну иногда все-таки надо усыплять главный поток, не все же гуёвые приложения..
Это для чего например? Что бы приложение выполнялось по дольше?


Название: Re: Синхронное обращение через сигнал слоты и возврат результата расчета после emit
Отправлено: navrocky от Октябрь 15, 2010, 11:03
Ну иногда все-таки надо усыплять главный поток, не все же гуёвые приложения..
Это для чего например? Что бы приложение выполнялось по дольше?


Тесты, работа с оборудованием, всякие специфические задачи, типа запустить программку подождать немного, обратиться...


Название: Re: Синхронное обращение через сигнал слоты и возврат результата расчета после emit
Отправлено: BRE от Октябрь 15, 2010, 11:10
Тесты, работа с оборудованием, всякие специфические задачи, типа запустить программку подождать немного, обратиться...
Ну как бы подобные вещи принято делать в отдельных потоках и пусть они там себе ждут, если надо.
А вот для чего останавливать главный поток?


Название: Re: Синхронное обращение через сигнал слоты и возврат результата расчета после emit
Отправлено: SASA от Октябрь 15, 2010, 12:59
Тесты, работа с оборудованием, всякие специфические задачи, типа запустить программку подождать немного, обратиться...
Тролтех подумал об этом void QTest::qSleep ( int ms ) ;D


Название: Re: Синхронное обращение через сигнал слоты и возврат результата расчета после emit
Отправлено: Igors от Октябрь 15, 2010, 17:28
А вот для чего останавливать главный поток?
Да его только и делают что усыпляют  :) Чем занимается главная нитка - ждет событий (на том же мутексе/семафоре), то же "усыпление".

Что касается sleep (в любой форме), то сколько раз я его ставил - столько же и убирал. Упирается в то что глупо ждать когда ответ уже есть. Так что sleep - для тестовых/отладочных целей, не более. Другое дело - напр ждать на семафоре заданное время, такая возможность есть.


Название: Re: Синхронное обращение через сигнал слоты и возврат результата расчета после emit
Отправлено: Denjs от Октябрь 15, 2010, 17:44
Что касается sleep (в любой форме), то сколько раз я его ставил - столько же и убирал. Упирается в то что глупо ждать когда ответ уже есть. Так что sleep - для тестовых/отладочных целей, не более. Другое дело - напр ждать на семафоре заданное время, такая возможность есть.
Sleep удобен когда работаешь с оборуоваием и реализуешь в одной процедуре некий протокол обмена данными.

Мол авторизация, 5 сек ждем ответа, команда, ждем ответа, выключиться, ждем статуса завершения.
Если описанное выше делать в асинхронной сигнал слотовой модели - мне нужно делать машину состояний с 4 состояниями, писать 3 процедуры и кучу проверок. И городить ещё и таймер , что бы отслеживать таймаут.

Со слипом это прекрасно уложится в одну функцию. Короткую, простую, понятную.


Название: Re: Синхронное обращение через сигнал слоты и возврат результата расчета после emit
Отправлено: navrocky от Октябрь 15, 2010, 18:09
Цитировать
Со слипом это прекрасно уложится в одну функцию. Короткую, простую, понятную.

Плюсую.
 
Что бы тут не говорили иногда sleep нужен, и тролли лучше бы сделали одну нормальную реализацию, чем плодили бы их в каждом модуле отдельно.. ну бог им судья. Я лично пользую sleep из буста...


Название: Re: Синхронное обращение через сигнал слоты и возврат результата расчета после emit
Отправлено: BRE от Октябрь 15, 2010, 19:04
Да его только и делают что усыпляют  :) Чем занимается главная нитка - ждет событий (на том же мутексе/семафоре), то же "усыпление".
Мы говорим конкретно про sleep в главном потоке, судя по следующему тексту ты это понял, для чего это "пояснение" про мютексы/семафоры? Или это не мне "пояснение" или ты думаешь я этого не знаю?

Упирается в то что глупо ждать когда ответ уже есть.
Золотые слова.


Название: Re: Синхронное обращение через сигнал слоты и возврат результата расчета после emit
Отправлено: BRE от Октябрь 15, 2010, 19:06
Мол авторизация, 5 сек ждем ответа, команда, ждем ответа, выключиться, ждем статуса завершения.
Если описанное выше делать в асинхронной сигнал слотовой модели - мне нужно делать машину состояний с 4 состояниями, писать 3 процедуры и кучу проверок. И городить ещё и таймер , что бы отслеживать таймаут.
Для чего это делать в главном потоке? Запусти нитку и пусть она хоть по десять минут ждет ответа.


Название: Re: Синхронное обращение через сигнал слоты и возврат результата расчета после emit
Отправлено: Igors от Октябрь 15, 2010, 19:18
Если не надо отслеживать cancel и перерисовывать окна (а за 5 сек это может понадобиться) - ну тогда конечно sleep всем хорош  :) Ну да бог с ним, мы отвлеклись.

А вот как удалять созданный экземпляр t_returnSyncObject ? Я поприкидывал, но не вижу простого решения - сложновато получается. Какие есть мнения?


Название: Re: Синхронное обращение через сигнал слоты и возврат результата расчета после emit
Отправлено: Denjs от Октябрь 15, 2010, 19:54
Для чего это делать в главном потоке? Запусти нитку и пусть она хоть по десять минут ждет ответа.
А,... ну если так... )) но тут скорее вопрос не в главном потоке или нет, а в том, что как "заснуть" в методе класса?
т.е. у меня есть класс - я его засунул в параллельный поток. Потом срабатывает слот - и в этом слоте(слоту?)) мне надо сделать "описанный выше протокол". Я могу получить поток, в котором я сейчас нахожусь - но мне это ничего не даст. т.к. метод "поспать" у обычного QT-шного потока - частный. Приходится или извращаться, или делать кроссплатформенную обертку над ос-зависимыми функциями.

Вспомните - с чего данная нить разговора началась?)


Название: Re: Синхронное обращение через сигнал слоты и возврат результата расчета после emit
Отправлено: Denjs от Октябрь 15, 2010, 19:59
А вот как удалять созданный экземпляр t_returnSyncObject ? ... Какие есть мнения?
сам удалится сборщиком мусора) почему не?

или с сигналом пересылать QPointer<returnSyncObject> для безопасности, а в конструкторе returnSyncObject сделать deleterLater?
все равно объекту не нужно жить дольше чем работает функция в которой он создан.


Название: Re: Синхронное обращение через сигнал слоты и возврат результата расчета после emit
Отправлено: BRE от Октябрь 15, 2010, 20:05
Вспомните - с чего данная нить разговора началась?)
Я помню. :)

Если твой класс является наследником от QThread, то sleep будет доступен для всех его методов.


Название: Re: Синхронное обращение через сигнал слоты и возврат результата расчета после emit
Отправлено: Igors от Октябрь 15, 2010, 20:15
или с сигналом пересылать QPointer<returnSyncObject> для безопасности, а в конструкторе returnSyncObject сделать deleterLater?
все равно объекту не нужно жить дольше чем работает функция в которой он создан.
Не дождались ответа - кончился таймаут. Удалили объект и вышли. Слот проснулся, долбит удаленный объект. Ваши действия?

Edit: еще одно соображение: если вышли по таймауту, то по-хорошему слот не должен выполнять действий, т.к. поезд ушел.


Название: Re: Синхронное обращение через сигнал слоты и возврат результата расчета после emit
Отправлено: Denjs от Октябрь 15, 2010, 20:26
Не дождались ответа - кончился таймаут. Удалили объект и вышли. Слот проснулся, долбит удаленный объект. Ваши действия?
эээээ....
"долбит" удаленный объект? простите за нескромный вопрос - "кто кого куда"?))))
"слот проснулся" - т.е. наконец до него был доставлен сигнал?

приемный класс никого не "долбит". Если Pointer<returnSyncObject> выдал что объект удален - то извините. Поздно. Никаких действий.

Это если с QPointer. Если с простыми ссылками - то объект не должен быть удален пока на него есть ссылки. И собственно приемный объект.

А собственно какие проблемы если ничго не делать?


Название: Re: Синхронное обращение через сигнал слоты и возврат результата расчета после emit
Отправлено: ритт от Октябрь 15, 2010, 20:34
я вот читаю-читаю и никак понять не могу - чем вам invokeMethod() не угодил?
результаты возвращать позволяет, прямые и отложенные (в т.ч. и с блокировкой) вызовы поддерживает, никаких хитрых объектов городить и портить сигнатуры не нужно...


Название: Re: Синхронное обращение через сигнал слоты и возврат результата расчета после emit
Отправлено: Igors от Октябрь 15, 2010, 21:04
"слот проснулся" - т.е. наконец до него был доставлен сигнал?
Да
А собственно какие проблемы если ничго не делать?
Если объект не удалять - течет память. Если удалять - обработчик получает невалидный указатель.

приемный класс никого не "долбит". Если Pointer<returnSyncObject> выдал что объект удален - то извините. Поздно. Никаких действий.
Это если с QPointer.
А когда выдал? Слот получает сигнал и начинает его обрабатывать. В этот момент у посылающего кончился таймаут - и объект удален. Тогда получается нужен QSharedPointer, хотя лучше держать информацию об отмене в самом объекте.

Если с простыми ссылками - то объект не должен быть удален пока на него есть ссылки. И собственно приемный объект.
Это понятно но Вы уж пожалуйста оформите все как положено, ведь это "кладовая готовых решений".



Название: Re: Синхронное обращение через сигнал слоты и возврат результата расчета после emit
Отправлено: Denjs от Октябрь 15, 2010, 21:16
я вот читаю-читаю и никак понять не могу - чем вам invokeMethod() не угодил?
результаты возвращать позволяет, прямые и отложенные (в т.ч. и с блокировкой) вызовы поддерживает, никаких хитрых объектов городить и портить сигнатуры не нужно...
он требует знания о том, то тебя вызвал и его методах.
Т.е. вы не "портите сигналтуры",  -  вы "портите методы класса")))

пр сигнал слотовом механизме я даже к наименованию не привязан, не коворя о получении ссылки "на объект на другом конце".


Название: Re: Синхронное обращение через сигнал слоты и возврат результата расчета после emit
Отправлено: ритт от Октябрь 15, 2010, 22:28
он требует знания о том, то тебя вызвал и его методах.
Т.е. вы не "портите сигналтуры",  -  вы "портите методы класса")))
ась? это вообще о чём было? зачем знать апи вызывающего? при чём тут методы класса и их порча?

пр сигнал слотовом механизме я даже к наименованию не привязан, не коворя о получении ссылки "на объект на другом конце".
какому-такому наименованию?
что за объект на другом конце и зачем нужна ссылка на него? если это про объект, испустивший сигнал, то `sender()` в помощь.

короче, них не понял я пред.мессага...