2013-02-16 2 views
0

멀티 스레드 서버 (QTcpServer 상속)가 있습니다. 새 연결이 나타나면 새 작업 (QRunnable 상속)을 만들고 소켓 설명자를 생성자에 전달한 다음이 작업을 QThreadpool (3 명의 작업자)에게 보냅니다. 실행에서실행 된 작업 삭제시 Qt 앱이 충돌 함

QThreadPool::globalInstance()->start(task); 

() 나는 동적으로 QTcpSocket 설정 소켓 기술자를 생성하고 처음받은 바이트를 읽습니다. 이 바이트 값을 기반으로 새로운 특정 작업 (QRunnable 상속)을 만들어 이전에 만든 QTcpSocket 개체에 대한 ctr 포인터로 전달하고이 작업을 QThreadpool로 푸시합니다.

이 특정 작업으로 인해 일상적인 응용 프로그램 충돌이 발생합니다. 로그 파일에서이 특정 작업의 소멸자가 호출 된 것을 봅니다.

QObject를 :

또한 Qt는 창조주는 다음 오류 메시지를 다른 스레드에있는 부모를위한 어린이를 만들 수 없습니다. (부모가 QNativeSocketEngine입니다 (0x18c62290)는, 부모의 스레드 QThread가 (0x18c603e0), 현재의 thread가 QThread입니다 (0x18cc3b60) QSocketNotifier : "개체에 이벤트를 보낼 수 없습니다 : 소켓 신고자는 QCoreApplication :: sendEvent에서 다른 스레드 ASSERT 실패에서 비활성화 할 수 없습니다 다른 스레드에 의해 소유. 현재 스레드 스레드 18c603e0에서 만든 '(QNativeSocketEngine'유형 ') 18cc3b60. 수신기' "파일 커널/qcoreapplication.cpp, 라인 (420)

나는 유사한 게시물을 발견하지만 불행히도 나는 할 수 없었다 내 문제를 해결하는 방법을 이해하십시오. 제발, 도와주세요.

답변

1

tw에서부터 QTcpSocket을 사용할 수 없습니다. o QObject은 스레드로부터 안전하지 않기 때문에 다른 스레드가 필요합니다.

첫 번째 작업에서 QTcpSocket을 만들었으므로 해당 작업과 관련된 스레드에 "살아"있습니다. 포인터를 다른 QRunnable에 전달하면 두 번째 스레드가 포인터를 액세스하려고 시도합니다.

다른 스레드간에 동일한 QTcpSocket을 공유하지 않는 방식으로 앱을 다시 디자인해야합니다. 한 가지 가능성은 원래 작업에서 다른 특정 기능을 구현하고 첫 번째받은 바이트를 기반으로 적절한 기능을 선택하는 것입니다.

+0

도움을 주셔서 감사합니다. 문제를 게시하기 전에 내가 권고 한 방식으로 앱을 구현했습니다. 잘 작동하지만 미래에는 많은 작업을 추가 할 계획이므로 끔찍한 것처럼 보입니다. 그리고 특정 기능 접근 방식을 사용하면 한 순간에 원래 작업이 너무 뚱뚱해질 것입니다. 그래서 더 나은 해결책을 공동체에 물어보기로했습니다. – Den

+0

그러나 그것은 충분히 이상합니다. 첫 번째 작업에서는 QTcpSocket * socket = new QTcpSocket; 그런 식으로 나는이 소켓을 작업 사이에 던지고 싶었습니다. 그리고 나는 그것을 얻었다. 나는 원래 작업의 첫 번째 바이트를 읽고, 다른 작업을 생성하고, 소켓 포인터를 전달한다. 소켓 작업이 끝나면 아무것도하지 않는다. 두 번째 작업에서는이 소켓을 통해 클라이언트 응용 프로그램에 테스트 메시지를 보냅니다. 고객이이 메시지를받습니다. 하지만 그때 나는 '소켓을 삭제하십시오;' 두 번째 작업 소멸자에서 내 응용 프로그램이 충돌합니다. – Den

+0

소켓에 다른 작업을 수행하지 않더라도 여전히 내부적으로 이벤트를 처리하고 있습니다. – JKSH