2013-03-30 5 views
1

나는 python python-wrapped C++을 호출 할 때 출력을 리디렉션하는 래퍼를 가지고 있습니다.파일 디스크립터를 삭제할 때 언제 flush()를 호출합니까?

기본적인 아이디어는 제가 C++에서 printf 출력을 잡을 수 있었던 유일한 방법입니다 dupdup2을 사용하는 것입니다. 랩퍼는 대화 형으로 작업을 실행하는 한에 대한 호출이 없어도 정상적으로 작동하지만 TORQUE 배치로 작업을 보내면 다시 반갑지 않은 결과를 얻습니다.

내 이해, this question에서 일부 잘 배치 된 flush() 호출은이 문제를 해결해야하지만 정확히 어디로 가야합니까? 내가 임시 파일에 dup'ing 전에 버퍼 플러시해야합니까? 전에 dup'ing하기 전에? 양자 모두? 다음


내가 사용 래퍼는 다음 TTY 연결된 경우

class Filter(object): 
    """ 
    Workaround filter for annoying and worthless errors. 
    """ 
    def __init__(self, veto_words={'ClassTable'}): 
     self.veto_words = set(veto_words) 
     self.temp = tempfile.NamedTemporaryFile() 
    def __enter__(self): 
     sys.stdout.flush() # <--- NEEDED? 
     sys.stderr.flush() # <--- NEEDED? 
     self.old_out, self.old_err = os.dup(1), os.dup(2) 
     os.dup2(self.temp.fileno(), 1) 
     os.dup2(self.temp.fileno(), 2) 
    def __exit__(self, exe_type, exe_val, tb): 
     sys.stdout.flush() # <--- NEEDED? 
     sys.stderr.flush() # <--- NEEDED? 
     os.dup2(self.old_out, 1) 
     os.dup2(self.old_err, 2) 
     self.temp.seek(0) 
     for line in self.temp: 
      veto = set(line.split()) & self.veto_words 
      if not veto: 
       sys.stderr.write(line) 

답변

2

파이썬 라인 버퍼링을인가 그렇지 않으면 큰 버퍼가 필요하다.

파이썬 프로그램을 파이프로 리디렉션한다는 것은 스트림에 TTY가 연결되어 있지 않음을 의미하며, 개행 문자를 보낼 때도 .flush()을 사용해야합니다.

-u과 함께 Python을 실행하여 stdout의 버퍼링을 해제 할 수 있습니다.

+0

내가 이해하지 못하는 것은'flush()'를 몇 번이나 호출해야하는지입니다. 내가 링크 된 예제는 _before_ duping이라고 불렀지 만, 원래의 out/error 스트림으로 버퍼 덤프를 피하기 위해 _back_ 스트림을 설정하기 전에 당신이'flush()'를 호출 할 것으로 기대했다. – Shep