2013-03-30 4 views
1

У меня есть оболочка для перенаправления выходов, когда я вызываю Python на Python-wrapped C++.Когда я вызываю flush() при дублировании файловых дескрипторов?

Основная идея заключается в использовании dup и dup2, которые являются единственными способами, которыми я смог поймать выходы printf из C++. Обертка отлично работает без вызовов flush(), пока я выполняю работу в интерактивном режиме, но когда я отправляю задание в пакет TORQUE, я снова получаю нежелательные выходные данные.

Мое понимание, частично от this question, заключается в том, что некоторые хорошо расположенные звонки flush() должны исправить это, но куда именно им нужно идти? Должен ли я сбросить буфер до, дублируя временный файл? Прежде чем окунуться в прошлое? И то и другое?


Обертка Я использую выглядит следующим образом:

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

Python применяет буферизацию линии при подключении к TTY, в противном случае больший буфер необходим.

Перенаправление программы Python на канал означает, что TTY не подключен к потоку, и вам придется использовать .flush() даже при отправке новых строк.

Вы можете запустить Python с -u, чтобы отключить буферизацию stdout.

+0

Я не понимаю, сколько раз мне приходится называть 'flush()'. Пример, связанный с ним, вызвал его _before_ duping, тогда как я ожидал бы, что вы вызовете 'flush()' перед установкой потока _back_, так как я хочу избежать сброса буфера в исходный поток out/error. – Shep

 Смежные вопросы

  • Нет связанных вопросов^_^