python 多線程和多進程的區別 mutiprocessing theading

多線程能夠共享全局變量,多進程不能。多線程中,全部子線程的進程號相同;多進程中,不一樣的子進程進程號不一樣。html

#!/usr/bin/python
# -*- coding:utf-8 -*-
import os
import threading
import multiprocessing
count_thread = 0
count_process = 0

# worker function
def worker1(sign, lock):
    global count_thread
    lock.acquire()
    count_thread += 1
    print(sign, os.getpid())
    lock.release()

def worker2(sign, lock):
    global count_process
    lock.acquire()
    count_process += 1
    print(sign, os.getpid())
    lock.release()
# Main
print('Main:',os.getpid())

# Multi-thread
record = []
lock  = threading.Lock()
for i in range(5):
    thread = threading.Thread(target=worker1,args=('thread',lock))
    thread.start()
    record.append(thread)

for thread in record:
    thread.join()

# Multi-process
record = []
lock = multiprocessing.Lock()
for i in range(5):
    process = multiprocessing.Process(target=worker2,args=('process',lock))
    process.start()
    record.append(process)

for process in record:
    process.join()


print count_thread
print count_process

運行結果python

('Main:', 3142)
('thread', 3142)
('thread', 3142)
('thread', 3142)
('thread', 3142)
('thread', 3142)
('process', 3148)
('process', 3149)
('process', 3150)
('process', 3151)
('process', 3152)
5
0數組

應該儘可能避免多進程共享資源。多進程共享資源必然會帶來進程間相互競爭。而這種競爭又會形成race condition,咱們的結果有可能被競爭的不肯定性所影響。但若是須要,咱們依然能夠經過共享內存和Manager對象這麼作。服務器

1) 共享內存網絡

用Python實現的例子:多線程

import multiprocessing

def f(n, a):
    n.value   = 3.14
    a[0]      = 5

num   = multiprocessing.Value('d', 0.0)
arr   = multiprocessing.Array('i', range(10))

p = multiprocessing.Process(target=f, args=(num, arr))
p.start()
p.join()

print num.value
print arr[:]

這裏咱們實際上只有主進程和Process對象表明的進程。咱們在主進程的內存空間中建立共享的內存,也就是Value和Array兩個對象。對象Value被設置成爲雙精度數(d), 並初始化爲0.0。而Array則相似於C中的數組,有固定的類型(i, 也就是整數)。在Process進程中,咱們修改了Value和Array對象。回到主程序,打印出結果,主程序也看到了兩個對象的改變,說明資源確實在兩個進程之間共享。app

2)Managerui

Manager對象相似於服務器與客戶之間的通訊 (server-client),與咱們在Internet上的活動很相似。咱們用一個進程做爲服務器,創建Manager來真正存放資源。其它的進程能夠經過參數傳遞或者根據地址來訪問Manager,創建鏈接後,操做服務器上的資源。在防火牆容許的狀況下,咱們徹底能夠將Manager運用於多計算機,從而模仿了一個真實的網絡情境。下面的例子中,咱們對Manager的使用相似於shared memory,但能夠共享更豐富的對象類型。.net

import multiprocessing

def f(x, arr, l):
    x.value = 3.14
    arr[0] = 5
    l.append('Hello')

server = multiprocessing.Manager()
x    = server.Value('d', 0.0)
arr  = server.Array('i', range(10))
l    = server.list()

proc = multiprocessing.Process(target=f, args=(x, arr, l))
proc.start()
proc.join()

print(x.value)
print(arr)
print(l)

Manager利用list()方法提供了表的共享方式。實際上你能夠利用dict()來共享詞典,Lock()來共享threading.Lock(注意,咱們共享的是threading.Lock,而不是進程的mutiprocessing.Lock。後者自己已經實現了進程共享)等。 這樣Manager就容許咱們共享更多樣的對象。線程

參考資料:

http://blog.csdn.net/zhaozhi406/article/details/8137670

http://www.xuebuyuan.com/1968817.html

相關文章
相關標籤/搜索