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

时间:2016-09-28 12:01:52

标签: python multithreading

我有复制文件的代码。当它这样做时,光标旋转。一切正常。但是,如果我使用 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
        ...

1 个答案:

答案 0 :(得分:1)

这不是一个真正的答案,因为我无法解释究竟发生了什么,但我可以部分重现。看起来copy_file 吞下 KeyboardInterrupt并引发另一个异常。如果发生这种情况,因为processing_flag.set()仅在普通和except KeyboardInterrupt分支中,控制权永远不会通过那里。因此,事件永远不会被设置,并且子线程继续旋转(这是我为重现行为所做的...)

变通方法。

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

  • 使用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()