Python Curses窗口上的getch如果在另一个线程上,则不会返回KEY_RESIZE

2024-04-27 00:51:01 发布

您现在位置:Python中文网/ 问答频道 /正文

import curses, threading, sys

def thread():
    a = curses.initscr()
    curses.noecho()
    curses.cbreak()
    a.keypad(True)
    while True:
        char = a.getch()
        if char == curses.KEY_RESIZE: 
            print("key_resize", file=sys.stderr)
        else:
            print("other", file=sys.stderr)

threading.Thread(target=thread).start()

当我自己运行这个函数时,一切都很好——KEY_RESIZE被发送,一切都很好。当我从线程内部调用getch()时,问题就出现了——key事件似乎运行得很好(我还没有进行全面或全面的测试),但是key_RESIZE从来没有被发送出去。在

我是不是做错了什么事,或者有什么方法可以解决这个问题,这样不管线程如何,KEY_RESIZE都会被发送出去?在

我尝试过在线程内部和外部初始化屏幕,以及在python3.4.3上的两个不同的终端模拟器(gnome终端和konsole)上进行初始化。在

打印发送到stderr(它被重定向到另一个终端),因为诅咒会损坏屏幕输出。我也没有处理修复这个代码的终端,所以你需要重置它,使它恢复正常。在


Tags: keytrue终端stderrsys线程threadcurses
1条回答
网友
1楼 · 发布于 2024-04-27 00:51:01

通常,诅咒不是线程安全的。如果在一个线程中完成所有工作,就可以使curses应用程序正常工作。否则,你会有意想不到的行为。。。在

ncurses有一个编译时配置,它提供了基本的支持(即,一个更好的起点),但是您不太可能在预打包的形式中遇到它,尽管它是在几年前引入的(参见FAQOfficial releases)。在

进一步阅读:

在初始化期间,ncurses为SIGWINCH和其他一些函数添加信号处理程序。使用strace,我可以看到python正在捕获SIGWINCH并忽略它:

2722  <... futex resumed> )             = ? ERESTARTSYS (To be restarted if SA_RESTART is set)
2722   - SIGWINCH {si_signo=SIGWINCH, si_code=SI_KERNEL}  -
2722  rt_sigreturn({mask=[]})           = -1 EINTR (Interrupted system call)
2722  futex(0x7f94d4000c10, FUTEX_WAIT_PRIVATE, 0, NULL) = ? ERESTARTSYS (To be restarted if SA_RESTART is set)
2722   - SIGWINCH {si_signo=SIGWINCH, si_code=SI_KERNEL}  -
2722  rt_sigreturn({mask=[]})           = -1 EINTR (Interrupted system call)
2722  futex(0x7f94d4000c10, FUTEX_WAIT_PRIVATE, 0, NULL) = ? ERESTARTSYS (To be restarted if SA_RESTART is set)
2722   - SIGINT {si_signo=SIGINT, si_code=SI_KERNEL}  -
2722  rt_sigreturn({mask=[]})           = -1 EINTR (Interrupted system call)
2722  write(2, "Exception ignored in: <module 'threading' from '/usr/lib/python3.4/threading.py'>\n", 82) = 82
2722  write(2, "Traceback (most recent call last):\n", 35) = 35
2722  write(2, "  File \"/usr/lib/python3.4/threading.py\", line 1285, in _shutdown\n", 66) = 66
2722  open("/usr/lib/python3.4/threading.py", O_RDONLY|O_CLOEXEC) = 4 

因为python已经建立了一个信号处理程序,ncurses再也看不到SIGWINCH,也不会传递{}。假设这是在python中完成的,以缓解线程配置中的信号问题。在

或许相关信息:

相关问题 更多 >