Control-C不停止线程/旋转光标



我有复制文件的代码。当它这样做时,光标旋转。这一切都很好。但是,如果我使用Ctrl+C来停止复制,我希望KeyboardInterrupt设置事件和光标停止旋转。复制停止,但是光标永远旋转,为什么?

我试着把一个打印到中断,没有得到显示,所以它似乎没有被调用?

def spinning_cursor(event):
      for j in itertools.cycle('/-|'):
          if not event.is_set():
              sys.stdout.write(j)
              sys.stdout.flush()
              time.sleep(0.1)
              sys.stdout.write('b')
          else:
              return

def copy_file(sfile, dfile, sync):
    processing_flag = Event()
    Thread(target = spinning_cursor, kwargs = {'event': processing_flag}).start()
    if os.path.exists(sfile):
        try:
            shutil.copyfile(sfile, dfile)
            processing_flag.set()
        except KeyboardInterrupt:
            processing_flag.set()
            pass
        ...

这不是一个真正的答案,因为我无法解释到底发生了什么,但我可以部分重现。看起来copy_file 吞下 KeyboardInterrupt并引发另一个异常。如果发生这种情况,由于processing_flag.set()只在正常和except KeyboardInterrupt分支中,控制永远不会传递到那里。因此,Event永远不会被设置,子线程继续旋转(这就是我所做的重现行为…)

工作区。

我可以找到两种可能的解决方法

  • 使用except不做任何过滤:

    try:
        shutil.copyfile(sfile, dfile)
        processing_flag.set()
    except:
        processing_flag.set()
        pass
    

    应该足以捕获copyfile

  • 引发的任何可能的异常
  • 使用finally块。我个人更喜欢这种方式,因为这确实是finally的目标:执行该分支,无论发生什么。在这种情况下,您甚至可以删除except块,只使用try:... finally:...:

    try:
        shutil.copyfile(sfile, dfile)
    finally:
        processing_flag.set()
    

最新更新