0

Я запускаю два потока python (import threading). Оба они заблокированы по вызову open(); на самом деле они пытаются открыть именованные каналы, чтобы писать в них, поэтому это нормальное поведение, чтобы блокировать, пока кто-то не попытается прочитать из именованного канала.Распространение системных вызовов в потоках

Короче говоря, это выглядит следующим образом:

import threading 

def f(): 
    open('pipe2', 'r') 

if __name__ == '__main__': 
    t = threading.Thread(target=f) 
    t.start() 
    open('pipe1', 'r') 

Когда я типа^C, то open() в основном потоке прерывается (поднимает IOError с Errno == 4).

Моя проблема: все еще ждут потоки t, и я хотел бы распространять поведение прерывания, чтобы заставить его поднять IOError.

+0

Что произойдет, если вы установите daemon = True в дочернем потоке перед его запуском? –

+0

Больше ничего. И цель моего вопроса - не убить нить, я бы хотел, чтобы он сделал кое-что (чистку) после получения сигнала. – deathiop

ответ

0

Я нашел это в питоне документации:
" ... только основной поток может установить новый обработчик сигнала, и основной поток будет только один для приема сигналов (это обеспечивается с помощью сигнального модуля Python , даже если реализация основного потока поддерживает отправку сигналов в отдельные потоки) .Это означает, что сигналы не могут использоваться как средство межпоточной связи. Вместо этого используйте блокировки. «
Возможно, вам также следует проверить эти документы:
exceptions.KeyboardInterrupt

library/signal.html

Еще одна идея - использовать select для чтения асинхронно в потоках. Это работает в Linux, не уверен в Windows (это не самая чистая или лучшая реализация):

#!/usr/bin/python 

    import threading 
    import os 
    import select 

    def f(): 
      f = os.fdopen(os.open('pipe2', os.O_RDONLY|os.O_NONBLOCK)) 
      finput = [ f ] 
      foutput = [] 
      # here the pipe is scanned and whatever gets in will be printed out 
      # ...as long as 'getout' is False 
      while finput and not getout: 
        fread, fwrite, fexcep = select.select(finput, foutput, finput) 
        for q in fread: 
          if q in finput: 
            s = q.read() 
            if len(s) > 0: 
              print s 

    if __name__ == '__main__': 
      getout = False 
      t = threading.Thread(target=f) 
      t.start() 
      try: 
        open('pipe1', 'r') 
      except: 
        getout = True 
Смежные вопросы