수색…


Qt 사용 : 수신기 개체가 신호를받지 못하는 경우 DirectConnection

어떤 시간에 발신자 스레드에서 신호가 방출되지만 연결된 슬롯이 호출되지 않는다는 것을 알게되면 (즉, 신호를 수신하지 않음) 사용자가 질문을하고 마지막으로 Qt :: DirectConnection 연결 유형을 수정하게됩니다. 그래서 문제는 발견되었고 모든 것은 괜찮습니다.

하지만 일반적으로 Qt를 사용하는 것은 좋지 않습니다. DirectConnection은 실제로 무엇이 다른지 알기 전까지는 DirectConnection입니다. Qt가 생성 한 각 스레드 (QThread가 생성 한 주 스레드와 새 스레드 포함)는 Event 루프를 가지며 이벤트 루프는 신호를 수신하고 해당 스레드에서 자동 슬롯을 호출합니다. 일반적으로 슬롯 내에서 블로킹 연산을 실행하는 것은 그 스레드의 이벤트 루프를 차단하여 다른 슬롯을 호출 할 수 없기 때문에 바람직하지 못합니다.

이벤트 루프를 차단하면 (매우 시간이 많이 소요되거나 작동을 막음으로써) 이벤트 루프가 차단 해제 될 때까지 해당 스레드에서 이벤트를 수신하지 않습니다. 블로킹 동작이 이벤트 루프를 영원히 차단하면 (예 : 통화 중일 때) 슬롯을 호출 할 수 없습니다.

이 상황에서 Qt :: DirectConnection에 연결할 때 연결 유형을 설정할 수 있습니다. 이제 이벤트 루프가 차단 된 경우에도 슬롯이 호출됩니다. 어떻게 이것이 모든 것을 깨뜨릴 수 있었습니까? In Qt :: DirectConnection 슬롯은 이미 터 스레드에서 호출되며 수신기 스레드에서는 호출되지 않으며 데이터 동기화가 중단되어 다른 문제가 발생할 수 있습니다. 그러므로 Qt :: DirectConnection은 결코 사용하지 마십시오. Qt :: DirectConnection을 사용하여 문제가 해결되면, 코드를주의 깊게 살펴보고 이벤트 루프가 차단 된 이유를 찾아야합니다. Qt에서 이벤트 루프를 차단하지 않는 것이 좋습니다.

여기에 문제를 보여주는 작은 예제가 있습니다. nonBlockingSlot은 blockingSlot이라는 블로킹 이벤트 루프라고 불리는 것을 볼 수 있습니다. while (1)은 잘못된 코딩을 나타냅니다.

class TestReceiver : public QObject{
    Q_OBJECT
public:
    TestReceiver(){
         qDebug() << "TestReceiver Constructed in" << QThread::currentThreadId();
    }
public slots:
    void blockingSlot()
    {
        static bool firstInstance = false;
        qDebug() << "Blocking slot called in thread" << QThread::currentThreadId();
        if(!firstInstance){
            firstInstance = true;
            while(1);
        }
    }
    void nonBlockingSlot(){
        qDebug() << "Non-blocking slot called" << QThread::currentThreadId();
    }
};

class TestSender : public QObject{
    Q_OBJECT
public:
    TestSender(TestReceiver * receiver){
        this->nonBlockingTimer.setInterval(100);
        this->blockingTimer.setInterval(100);

        connect(&this->blockingTimer, &QTimer::timeout, receiver, &TestReceiver::blockingSlot);
        connect(&this->nonBlockingTimer, &QTimer::timeout, receiver, &TestReceiver::nonBlockingSlot, Qt::DirectConnection);
        this->nonBlockingTimer.start();
        this->blockingTimer.start();
    }
private:
    QTimer nonBlockingTimer;
    QTimer blockingTimer;
};

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

    TestReceiver TestReceiverInstance;
    TestSender testSenderInstance(&TestReceiverInstance);
    QThread receiverThread;
    TestReceiverInstance.moveToThread(&receiverThread);
    receiverThread.start();

    return a.exec();
}


Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow