0x00 起
今天在寫一個小東西的時候,需要控制並發量,但又不能直接調用python multiprocessing(問題會在文后提到)。於是嘗試用Queue來實現。
最一開始的思路是這樣的:
from multiprocessing import Process from Queue import Queue q = Queue(maxsize = 10) # 通過web應用往隊列中添加數據 def put(num): q.put(num) def read(): while True: print q.get() if __name__ == '__main__': Process(target=read, args=())
隊列的數據,是從web應用中添加過來的(上面省略了bottle的代碼),開了一個進程,不斷從queue中讀取數據,並進行處理(省略了處理過程)。
邏輯是沒錯的,但是在實際測試的時候,發現一個問題。
Queue.get()函數是個默認阻塞的函數,如果隊列為空,會一直等待,類似於socket.recv。在測試的時候,程序一直卡在這里,也就是說read()函數並沒有讀到隊列中的數據。
0x10 承
為了解決驗證這個問題,我修改了一下代碼,打印相關的信息:
# encoding: utf-8 from multiprocessing import Process from Queue import Queue q = Queue(maxsize = 10) # 通過web應用往隊列中添加數據 def put(num): q.put(num) def read(): print q.qsize() # while True: # print q.get() if __name__ == '__main__': put(2333) print q.qsize() Process(target=read, args=()).start()
打印出來的結果是1 0。在新開的進程中的隊列,果然是空的。
去查了一下資料(http://my.oschina.net/yangyanxing/blog/296052),給出的解釋是:隊列對象不能在父進程與子進程間通信
0x20 轉
最后得知multiprocessing提供了Queue供調用,可完美解決這個問題。
# encoding: utf-8 from multiprocessing import Process, Queue q = Queue(10) # 通過web應用往隊列中添加數據 def put(num): q.put(num) def read(): while True: print q.get() if __name__ == '__main__': put(2333) print q.qsize() Process(target=read, args=()).start()
0x30 合
上面提到,在bottle中無法使用multiprocessing,稍微查了一下,給出的原因是線程中無法開進程。還沒太理解。