2012-05-31 3 views
2

QTcpSocket 연결을 설정하고 유지하기 위해 C++/Qt의 스레드로 작업하고 있습니다.Qt의 스레드 간 통신

문제는 네트워크 연결이 끊어지면 해당 스레드가 특정 순서로 다시 연결되어야한다는 것입니다. 이미 작동하고 있지만 다른 문제가 있습니다. 현재 스레드 만 연결이 끊어 졌거나 모두 연결이 끊어진 경우 각 스레드에 대해 알아야합니다.

내가 가진 첫 번째 아이디어는 각 스레드 상태를 저장하고 다른 모든 사람을 검사 할 수있는 클래스에 대한 참조를 모든 스레드에 전달하는 것이 었습니다.

그러나 나는 더 쉬운 생각을 가지고 있으며, 그것이 작동하는지 또는 불가능할지를 알고 싶습니다. Qt의 슬롯과 신호를 사용하십시오.

그래서 모든 스레드는 같은 클래스에서 왔지만 다른 데이터는 Ctor로 전달됩니다. 그래서 그 아이디어는 그 클래스 안에 슬롯과 신호를 만들고 그들을 연결하고 ID를 전달하는 신호를 방출하는 것입니다. 그렇다면 모든 스레드의 슬롯이 시작됩니다 ... 아니면 완전히 잘못된 것일 수 있으며 유일한 슬롯은 신호를 방출 한 스레드와 동일한 것입니다.

이 것이 가능합니까 또는 아니십니까?

답변

2

신호 및 슬롯 연결은 런타임에 수행됩니다. 즉, 클래스의 특정 인스턴스를 연결하고 있습니다. 신호를 방출 할 수 없으며 클래스의 모든 인스턴스에 "브로드 캐스트"할 수 있습니다. 서로 다른 스레드 사이의 신호가 가능하지만이를 유지하는 것은 약간 번거로운 일이 될 수 있습니다 (모두 the documentation에서 아주 잘 설명됩니다).

내가 너라면, 아마도 QSemaphore 또는 QSharedMemory을 들여다 볼 것입니다.

+0

링크를 제공해 주셔서 감사합니다. 설명서에 해당 정보가 없습니다. 마침내 뮤텍스와 공유 메모리를 사용했지만 스레드 간 신호를 완전히 살펴볼 것입니다. 재미있을 것 같습니다. –

3

우선 신호 슬롯 연결은 스레드와 QObject의 신호와 슬롯 사이에서 이루어집니다. 음, QThread는 QObject이지만, 실제로 QThread에서 파생해서는 안됩니다. QThread에서 파생하지 마십시오.

당신이 할 것은 :

  1. 하나 이상의 QThreads 가 (단지 건설되지 않음) 시작하기. 이러한 QThread는 기본 Qt 클래스 일 뿐이며 그 클래스에서 파생되지 않습니다. 시작된 QThread가 차단되어 이벤트가 이벤트 대기열에 게시 될 때까지 대기합니다. QThread::run()의 기본 구현은 QEventLoop::exec() (또는 이에 상응하는 것)을 호출합니다. 따라서 이러한 스레드는 시작 후에 CPU주기를 소비하지 않습니다.

  2. QObject 묶음을 인스턴스화합니다. 필요에 따라 모든 신호/슬롯 연결을 수행하십시오.

  3. moveToThread(QThread*)을 호출하여 이러한 개체를 하나 이상의 QThread로 이동합니다.

신호 슬롯 연결 설정은 일반적인 방법으로 이루어 지므로 특별한주의가 필요하지 않습니다. 스레드간에 QObject를 이동할 때 Qt::DirectConnection에서 Qt::QueuedConnection까지 연결 유형을 변경하는 것을 포함하여 Qt가 모든 것을 처리합니다.

다른 스레드에서 그렇게 할 가능성이 높기 때문에 해당 QObject에 직접 메서드를 호출하면 안됩니다. 따라서 액세스가 직렬화되지 않을 때 모든 종류의 불량 사항이 발생합니다. 당신은 아래에서 가장 빠른 것부터 가장 느린 것부터 순서대로해야합니다.# 3은 항상 # 4보다 빠르지 만 # 2와 # 3 사이의 벤치마킹이 필요합니다.

  1. 포스트 QObject를에 사용자 정의 이벤트

    및 파생 QObject를의 customEvent(QEvent*) 방법을 처리합니다.

  2. 신호 슬롯 연결을 사용하고 QObjects '슬롯에 연결된 신호를 방출하십시오.

  3. 이전에 찾은 방법으로 QMetaMethod::invoke을 사용하십시오. 메서드 조회가 한 번만 수행되기 때문에 # 4보다 빠릅니다.

  4. QMetaObject::invokeMethod을 사용하십시오. 라는 카피 생성자가없는 및 ​​QEvent의 건설에 당신이 직접 제외 할 더 마샬링가 없기 때문에

는 QObjects에 QEvents를 게시하는 것은, 신호 슬롯 호출을 사용하는 것보다 빠릅니다.

프로파일 링/벤치마킹에서 이벤트 게시가 너무 느린 경우에만 QSharedMemory을 사용하는 것이 좋습니다. 과도한 수의 QThread를 갖는 것은 비생산적입니다. 아마도 시스템의 CPU 코어 수보다 많지 않아야합니다. 뮤텍스 나 세마포어와 같은 동기화 프리미티브를 사용하면 너무 많은 스레드를 커밋해야합니다. 당신은 확실히 을하지 마십시오는 연결 당 하나의 스레드를 갖고 싶습니다! Qt는 이미 이미 사용하고있는 이벤트 큐를 사용하여 QObject마다 이벤트 큐 뮤텍스를 가지고 있습니다.