2014-04-13 27 views
1

防止競爭條件我有一個類似的問題在這個崗位與ncurses的+蟒蛇

C, junk appearing on screen using curses

不過,我使用python。我編寫了一個包裝器Screen類,以更方便的方式封裝了curses模塊。我有這樣

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線程調用寫,當一個鍵被按下,它被添加到隊列中。在另一個(主)線程中,我有一個事件循環,從隊列中獲取事件,執行重繪並刷新屏幕。

據我知道的ncurses持有共享狀態,我加了一堆threading.Locks,以防止競爭條件,但如果我按住方向鍵,偶爾我得到的垃圾。 我想這是由於getch在從另一個線程進行重新繪製時在ncurses中釋放的原因。這擾亂了重繪的狀態,給出了奇怪的結果。我顯然不能有我getKeyCode線程持有鎖,因爲這將意味着,以防止重畫的所有,直到殘培回報,我也希望有一個殘培無阻塞的,因爲我會1)不能真正解決問題, 2)有一個不斷運行的線程,可以將CPU使用率提高到100%。我怎麼解決這個問題?

回答

1

我解決了這個問題。我設置getch nonblocking與

self._curses_screen.nodelay(True) 

然後我做的不是在curses裏面,而是在選擇標準輸入。當select返回時,有些東西可用,我可以鎖定並獲得對ncurses後端的獨佔訪問權限,保證我將立即返回可用的內容並釋放鎖定。

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