线程与 Python 诅咒给我奇怪的字符?

Posted

技术标签:

【中文标题】线程与 Python 诅咒给我奇怪的字符?【英文标题】:Threading with Python Curses giving me weird characters? 【发布时间】:2018-03-28 04:00:51 【问题描述】:

嘿,堆栈溢出。我正在尝试构建一个测试脚本,该脚本应该在多行(随着时间的推移创建它们)上混合输出变化的字符(使用诅咒),根据线程号创建新行。 我有以下代码:

# -*- 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 的行,同时添加新的行做同样的事情。我该怎么做?在此先感谢:)

【问题讨论】:

只是一个想法,我不熟悉 stdscr 的东西,但是在这一行 stdscr.addstr(linePos, 0, "testing %s..." % i) 你不叫 str (一世)。你试过这样吗? @Jeff 是的,我有,它不会改变任何东西;不幸的是,仍然出现错误。 curses in python getstr() while refreshing的可能重复 Workaround for ncurses multi-thread read and write的可能重复 【参考方案1】:

即使您只在一个线程中使用 curses,其他处理繁重的线程也会破坏 curses 线程中的转义序列。环境变量$ESCDELAY 表示发送转义码(0x1B)后等待多长时间(以毫秒为单位);如果超过该时间,get_wch() 将返回^[ 击键 (ESC)。

【讨论】:

但是,OP 使用的是多个线程,所以这个答案没有用。【参考方案2】:

从多个线程打印到终端会给你这样的混合输出。这是race condition 的一个非常简单的例子。使用某种锁定机制来协调对终端的写入,或者确保只从一个线程写入(例如,使用 FIFO 将消息传递给写入线程,写入线程会将它们写入终端)。

您看到的奇怪数字是ANSI escape sequences 的一部分,程序使用这些数字来使用终端的特殊功能:例如,将\x1B[nF 写入输出将使您的终端将光标向上移动一行。 Curses 正在为您输出此类代码,并且由于终端根据 ANSI 含义对其进行解释,因此您通常看不到它们。但是因为多线程的问题,混合起来无效,一部分被打印到屏幕上。

【讨论】:

以上是关于线程与 Python 诅咒给我奇怪的字符?的主要内容,如果未能解决你的问题,请参考以下文章

在 Python 的类中生成一个数字给我一个奇怪的错误 [重复]

ajax 发布后的 Phpmyadmin 奇怪的字符

在 Kivy/Python 中作为线程运行时表现奇怪的函数

诅咒返回 AttributeError:“模块”对象没有属性“initscr”

Pycharm:如何启动标准终端(解决诅咒问题)

从Python中的字符串中删除奇怪的隐藏字符