Может ли time.sleep(secs) приостановить QNetworkAccessManager, запрашивает ли он асинхронно?

QNetworkAccessManager может выполнять запросы асинхронно, а time.sleep(secs) может приостановить выполнение на заданное количество секунд. Меня смутил приведенный ниже код. Здесь t2 всегда больше 10 секунд?

Без использования time.sleep(secs) в коде здесь готовый слот getWebPageSRC вызывался за фиксированное время, примерно около 3 секунд.

Я проверил это пару раз и обнаружил, что t2 всегда больше 10 секунд. Кто-нибудь может объяснить, почему?

de myMethod(self):
    ...
    reply.finished.connect(self.getWebPageSRC)
    self.t=time.clock()
    time.sleep(10)

def getWebPageSRC(self):
    t2=time.clock()-self.t
    print(t2)

P.S. поскольку QNAM выполняет свою работу асинхронно, я думаю, что он работает в другом потоке, поэтому имеет свой собственный цикл событий, поэтому time.sleep(secs) приостанавливает весь цикл событий Qt всех потоков или только цикл событий потока, в котором он находится? Приостанавливает ли спящий режим в основном потоке цикл обработки событий всех других потоков?


person iMath    schedule 21.12.2014    source источник
comment
Извините, я сделал ваш вопрос более правильным английским языком. ;-) Вы используете pyqt или pyside? Недостаточно места, чтобы добавить оба.   -  person lpapp    schedule 21.12.2014
comment
@lpapp Спасибо, стыдно за мой плохой английский ... Я использую PyQt. Недостаточно места, чтобы добавить оба. Я не понимаю, что вы здесь имеете в виду.   -  person iMath    schedule 22.12.2014
comment
Мы можем добавить максимум до пяти тегов к вопросу.   -  person lpapp    schedule 22.12.2014


Ответы (3)


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

Сказав это, причина относительно проста: когда вы начинаете спать, цикл событий Qt не может выполнять свою работу, поэтому ваш слот не может быть обработан из очереди событий циклом событий до того, как вы проснетесь от блокирующего сна.

Это не было бы проблемой, если бы вы, скажем, спали в другом потоке, хотя даже это было бы поначалу слишком странно, но здесь вы спите в потоке (блоке), где событие должно обрабатываться асинхронно.

В конце концов, в приложении Qt нет особого смысла спать. Qt в первую очередь предназначен для асинхронной работы, особенно для интерфейсов QIODevice, таких как QtNetwork.

При использовании Qt забудьте о существовании этого оператора:

time.sleep(10)

Всякий раз, когда вы решите заблокировать ожидание ответа, вы можете использовать API синхронизации, хотя, если честно, даже это не является полной синхронизацией:

# 10000 msecs = 10 secs
myNetworkReply.waitForBytesWritten(10000)

Я, вероятно, даже пойду дальше: я бы, вероятно, избегал использования Qt в приложении Python для чего-либо еще, кроме строго пользовательского интерфейса. То есть всего остального можно добиться средствами python, обычно лучше и проще из python приложения. Я думаю, вам следует сосредоточиться на графическом интерфейсе, но это, безусловно, основано на мнении. Подходящими альтернативами могут быть асинкор, скрученный и т. д.

person lpapp    schedule 21.12.2014
comment
да, вы правы. В документации QThread говорится, что это :wait(), а функции sleep() вообще не нужны, поскольку Qt - это среда, управляемая событиями. Вместо ожидания () рассмотрите возможность прослушивания сигнала готового (). Вместо функций sleep() рассмотрите возможность использования QTimer. - person iMath; 22.12.2014
comment
@iMath: если проблема решена, выберите ответ. - person lpapp; 22.12.2014
comment
Я дополнил вопрос, не получил никакого уведомления? - person iMath; 22.12.2014
comment
@iMath: пожалуйста, никогда не меняйте свой вопрос, и ваш QNAM не запускается в другом потоке на основе того, что вы просили, но даже если бы это было так, сон не мог бы заблокировать другой поток, как в ответе. - person lpapp; 22.12.2014
comment
поскольку QNAM выполняет свою работу асинхронно, я думаю, что это работает в другом потоке, правильно ли это? - person iMath; 22.12.2014
comment
@iMath: нет, это неправильно, но в любых ответах здесь уже хорошо объяснено, что это основной поток. Пожалуйста, внимательно перечитайте ответы и постарайтесь понять их. Мы не написали неверных вещей. - person lpapp; 22.12.2014
comment
Кроме того, я предлагаю вам забыть о QtNetwork согласно моему ответу. На мой взгляд, нет особого смысла использовать его в приложении Python, поскольку у Python гораздо более зрелые сетевые модули, которые лучше интегрируются с миром Python, а также без накладных расходов C++ на Python. Но опять же, это тоже есть в ответе, просто повторюсь. Итак, почти все, что вы задали в этом вопросе, следует забыть, хех. Это хороший академический вопрос, но на практике он бесполезен, если вы все делаете правильно. - person lpapp; 22.12.2014
comment
@iMath: чего-то не хватает в ответе? - person lpapp; 23.12.2014
comment
Спасибо за вашу большую помощь !!! Я думаю, что не понимаю асинхронность, поэтому задал этот вопрос. мой последний вопрос здесь: приостанавливает ли сон в основном потоке цикл событий всех других потоков? - person iMath; 26.12.2014
comment
Причина, по которой я использую QtNetwork здесь, заключается в том, что мне было легко рассчитать скорость загрузки с помощью void QNetworkReply::downloadProgress(qint64 bytesReceived, qint64 bytesTotal) с QTimer, что касается сетевых модулей Python, я использовал запросы в своем приложении, пока я не могу найти также способ расчета скорости загрузки по запросам, поскольку QNetworkAccessManager может выполнять запросы асинхронно, чтобы вмешательство пользователя не было заморожено, а если вместо этого вы используете запросы, вам нужно обернуть его в другой поток, кажется неудобным. - person iMath; 26.12.2014
comment
@iMath: нет, не должно. - person lpapp; 26.12.2014
comment
@iMath: вы пробовали библиотеки, о которых я вам говорил? Например. asyncore не требует многопоточности. - person lpapp; 26.12.2014
comment
Большое спасибо! Я никогда не использовал asyncore, соответствующий asyncio в py3.docs.python. org/3.4/library/asyncio.html#module-asyncio Хотя я не понимаю примечание в начале, означает ли это, что модуль не является зрелым, поэтому API все еще можно изменить или даже удалить? от Python в будущем? - person iMath; 27.12.2014

Независимо от того, что QNAM выполняет свою работу асинхронно, он по-прежнему работает в основном потоке. Остановка основного потока на 10 секунд также блокирует QNAM.

person Jerry    schedule 21.12.2014
comment
поскольку QNAM выполняет свою работу асинхронно, я думаю, что он работает в другом потоке, поэтому имеет свой собственный цикл событий, поэтому time.sleep(secs) приостанавливает весь цикл событий Qt всех потоков или только цикл событий потока, в котором он находится? Приостанавливает ли спящий режим в основном потоке цикл обработки событий всех других потоков? - person iMath; 22.12.2014
comment
Нет, это не работает в другом потоке, если вы явно не указали его. - person Jerry; 23.12.2014
comment
Спасибо, time.sleep(secs) приостанавливает весь цикл событий Qt всех потоков или только цикл событий потока, в котором он находится? Приостанавливает ли спящий режим в основном потоке цикл обработки событий всех других потоков? - person iMath; 26.12.2014

Это правда, что QNetworkAccessManager может выполнять запросы асинхронно, но все они выполняются в основном потоке приложения. Поэтому, когда вы звоните

time.sleep(10)

Основной поток блокируется на 10 секунд и во время этой блокировки больше ничего не делается. Это потому, что QNetworkAccessManager здесь нет в другой теме.

person Nejat    schedule 21.12.2014
comment
поскольку QNAM выполняет свою работу асинхронно, я думаю, что он работает в другом потоке, поэтому имеет свой собственный цикл событий, поэтому time.sleep(secs) приостанавливает весь цикл событий Qt всех потоков или только цикл событий потока, в котором он находится? Приостанавливает ли спящий режим в основном потоке цикл обработки событий всех других потоков? - person iMath; 22.12.2014
comment
@iMath Асинхронная работа не означает, что у него есть собственный цикл обработки событий. Многие объекты могут действовать асинхронно в основном цикле событий, используя сигналы и слоты. Также QNAM не живет в другом потоке. Таким образом, здесь блокировка основного цикла событий приводит к блокировке QNAM. - person Nejat; 22.12.2014
comment
Спасибо, time.sleep(secs) приостанавливает весь цикл событий Qt всех потоков или только цикл событий потока, в котором он находится? Приостанавливает ли спящий режим в основном потоке цикл обработки событий всех других потоков? - person iMath; 26.12.2014
comment
@iMath time.sleep(secs) просто приостанавливает цикл событий своего потока (здесь только основной цикл событий). Поэтому, если вы создаете какие-либо другие потоки, они не затрагиваются и продолжают работать. Сон в основном потоке просто приостанавливает основной поток. - person Nejat; 26.12.2014