进程:一个具有独立功能的程序关于某个数据集合的一次运行活动。 是一堆资源的集合,进程的执行必须在线程的基础上。
进程中最少必须拥有一个线程。
进程与线程的区别?
(1)线程共享内存空间,进程的内存是独立的
(2)同一个进程的线程之间可以直接交流,两个进程想通信,必须通过一个中间代理来实现
(3)创建新线程很简单, 创建新进程需要对其父进程进行一次克隆
(4)一个线程可以控制和操作同一进程里的其他线程,但是进程只能操作子进程
(5)对主线程的修改有可能影响其他线程的运行,对一个父进程的修改不会影响子进程
进程知识点:
(1)进程的创建
创建多线程,单线程只需把for语句去掉
import multiprocessing,threading,os
import time
def run(name):
time.sleep(2)
print("****************************************")
print("module name :",__name__)
print("parent process :", os.getppid())
print("process id :", os.getpid())
print("process info:",multiprocessing.current_process())
print("threading info:",threading.current_thread())#进程里的主线程
print("[%s] is process"%name)#进程里创建子线程
print("****************************************")
t = threading.Thread(target=handle , args=(name ,))
t.start()
def handle(name):
print("[%s] is thread" % name)
print(threading.get_ident())
if __name__ =='__main__':
run('main')
for i in range(10):
p = multiprocessing.Process(target=run , args=(i,))
p.start()
(2)进程间的通信
A、进程队列
本质上是两个不同的列表,因为子进程创建的时候把父进程拷贝了一份,底层用pickle将子进程里的q序列化后放在一个两个进程都能碰到的地方, 然后父进程反序列化出来,从而实现了数据的交互。并不是修改同一份数据,只是完成了数据的传递。
import multiprocessing
def run(q):
q.put([42,None,'leo'])
print("child process :" , id(q))
if __name__ =="__main__":
q = multiprocessing.Queue()
p = multiprocessing.Process(target=run , args=(q,))
p.start()
print(q.get())
print("parent process :", id(q))
B、管道pies
import multiprocessing
def run(conn):
while True:
date = conn.recv()
print("sub process:%s\n"%date)
conn.send(date)
if __name__ =="__main__":
parent_conn,sub_conn = multiprocessing.Pipe()
p = multiprocessing.Process(target=run , args= (sub_conn,))
p.start()
while True:
com = input("from parent>>\n:")
parent_conn.send(com)
print("parent process :%s"%parent_conn.recv())
C、Manage
import multiprocessing,os
def run(i,d,l,lock):
lock.acquire() #锁
d[os.getpid()] = i
# l.append(os.getpid())
for a in range(1000):
l[0] +=1
print(l)
lock.release()
if __name__ =="__main__":
with multiprocessing.Manager() as manager:
# 相当于 manager=multiprocessing.Manager()
d = manager.dict()#生成一个字典,可在多个进程间共享和传递
l = manager.list(range(5))
p_list=[]
lock =multiprocessing.Lock()#进程锁,主要作用是输出屏幕的数据不乱
for i in range(10):
p = multiprocessing.Process(target=run , args=(i,d,l,lock,))
p_list.append(p)
p.start()
for i in p_list: #等待子进程执行完毕
i.join()
print(d)
print(l)
(3)进程池
进程池:进程太多,启动时开销太大,导致系统变慢。需要限制每次启动进程的个数。
必须先调用close()再调用join()
import multiprocessing,os,time
def run(i):
time.sleep(2)
print("[%s] is processing "%os.getpid())
return i+100,'xxxx'
def Bar(*args):#主进程调用回调
print('-->exec done:',args)
print('callback from :',multiprocessing.current_process())
if __name__ == '__main__':
pool = multiprocessing.Pool(processes=5) #允许进程池里同时放入5个进程
for i in range(10):#启动了10个进程,同一时间只有5个进程运行
# pool.apply(func=run , args=(i,))#同步执行,串行
#pool.apply_async(func=run, args=(i,)) # 异步执行,并行
pool.apply_async(func=run, args=(i,),callback=Bar) # 异步执行,并行,callback回调
print('end')
pool.close()
pool.join()#进程池中进程执行完毕后再关闭,如果注释,那么程序直接关闭。