2012-05-13 4 views
4

Qt 코드를 무한 루프로 실행할 수 있습니까?이 코드는 잠재적으로 무한 루프로 진행될 수 있습니까?

QNetworkAccessManager m; 
QNetworkReply *reply = m.get(QNetworkRequest(QUrl("http://www.example.org/"))); 
QEventLoop loop; 
QObject::connect(reply, SIGNAL(finished()), &loop, SLOT(quit())); 
loop.exec(); 
qDebug() << reply->readAll(); 
delete reply; 

이것은 기본적으로 웹 페이지의 내용을 표시하는 "동기식"방법입니다.

은 그것을 사용하여 문제를 관찰 않았지만, I는 다음과 같은 시나리오를 고려 : replyfinished 신호 이벤트 루프가 만들어 전에 방출 finished 간의 신호 슬롯 연결된다

  • quit는 신호가 순방향 따라서 트리거링되지 않을 시점으로부터 방출되지 않는다
  • 로한다 quit
  • loop.exec() 것 계속 루프

Qt 이벤트 루프가 어떻게 작동하는지 이해할 수 있습니까?

답변

1

Qt가 자신의 코드 (위 코드 예)를 실행하는 동안 새로운 신호와 호출 슬롯을 처리 할 수 ​​없습니다. 메소드가 실행되는 동안 모든 신호가 방출되고 나중에 처리됩니다. 도중에 신호를 강제 처리하려면 QCoreApplication::processEvents을 호출하여 현재 이벤트 루프의 신호를 처리하거나 QEventLoop::exec을 호출하여 다른 루프에서 신호를 처리 할 수 ​​있습니다.

따라서이 코드는 안전합니다. 신호가 너무 빨리 지나면 이벤트 대기열에서 대기합니다.

신호를 내보내고이 신호에 연결된 슬롯이 Qt::DirectConnection 인 경우이 슬롯이 즉시 실행됩니다. 그러나 이것은 귀하의 사건과 일치하지 않습니다. Qt는 singal이 나오기 전에 내부 코드를 실행해야합니다. 메서드가 실행되는 동안이 코드를 실행할 수 없습니다. 스레드는 하나이고 호출 스택은 하나뿐입니다.

Qt 스레드를 사용할 때 이벤트 루프의 동작은 더욱 복잡합니다.

+0

"나중에 처리됩니다". 올바르지 않습니다. "신호가 방출되면 슬롯에 연결된 슬롯은 대개 즉시 실행됩니다"[Qt documentation] (http://qt-project.org/doc/qt-4.8/signalsandslots.html)을 참조하십시오. 당신이 혼란스러운 신호와 사건이라고 생각합니다. 동일한 스레드 내에서 출력되는 신호는'QMetaObject :: activate'->'qt_static_metacall'을 사용하여 즉시 처리되므로 부적절한 신호 처리 CAN은 무한 재귀 및 스택 오버 플로우를 초래합니다. – SigTerm

+0

예, 이것에 대해 썼습니다. 그러나 이것은이 코드가 신호를 내보내는 경우에만 발생할 수 있습니다. 그러나 순간에 실행되는 코드가 QNetworkReply와 관련이 없다면 QNetworkReply의 신호를 내 보내지 못합니다 (또는 중첩 된 함수 호출). 그리고 아무도이 신호를 동시에 방출 할 수 없습니다. –

-1

loop.exec()을 실행하기 직전에 reply->isFinished()을 확인할 수 있습니다. 그렇다면 루프를 실행하지 마십시오.

+0

틀린, QNetworkAccessManager :: get는 이벤트 루프에 도착할 때까지 생성 된 요청 처리를 시작하지 않습니다. –

관련 문제