2014-04-17 20 views
5

我必須在Python 2.7中編寫一個類,並且我有一些問題。 我來自一個Java的背景,得知蟒蛇最近相當Python的等效Java的函數wait(),notify(),同步

這裏是什麼,如果我必須用Java做我會寫

public class CommandSender extends Thread { 
    private boolean isTimeOut; 
    private boolean running; 
    private ArrayList<Command> waitingList; 

    public CommandSender() { 
     running = false; 
     waitingList = new LinkedList<Command>(); 
     isTimeOut = false; 
    } 

    public void run() { 
     running = true; 
     while (running) { 
      synchronized (this) { 
       while (waitingList.isEmpty() && running) { 
        try { 
         wait(); 
        } catch (InterruptedException ie) { 
         ie.printStackTrace(); 
        } 
        } 
        while (!waitingList.isEmpty() && running) { 
         currentCmd = waitingList.remove(0); 
         // doSomething(currentCmd) 
        } 
      } 
     } 
    } 

    public synchronized void sendCommand(Command cmd) { 
     waitingList.add(cmd); 
     notify(); 
    } 

    public synchronized boolean isTimeOut() { 
     return isTimeOut; 
    } 
} 

我有什麼一時

class CommandSender(threading.Thread) 

    def __init__(self): 
     threading.Thread.__init__(self) 
     self.waiting_list = [] 
     self.running = False 
     self.is-time_out = False 
     self.my_lock = threading.Lock() 

    def run(self): 
     self.running = True 
     with self.my_lock: 
      while len(self.waiting_list) == 0 and self.running: 
       # Don't know what I have to do here 
      while len(self.waiting_list) != 0 and self.running: 
       # Do my stuff 

    def send_command(self, cmd): 
     with self.my_lock: 
      self.waiting_list.append(cmd) 
      # Notify ? 

    def is_time_out(self): 
     with self.my_lock: 
      return self.is_rime_out 

做我使用的每個實例都有一個鎖,因爲有CommandSender

只有一個實例那麼怎麼辦等待/通知過程?我的同步塊是否很好用?

謝謝!

+0

一個側面說明:我個人認爲這是一個更好的模式來使用鎖定對象(無論語言),而不是同步整個對象。否則,如果您的對象用於外部同步,將導致奇怪的結果。 – Krumelur

回答

3

首先,您應該意識到Python的global interpreter lock不會允許多個線程同時運行Python代碼(儘管線程可以運行例如C代碼,例如,如果使用本地代碼模塊釋放GIL適當地)。如果您需要使用Python代碼使用多核CPU,請查看multiprocessing模塊。現在

,直接相當於是threading.Event類。創建一個對象,然後使用waitset

1

這聽起來像一個簡單的生產者 - 消費者隊列。在Java中,您應該考慮使用ConcurrentLinkedQueue。在Python中,您可以使用Queue.Queue類用於線程化程序,而multiprocessing.Queue類可用於使用multiprocessing的程序。

除非這是功課,你需要使用一些特定的鎖定機制來實現自己的代碼。我知道實現生產者 - 消費者隊列的最簡單方法是使用兩個或三個信號量:

  • 一個信號量來計算隊列中元素的數量。最初爲零。
  • 一個信號量,用於計算隊列中元素的限制/最大數量,用此最大數量進行初始化。如果你不需要有限的隊列,這是可選的。
  • 共享訪問內部隊列/鏈接列表的一個信號量,互斥鎖或關鍵部分。在Python中,這不是線程程序所必需的,因爲GIL允許您將元素添加到列表中而無需同步線程。
+0

它是,但生產者和消費者在與主程序不同的同一個線程中。 基本上我的主程序做的事情,而CommandSender發送命令時,它可以。 – Zycho

+0

@Zycho問題是什麼?謹慎闡述?您可以從同一個線程添加和刪除隊列中的元素。 – vz0

相關問題