Python: Windows下用multiprocessing的深坑

今天在測試多進程時, 發現了一個問題html

測試代碼:python

#coding: utf8
from multiprocessing import Process 
import os 
print('Global_print', os.getpid())
def run_proc(name):

    print('Run child process %s (%s)…' % (name, os.getpid()))
if __name__=='__main__': 
    p = Process(target=run_proc, args=('test',)) 
    print(os.getpid()) 
    p.start()

上述代碼不復雜, 肉眼就能猜出八九分: 父進程來執行了首尾的兩個print, 而子進程則只執行run_proc ,linux

下面就這針對這一個猜想來驗證:segmentfault

LInux下,windows

'Global_print', 14382
14382
Run child process test (14383)…

很符合咱們的預期, 由於兩次os.getpid()獲得了同樣的結果, 而子進程的那句輸出也從側面驗證了另外兩句print是父進程執行的.centos

接下來看下Windows:安全

clipboard.png

What ???...黑人問號..這是什麼鬼..分分鐘被打臉...函數

在測試了debian/centos等等 unix/linux不一樣發行版和不一樣Python版本, 表現均爲一致, 也就是上面Linux的輸出.測試

然而..在Windows下也也是很頑固的和上面的輸出不一致..spa

總所周知, WindowsLinux在實現多進程上面是有點區別的..

因而, 感受應該是Windows自身的問題, 在諮詢了大佬以後, 得知官網早已有對這塊進行說明了:

傳送門: https://docs.python.org/2/lib...

摘抄資料以下:

clipboard.png

簡單的意思應該是下面這樣:

由於Windows缺少linix那種fork, 因此它會有一些額外的限制:

  • 無論是綁定仍是未綁定的方法, 都不要直接做爲參數傳給Process初始化的target, 相反應該要用普通的函數代替
  • 子進程在訪問全局變量時, 可能會與父進程的值不一樣. ( 模塊級別的常量沒這問題 )
  • 開啓新Python解析器或者建立新process時, 肯定主模塊可以安全的導入.

而剛纔的那個問題, 就是由於沒有注意到第三點, 因此致使了意想不到的的反作用, 應該用下面的寫法取代上面的不安全寫法:

from multiprocessing import Process, freeze_support

def foo():
    print 'hello'

if __name__ == '__main__':
    freeze_support()
    p = Process(target=foo)
    p.start()

果真..Windows無處不在都在挖坑....

歡迎各位大神指點交流, QQ討論羣: 258498217
轉載請註明來源: https://segmentfault.com/a/11...

相關文章
相關標籤/搜索