python多线程,不适合cpu密集操作型的任务,适合io操作的密集型的任务
io操作不占用cpu(硬盘读数据,网络读数据...),计算占用cpu
多进程
import multiprocessing
import time,threading
def thread_run():
print('进程号:',threading.get_ident())
def run(name):
time.sleep(2)
print('hello', name )
t = threading.Thread(target=thread_run,) #在进程中又启动线程
t.start()
if __name__ == '__main__':
for i in range(10):
p = multiprocessing.Process(target=run, args=('wangteng %s' %i,))
p.start()
#p.join()
分析进程id
from multiprocessing import Process
import os
def info(title):
print(title)
print('module name:', __name__) #模块名
print('parent process:', os.getppid()) #父进程id
print('process id:', os.getpid())
print('\n\n')
def f(name):
info('\033[31;1m called from child process function f\033[0m') #调用info,在子进程中调用
print('hello', name)
if __name__ == '__main__':
info('\033[32;1m main process line \033[0m')
p = Process(target=f,args=('wangteng',)) #调用f
p.start()
p.join()
进程间的通信,进程之间相互独立。要想实现通信:(Queues,Pipes实现进程之间的数据传递),manager实现进程之间的数据传递共享
进程queue
from multiprocessing import Process,Queue
#从表面上看,是一个queue,但其实相当于克隆了queue,序列化与反序列化中间件实现了不同进程之间的通信
def f(q):
q.put([42,None,'hello'])
if __name__ == '__main__':
q = Queue() #进程queue
p = Process(target=f,args=(q,))
p.start()
print(q.get()) #print "[42, None , 'hello']"
p.join()
pipe管道
from multiprocessing import Process, Pipe
def f(conn):
conn.send([42,None,'HELLO from child'])
conn.send([42, None, 'HELLO from child2'])
print('from parent:',conn.recv()) #接受来自parent_conn
conn.close()
if __name__ == '__main__':
parent_conn, child_conn = Pipe() #创建管道,管道有两头,这两头可以定义互通
p = Process(target=f,args=(child_conn,)) #实例化一个进程,进入f
p.start()
print(parent_conn.recv()) #print '[42, None ,'hello']' 接收
print(parent_conn.recv())
parent_conn.send("你可安好?") #发送 由parent_conn发给child_conn
p.join() #等待
manager
from multiprocessing import Process,Manager
import os
def f(d,l):
#d[1] = '1'
#d['2'] = 2
#d[0.25] = None
d[os.getpid()] = os.getpid()
l.append(os.getpid())
print(l)
if __name__ == '__main__':
with Manager() as manager: #相对于赋了一个变量
d = manager.dict() #生成一个可在多个进程之间传递和共享的字典
l = manager.list(range(5)) #默认里面有五个数据的列表 生成一个可在多个进程之间传递和共享的列表
p_list = [] #空列表
for i in range(10):
p = Process(target=f, args=(d, l)) #实例化
p.start()
p_list.append(p) #添加到列表中
for res in p_list: #等待结果
res.join()
print("------------------------")
print(d)
print(l)
进程池 (相当于有多少进程同一时间在CPU上运行)
进程池中有两个方法:apply : 串行
apply_async : 并行
from multiprocessing import Process,Pool
import time,os
def Foo(i):
time.sleep(2)
print('in process:',os.getpid())
return i+100
def Bar(arg):
print('--->exec done:',arg,os.getpid())
if __name__ == '__main__': #如果是手动执行,就会执行下面的内容,通过模块导入就不会执行下面内容
pool = Pool(processes=5) #允许进程池同时放入5个进程
print("主进程:" ,os.getpid())
for i in range(10):
#pool.apply(func=Foo, args=(i,)) #串行
#pool.apply_async(func=Foo, args=(i,)) #并行
pool.apply_async(func=Foo, args=(i,), callback=Bar) #callback=回调,执行完func后再调用callback 好处是进程是由主线程启的
print('end')
pool.close()
pool.join() #进程池中近程执行完毕后在关闭,如果注释,那么程序直接关闭