2013-12-15 5 views
2

나는 누군가가 약간의 빛을 발할 수 있기를 희망하는 이상한 문제가있다.패키징 및 mayavi와 관련된 Python 교착 상태가 발생합니까?

스크립트로 가득 찬 디렉토리로 시작한 복잡한 코드 조각이있어서 패키지로 다시 작업하기로 결정했습니다. 이 코드 변경은 이상한 교착 상태가 나타나는 원인이 된 것으로 보입니다.

다음은 문제의 표준 재생산을 시도한 것입니다. 이 코드는 예상대로 실행된다는 의미에서 실패합니다. 실제로 문제를 재현하려면 많은 코드가 필요할 수 있습니다. 하지만 상황에 맞지 않는 코드 스 니펫과 다른 점은 상상할 수 없습니다.

import numpy as np 
from scipy.sparse import csr_matrix 
from threading import Thread 

def dummy(): 
    print 'this is printed' 
    I = np.eye(3) 
    print 'all is still fine' 
    csr_matrix(I) 
    print 'this is never printed; csr_matrix appears to be a trigger for deadlock' 
    print np.ones(4) 
    print 'same problem; somehow, printing ndarrays is no longer cool either' 

thr = Thread(target=dummy) 
thr.start() 

아마도이 간결한 주석은 관련되어 있을까요? 나는 완전히, 우선 여기에 주요 모듈 이외의

http://docs.python.org/2/library/threading#importing-in-threaded-code 말했다되는 내용하지 않도록 감사하고, 수입은 해당 스레드를 기다리는 다음 새 스레드를 산란과의 부작용이 없어야합니다 어떠한 방식으로. 생성 된 스레드가 직접 또는 간접적으로 모듈 가져 오기를 시도하면이 제한 사항을 준수하지 못하면 교착 상태가 발생할 수 있습니다.

일부 컨텍스트 : 나는이 스레드를 mayavi/traitsui 스레드에서 생성하려고하는 python 2.7, numpy 1.8을 사용하고 있습니다. (관련성이 있어야하는 이유와 패키지 전에 잘 작동하는지 보지 않습니다. 구조,하지만 좋아). 또한, 생성 된 스레드에는 numpy/scipy 코드의 보트로드가있어 완벽하게 정상적으로 실행됩니다. 그것의 방금 인쇄 ndarrays 및 교착 상태에 대한 트리거로 입증 된 희소 행렬을 만드는.

mayavi 창이 닫히면 모든 교착 상태의 스레드가 다시 실행되기 때문에 mayavi와 약간의 상호 작용이 의심됩니다. 아마도 이러한 특정 명령문은 파이썬 스레드를 다시 mayavi 스레드로 반환하도록 트리거하지만 어떻게 든 포커스를 다시 얻지 못합니다.

이 수수께끼를 더 좁히는 데 도움이되는 힌트는 대단히 감사하겠습니다!

+1

문제는 아마도 여기에서 재현하지 않은 코드의 세부 사항과 관련이 있기 때문에 말하기는 어렵습니다. 이 쓰레드를'join()'하고 있습니까? 당신이 우리에게 준 예제에서와 같이 모듈의 최상위 레벨에서 시작 했습니까? 이 두 가지를 모두 수행한다면 문서의 주석에 따라 수행하지 말라고 말하는 것입니다. 모듈의 코드가 실행되는 동안 보유되는 전역 가져 오기 잠금이 있습니다. 그런 식으로'csr_matrix() '를 호출하면 가져 오기가 일어나므로 가져 오기 잠금을 획득하려고 시도합니다. 교착 상태가 발생합니다. 그러지 마. –

+0

도움에 감사드립니다. 이것이 내가 문서를 이해 한 방법이다. 그러나 나는 그 일을하지 않고있다. 나는 아무데도 합류하지 않는다. 아마 mayavi는 장면 뒤에서 어딘가에서 않습니다; 그러나 그것은 문서가 경고하는 것이 아닙니다.스레드는 사용자 입력에 대한 응답으로 UI 객체의 메서드에서 시작됩니다. 또한 csr_matrix는 오랫동안이 시점에서 다른 곳으로 가져 왔습니다. 캐시되어야하므로 가져 오기 잠금이 여전히 작동합니까? –

+0

또한; csr_matrix와 ndarray .__ repr__을 특별하게 만드는 것에 대한 단서가 있습니까? 왜 내 스레드가 코드를 통해 행복하게 행진합니까? 수확량이 희박하고 수입이 많지만,이 두 가지 기능 중 어느 것을 호출하든간에 일관되게 붙어 있습니까? –

답변

1

귀하의 의견에 따르면 자회사 모듈 중 하나의 최상위 레벨에서 UI 이벤트 루프를 시작한 것처럼 보입니다. 이는 문서에서 언급 한 것과 정확히 같은 문제를 일으키기 때문에 좋은 생각이 아닙니다. import foo은 결코 UI 이벤트 루프를 시작하지 않아야합니다. 문제는 메인 스레드가 가져 오기 잠금을 가져 와서 모듈 가져 오기를 처리한다는 것입니다. 이 모듈은 가져 오기를 완료하기 전에 UI 이벤트 루프를 시작합니다. 이것은 본질적으로 다른 스레드가 끝날 때까지 기다리는 것과 같은 상황입니다. UI 루프가 끝나기를 기다리고 있습니다. UI가 다른 스레드를 시작하면 주 스레드가 가져 오기 잠금을 계속 잡고 있기 때문에 다른 스레드에서 실행중인 코드는 아무것도 가져올 수 없습니다 (csr_matrix()ndarray.__repr__() 다른 모듈 가져 오기).

+0

나는 본다; configure_traits는 스레드를 생성 한 다음 기다리고, 문서에서 지정된대로 규칙을 위반합니다 (mayavi 문서가 강조한 경우 아프지 않습니다). 그러나, 내가 얻지 못하는 것은 함수의 매우 좁은 하위 집합을 사용할 때만 교착 상태가 발생한다는 것입니다 (다시 말하면, import와 함께 흩어져있는 수많은 코드가 문제없이 실행됩니다. 마야 비 스레드에서 둘 다 자식과 동일합니다). –

+0

나는 아직도 여기에서 무슨 일이 일어나고 있는지 완전히 이해한다고 말하며 나는 그 모든 것의 비옥함에 다소 실망한다고 말해야 만한다. 그러나 그것에도 불구하고, 조심스럽게 문서를 읽고 그들에게 붙어서 문제를 해결합니다. 앞뒤로 주셔서 감사합니다. 내가 결국 그것을 알아 냈다고해도, 아픈 사람이 이것을 대답으로 받아들입니다. –

+0

'configure_traits()'는 쓰레드를 생성하지 않습니다. UI 루프를 실행하기 만하면 UI 루프가 완료 될 때까지 돌아 오지 않습니다. 모든 UI 루프는 이와 같이 작동합니다. ['configure_traits()'(http://docs.enthought.com/traits/traits_api_reference/has_traits.html#traits.has_traits.HasTraits.configure_traits)의 문서는 이것을 알려줍니다. 스레드를 시작하기 전에 모듈 네임 스페이스로 가져온 모듈을 사용하는 것 외에'csr_matrix()'또는'ndarray .__ repr __()'do를 호출하는 것과 같이 쓰레드를 실제로 가져 오는 쓰레드는 아무것도 없다고 생각합니다. –

관련 문제