首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >Python中的多线程curses输出

Python中的多线程curses输出
EN

Stack Overflow用户
提问于 2018-07-13 06:23:29
回答 1查看 2.1K关注 0票数 3

我正在尝试为一个长时间运行的函数在进度条下面实现一个简单的微调工具(使用改编自this answer的代码)。

代码语言:javascript
复制
[########         ] x%
/ Compressing filename

我让压缩和进度条在我的脚本的主线程中运行,而微调在另一个线程中运行,所以它实际上可以在压缩发生时旋转。但是,我在进度条和微调器中都使用了curses,而且两者都使用curses.refresh()

有时终端会随机输出胡言乱语,我不确定为什么。我认为这是由于微调器的多线程特性,因为当我禁用微调器时,问题就消失了。

以下是微调器的伪代码:

代码语言:javascript
复制
def start(self):
  self.busy = True
  global stdscr 
  stdscr = curses.initscr()
  curses.noecho()
  curses.cbreak()
  threading.Thread(target=self.spinner_task).start()

def spinner_task(self):
  while self.busy:
    stdscr.addstr(1, 0, next(self.spinner_generator))
    time.sleep(self.delay)
    stdscr.refresh()

下面是进度条的伪代码:

代码语言:javascript
复制
progress_bar = "\r[{}] {:.0f}%".format("#" * block + " " * (bar_length - block), round(progress * 100, 0))
progress_file = " {} {}".format(s, filename)
stdscr.clrtoeol()
stdscr.addstr(1, 1, "                                                              ")
stdscr.clrtoeol()
stdscr.addstr(0, 0, progress_bar)
stdscr.addstr(1, 1, progress_file)
stdscr.refresh()

main()调用,如下所示:

代码语言:javascript
复制
spinner.start()
for each file:
  update_progress_bar
  compress(file)
spinner.stop()

为什么输出有时会损坏?是不是因为有单独的线程?如果是这样的话,有什么更好的设计方法的建议吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-07-13 10:02:14

如果这是您唯一使用curses模块的地方,最好的解决方案就是停止使用它。

您在这里真正使用的curses的唯一功能是它清除屏幕和移动光标的能力。这可以很容易地通过直接输出适当的控制序列来复制,例如:

代码语言:javascript
复制
sys.stdout.write("\x1b[f\x1b[J" + progress_bar + "\n" + progress_file)

\x1b[f序列将光标移动到1,1,\x1b[J清除从光标位置到屏幕末尾的所有内容。

不需要额外的调用来刷新屏幕,或者在完成后重新设置它。如果需要,您可以再次输出"\x1b[f\x1b[J"以清除屏幕。

诚然,这种方法确实假设用户正在使用VT100兼容的终端。但是,没有实现此标准的终端实际上已经绝迹,因此这可能是一个安全的假设。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51315269

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档