【问题标题】:Preventing race condition with ncurses+python使用 ncurses+python 防止竞争条件
【发布时间】:2014-05-27 14:50:16
【问题描述】:

我遇到了和这篇文章类似的问题

C, junk appearing on screen using curses

但是,我使用的是 python。我编写了一个包装器 Screen 类,它以更方便的方式包装了 curses 模块。我有一个像这样的getch

def getKeyCode(self):                                                                                                                         
    with self._curses_lock:                                                                                                                   
        self._curses_screen.nodelay(False)                                                                                                    

    c = self._curses_screen.getch()                                                                                                           
    if c == 27:                                                                                                                               
        with self._curses_lock:                                                                                                               
            self._curses_screen.nodelay(True)                                                                                                 
        next_c = self._curses_screen.getch()                                                                                                  

        with self._curses_lock:                                                                                                               
            self._curses_screen.nodelay(False)                                                                                                

    return c          

以及归结为这一点的写作

        with self._curses_lock:                                                                                                               
            self._curses_screen.addstr(y, x, out_string, attr)

getKeyCode 由一个单独的 python 线程调用,该线程大部分时间都在 getch 中等待,当按下某个键时,它会被添加到队列中。在另一个(主)线程上,我有一个事件循环,它从队列中获取事件、执行重绘和刷新屏幕。

我知道 ncurses 保持共享状态,我添加了一堆 threading.Locks 以防止竞争条件,但是如果我一直按下箭头键,有时我会得到垃圾。 我猜这是由于 getch 在 ncurses 中被释放,而另一个线程正在重新绘制。这会弄乱重绘的状态,产生奇怪的结果。我显然不能让我的 getKeyCode 线程持有锁,因为这意味着在 getch 返回之前完全阻止重新绘制,我也不希望 getch 非阻塞,因为我会 1) 不能真正解决问题和2) 有一个线程不断运行,这会将 CPU 使用率提高到 100%。我该如何解决这个问题?

【问题讨论】:

    标签: python multithreading ncurses curses


    【解决方案1】:

    我解决了这个问题,就像这样。我用

    设置了 getch 非阻塞
    self._curses_screen.nodelay(True) 
    

    然后我不在 curses 中等待,而是在标准输入上进行选择。 When the select returns, some stuff is available and I can lock and get exclusive access to the ncurses backend, guaranteed that I will return immediately with what's available and release the lock.

    def getKeyCode(self):                                                                                                                         
        select.select([sys.stdin], [], [])                                                                                                        
    
        with self._curses_lock:                                                                                                                   
    
            c = self._curses_screen.getch()                                                                                                       
            if c == 27:                                                                                                                           
                next_c = self._curses_screen.getch()                                                                                              
    
        return c
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-02-23
      • 2016-12-10
      相关资源
      最近更新 更多