2013-02-21 7 views
1

2D 플로팅 라이브러리 인 xmgrace에 대한 사용자 지정 컨트롤 인터페이스를 개발하는 데 Qt를 사용하고 있습니다. 나는 내 프로젝트에 3 명을 가지고있다QProcess : 프로세스가 아직 실행 중일 때 삭제됨

  1. 백그라운드 스레드에서 C에서 일부 공유 오브젝트 코드를 실행
  2. QThread Qt를에서 만든 GUI.
  3. 파이프를 사용하여 위의 두 가지에 연결된 xmgrace 창. (grace_np 라이브러리 사용)

(1) --> (2)의 통신은 공유 오브젝트 코드에 선언 된 일부 전역 변수의 상태를 변경함으로써 수행됩니다.

통신 : (1) --> (3) & (2) --> (3)은 grace_np 라이브러리가 제공하는 내장 함수를 사용합니다.

이제는 (2) --> (1)의 통신이 문제의 원인입니다. 나는 생각할 수있는 2 가지 가능한 방법을 시도했다 : a) Qt 신호를 내보내고 C 코드 내에서 호출되는 Qt 코드에서 공유 객체 선언. b) 스레드에서 리턴하고 리턴 값을 사용하여 일부 조작을 수행 한 후 스레드를 다시 시작하십시오.

이 두 방법론 모두 신뢰할 수없는 결과를 제공합니다. 내 GUI가 걸리면/세그먼트 오류가 발생 내가 메시지를 얻을 : 내 코드에서 아무 곳이나 QProcess 클래스를 사용하고 있지 않다

QProcess: Destroyed while process is still running

. 그래서 이것은 수수께끼가되었습니다. 가능한 원인에 대한 정보를 제공해주십시오.

추 신 : (3)에 대한 파이프는 편도이므로 그렇게해야합니다.

편집 1 : 참고로 내가 Qt는 4.2을 사용하고, 그래서 나는, 나는 코드를 참을 수 없어 미안 해요) ( 을 movetothread을 사용하여 다음 QObject를 접근 방식을 사용 할 수

회사 정책에 기인 할 수 없으며 또한 무엇을 넣을 지 모르기 때문에 (너무 거대합니다.) 공유 된 C 코드는 400k + lines입니다.

나는 내 문제의 원인을 찾았습니다. QMessageBox 클래스를 사용하면이 문제가 발생하는 것 같습니다. 처음에는 QMessageBox의 정적 함수를 사용했습니다. 이제는 스택과 힙 모두에 대해 선언을 시도했지만 문제는 여전히 지속됩니다. 하지만 코드에서 QMessageBox에 대한 모든 호출을 제거하면 문제가 해결된다는 것을 알았습니다. 하지만 지금 문제는 어떻게 메시지를 표시합니까? 저는 여기서 추측하고 있습니다 만, QMessageBox의 모달 특성이 내 프로그램과 xmgrace 사이에 존재하는 파이프를 차단하고 그 결과로 종료되도록 할 수 있습니까? 그런 다음 커스텀 QMessageBox (모달이 아닌)를 작성하면이 문제가 해결 될 수 있습니다.

편집 2 :

내가 작업자 스레드에서 QMessageBox를 호출하고 있지 않다. 게다가 작업자 스레드를 사용하는 방식으로 프로그램을 닫지 않으면 반환되지 않습니다.내 QThread :: 실행 기능의 형식 인 아이디어를 제공하려면 :

c_init & c_run 공유 C 코드에서 링크 된 함수입니다
QThread_Object::run() 
{ 
    c_init(); 
    c_main(); 
} 

. 따라서 QMessageBox를 직접 호출하는 것은 불가능합니다. 현재 QMessageBox를 사용하지 않고 대신 QMainWindow 상태 표시 줄을 사용할 계획입니다. 그러나 전체 기능을 제공하지는 않습니다. 나는이 편집 3

Qt는 4.2 버그 수도있을 것 같군요 :

내가 문제를 어떻게 유발 하였다 (2) --> (1)에서 이전의 통신을 언급했다. 이제는이 통신을 완전히 끝내 었으며 더 정확하게 작업자 스레드를 시작한 후에 QMessageBox를 호출하여 문제가 발생했음을 발견했습니다. 이전에 언급 한 통신은 Qt가 간접적으로 신호를 내고 QMessageBox를 호출하여 내가 범인이라고 믿었습니다.

편집 4 :

좋아, 나는 처음부터이 문제를 둘러싼 가장 큰 신비를 언급하는 것을 잊었다. 기본적으로 워크 스테이션 (장소 B)에 ssh를 통해 작업 (Place A)하고 코드를 작성하고이 프로그램을 실행합니다. B는 2 개의 물리적 네트워크에 연결됩니다. A는 네트워크 1을 통해 B에 연결됩니다. 이제이 문제는 이 아니므로 A에서 터미널 (네트워크 1을 통해 ssh)에서 작업하는 동안에는 발생하지 않습니다. 하지만 네트워크 2를 통해 B에 직접 액세스하거나 ssh를 통해 액세스 할 때 일관되게 발생합니다. 코드가 B에서만 실행될 때마다 항상 유의하십시오. 이 두 네트워크는 hundereds에 의해 사용됩니다.

편집 5

마지막으로, 나는 인 QDialog을 하위 클래스라는 내가 정말 QMessageBox의 확장 된 기능을 필요로하지 않는 사용자 정의 메시지 박스를 만들어 내 문제를 해결했다. QMessageBox 내에서 정확히 어떤 문제가 발생했는지 아직도 알 수 없습니다. 나는 언제나 수수께끼로 남아있는 Qt 내의 버그를 가정합니다.

+2

코드가 없습니까? 쿠키는 어때? –

+1

우리가 1, 2 및 3을하고 있음을 모르는 경우에는 대답 할 수 없습니다. "QProcess를 부르지는 않았지만 프로그램이 깨졌습니다."우리에게별로 도움이되지 않습니다. – Phlucious

답변

1

어둠 속에서 조금 어둠 속에서 촬영하고있는 코드가 없기 때문에 QProcess가 의도적으로 스택에 만들어 졌거나 QThread가 너무 일찍 파괴 된 것처럼 들립니다. 내가 잘못 QThread 개체에 돈을 넣을거야. 문서가 (또는 최근까지) 엉망이 된 이후로 당신을 비난하는 것은 어렵습니다. this threadthis thread을 읽고 QThread를 하위 클래스로 만들지 마십시오.

편집 : QMessageBox가 원인 인 경우 하위 스레드에서 표시하고있는 것 같습니다. documentation에서 : 그것은 GUI 관련 작업을 수행 할 수있는 유일한 스레드이기 때문에

GUI 애플리케이션에서 주 스레드는 또한 GUI 스레드 이라고합니다.

하위 스레드의 메시지를 표시하는 방법에는 여러 가지가 있습니다. 개인적으로 qt의 오류보고 체계를 사용하고 qCritical, qDebug 등을 stderr으로 리디렉션합니다. 더 쉬운 방법은 GUI 스레드에 의해 잡힌 작업자 스레드의 QString 신호를 emit에 보내고 오류를 표시/수집합니다. 내 MainWindow에서 오류를 수집 한 다음 작업 스레드가 완료되면이를 모두 표시하도록하는 것이 좋습니다.

편집 2 : 문제가 QMessageBox되는 모달 것으로 보인다 때문에이 (즉, 작업자 스레드가 앞으로 이동하는 동안 메인 스레드를 차단), 쉽게 자사의 비 모달 모드에서 QMessageBox를 사용하여이 문제를 해결할 수 있습니다. 0을 QMessageBox 생성자/static 함수의 상위 위젯으로 전달하기 만하면됩니다. 사용자가 창을 종료 할 때까지 기다리지 않고 처리가 계속됩니다. 이로 인해 여러 메시지 상자가 동시에 열릴 수도 있습니다. 이렇게하면 오류를 방지하는 데 도움이되는 경우 코드를 자세히 검토하여 닫은 후에 창을 제대로 파괴했는지 확인할 수 있습니다.

+0

이 문제를 검토해 주셔서 고맙지 만 유감스럽게도 하위 클래스 QThread가 유일한 옵션 인 Qt4.2를 사용하면서 다른 접근 방식을 시도 할 수 없습니다. 코드를 작성하지 않아서 유감입니다. 회사 정책으로 인해 할 수 없으며 무엇을 넣을 지 모르기 때문에. – theta

+0

귀하의 질문을 편집과 함께 검토했습니다. 위의 편집 내용을 참조하십시오. – Phlucious

+0

불행히도 나는 그 문제를 직접적으로 생각하지는 않지만, 내가 직면 해 왔던 문제의 행동 때문에 Qt 내에서이 개념과 어떻게 든 관련 될 수있다. – theta