首先值得说明的是进程和线程的概念,程序是数据和有序指令的结合,是一个静态的概念,当程序在计算机中运行之后才有了动态的概念,而进程就是程序动态概念。进程是系统中分配资源的最小单位,一般情况下进程之间是相互独立的,多进程之间是不能进行数据共享的,在保护模式下,一个进程挂了,其他进程不会受到什么影响;线程是存在于进程中的,作为最小调度和执行的单位,较比进程需要的系统资源少很多,切换效率更高,但是一旦线程挂了,所对应的进程也会随之挂了,因此多进程程序比多线程程序具有更好的程序健壮性。
总结:无论多线程还是多进程都不是完美的,需要根据实际情况选择对应的,如果在多核执行机上建议使用多线程,而进程则可以跨机器迁移。
def run(name):
print('hello,', name)
time.sleep(1)
t = threading.Thread(target=run_thread,)
t.start()
if __name__ == '__main__':
for i in range(10):
process = multiprocessing.Process(target=run, args=('test',))
process.start() # 启动进程
process.join() # 等待进程结果
# 子进程不会影响主进程的全局变量
import multiprocessing
import time
import os
h = ['hello'] # 全局变量,主进程与子进程是并发执行的,子进程不能改变主进程中全局变量的值
def tt():
datalist = []
datalist.append(1)
datalist.append(2)
datalist.append(3)
time.sleep(3)
print("son", os.getpid(), datalist)
if __name__ == "__main__":
p = multiprocessing.Process(target=tt, args=())
p.start()
# p.join() # 顺序执行
print h # 全局变量不受影响
h.append("a")
h.append("b")
h.append("c")
print("parent", os.getpid(), h)
默认情况下不同进程的内存是不能共享的,如果要实现进程之间共享数据,需要加入进程中Queue,如下
from multiprocessing import Process, Queue
def f(q):
q.put([66666, None, 'hello word'])
if __name__ == '__main__':
q = Queue() # 把这个q传给了子线程
p = Process(target=f, args=(q,)) # 子线程访问父线程的q
p.start()
print(q.get())
p.join()
除了上面的Queue实现数据的共享还有Pipe, Manger()
from multiprocessing import Manager,Pipe,Process,os, Lock
def t(d,l):
d[os.getpid()] = os.getpid()
l.append(os.getpid())
if __name__ =='__main__':
# parent_cnn, child_cnn = Pipe() # 管道生成两个实例
with Manager() as manager:
d = manager.dict()
l = manager.list(range(10)) # 声明一个[0,1,2,3....,9]的列表
p_list = []
for i in range(5):
p = Process(target=t,args=(d,l))
# p.daemon = True
p.start()
p_list.append(p)
for j in p_list:
j.join()
print d # {11160: 11160, 11161: 11161, 11162: 11162, 11163: 11163, 11164: 11164}
print l # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11160, 11161, 11162, 11163, 11164]
from multiprocessing import Process, Pipe
def t(cnn):
cnn.send('aaa') # 发送数据
cnn.send(['bbb',1,None])
info = cnn.recv() # 接受数据
print info
cnn.close()
if __name__ == '__main__':
parent_cnn, child_cnn = Pipe()
for i in range(2):
p = Process(target=t,args=(child_cnn,))
p.start()
print parent_cnn.recv()
parent_cnn.send('vfdf')
p.join()
参考:https://www.onexing.cn