嘿,堆栈溢出。我试图建立一个测试脚本,应该混合输出变化的字符(使用诅咒)在多行(创建他们随着时间的推移),创建新的行基于线程数。我有以下代码:
# -*- coding: utf-8 -*-
import curses, time, threading
def threadedFunction(linePos):
stdscr = curses.initscr()
curses.noecho()
curses.cbreak()
try:
stdscr.clear()
for i in range(50):
stdscr.addstr(linePos, 0, "testing %s..." % i)
stdscr.refresh()
time.sleep(.1)
finally:
curses.echo()
curses.nocbreak()
curses.endwin()
pass
pass
if __name__ == "__main__":
for x in xrange(0, 4): # should produce 5 lines maximum
exec("process" + str(x) + " = threading.Thread(target = threadedFunction, args = (" + str(x) + ",))")
exec("process" + str(x) + ".start()")
我以前试过使用multithreading
库,但是我对它不抱希望。线程库至少会在它发疯之前在几行上显示我想要的数字。下面是我运行它时的一个示例:
所有我想要的是程序只是简单地开始一个新的线程,并显示一行计数到50,同时添加新行做同样的事情。我该如何着手做这件事??提前感谢:)
3条答案
按热度按时间ohfgkhjo1#
从多个线程打印到终端会给予这样的混合输出。这是race condition的一个非常简单的例子。使用某种锁定机制来协调对终端的写入,或者确保只从一个线程写入(例如,使用FIFO将消息传递到写入线程,该线程将消息写入终端)。
您看到的奇怪数字是ANSI转义序列的一部分,程序使用这些转义序列来使用终端的特殊功能:例如,将
\x1B[nF
写入输出将使终端将光标向上移动一行。curses为您输出这样的代码,因为终端根据ANSI含义解释它们,所以您通常看不到它们。但是由于多线程问题,这些代码变得混合和无效,其中一部分被打印到屏幕上。w8f9ii692#
即使您只在一个线程中使用curses,其他处理繁重的线程也可能中断curses线程中的转义序列。环境变量
$ESCDELAY
指示转义码(0x 1B)发送后等待的时间(以ms为单位);如果超过该时间,get_wch()返回^[
击键(ESC)。ifsvaxew3#
使用
stdscr.noutrefresh()
代替stdscr.refresh()
,然后在处理更新的指定线程中调用curses.doupdate()
,其思想是只在一个线程中执行curses.doupdate()
。