"모델과 상호 작용"이란 무엇을 의미합니까? 직접 조작하여 여러 스레드에서 모델에 액세스하려는 경우 모델에 대한 액세스를 직렬화해야합니다. 모델 내에는 너무 많은 메소드가 있기 때문에 모델 내에 뮤텍스를 추가하지 말 것을 제안합니다. 뮤텍스 락커를 잊기가 너무 쉽기 때문에 매우 지루하고 오류가 발생하기 쉽습니다. 대신 모델이 QObject를 상속하므로 이벤트를 받아 들일 수 있습니다.
- gui 스레드가 모델에 직접 액세스합니다.
- 다른 스레드는 이벤트를 이벤트에 게시하고 응답 이벤트를 수신하여 모델과 상호 작용합니다.
- gui 스레드는 다른 모든 액세스와 함께 이러한 이벤트를 순차적으로 처리하므로 동시 액세스에서 모델을 보호합니다.
물론 다른 스레드도 이벤트를 통해 모델로부터 응답을받을 수 있습니다. 두 개의 이벤트 기본 클래스가 있습니다. Request
클래스가 모델에서 요청하는 데 사용되며, 모델에서 회신에 사용하는 Response
이벤트 기본 클래스가 있습니다. 요청 클래스에는 QObject* sender
구성원이 있어야합니다. 그러면 모델이 회신 이벤트를 게시 할 QObject를 알 수 있습니다. 요청과 응답이 일치 할 수 있도록 요청과 응답에 동일한 식별자 (예 : 순차적으로 증가하는 int)를 전달해야합니다.
QThread::run()
을 다시 구현하지 않고 QObject 내에서 이벤트를 통해 모델과 상호 작용하는 모든 스레드 코드를 구현해야합니다. QObject
을 인스턴스화 한 후에는 별도의 스레드로 이동하기 만하면됩니다. QThread의 기본 구현 인 run()
은 이벤트, 신호 또는 타이머가 준비되어있는 경우 QObject를 실행하기 위해 이벤트 루프를 돌립니다. 제로 지속 시간 타이머는 스레드를 영구적으로 사용중인 상태로 유지하는 방법이지만 한 번에 너무 많은 처리를하지 않도록하십시오. 그렇지 않으면 수신 이벤트 처리가 지연됩니다.
또한 신호와 슬롯을 사용할 수 있지만 직접 호출 할 수 없습니다, 당신은 할 수 있습니다 그들에게
connect()
,
- 가
Qt::QueuedConnection
와 QMetaObject::invokeMethod
를 통해 그들을 호출합니다.
- 은 주 스레드 컨텍스트에서 실행되는 펑터 (예 : 람다)를 통해 호출합니다. 그 방법은 this answer을 참조하십시오. 별도의 스레드에 상주 QObjects의 슬롯에 신호를 연결 장면 뒤에
은 QT 간격은 QMetaCallEvent
로 마샬링 각각의 신호에 해당 연결을 생성하고 스레드를 마샬링 여기서 QObject를 대상 슬롯 목숨 .