1、多进程
A:Unix/Linux进程(windows不支持)
import os
# fork创建一个子进程
pid = os.fork()
# 子进程返回0
if pid == 0:
print 'this is child : %s ,parent:%s' % (os.getpid(),os.ppid())
else
print 'this is parent: %s' % os.getpid()
B:multiprocessing 夸平台支持多进程
#coding=utf-8
from multiprocessing import Process
import os
def myProc(name):
print 'processing name :%s :%s' %(name,os.getpid())
if __name__ == '__main__':
print 'Parent process : %s' % os.getpid()
# 创建一个进程
# target 进程启动时运行的方法,args第一个参数是进程名称
pro = Process(target=myProc,args=('test',))
pro.start() # 启动子进程 运行myPro方法
pro.join() # 子进程运行完后再往下执行
print 'end'
C:Pool 启动大量进程
from multiprocessing import Pool
import os,time,random
def myPro(name):
print 'Run task %s (%s)...' % (name, os.getpid())
start = time.time()
# 进程休眠
time.sleep(random.random() * 2) # 秒
end = time.time()
print 'Task %s runs %0.2f seconds.' % (name, (end - start))
if __name__ == '__main__':
# 设置同时可以运行多个进程,默认cpu个数
p = Pool()
for i in range(5):
# 创建进程,并运行进程
p.apply_async(myPro,args=(i,))
print '----------start-------------'
#time.sleep(30)
p.close() # 保证之后不再添加新的进程
p.join() # 子进程都结束后再运行下边的程序
print '----------end---------------'
D:进程之间的通信
# Pipes一对一通信,效率高,Queue基于Pipes,可以多对多通信
# 以Queue为例
from multiprocessing import Process,Queue
import os,time,random
# 写
def write(q,name):
for v in ['1','2','3','4','5','6','7','8','9','0']:
q.put(v)
print 'who: %s write %s' % (name,v)
time.sleep(random.random()*2)
# 读
def read(q,name):
while True: #时刻在读取Queue中数据
print 'who: %s read %s' % (name,q.get(True))
time.sleep(random.random()*1)
if __name__ == '__main__':
q = Queue()
# 写 进程
w = Process(target=write,args=(q,'w'))
# 读 进程
r = Process(target=read,args=(q,'r'))
w.start()
r.start()
w.join()
r.terminate() # 强制停止进程
2、多线程(进程中有一个或多个线程)
A:threading (对thread进行封装)
import time,threading
# 线程执行的代码
def mydef():
print 'who run : %s' % threading.current_thread().name
n = 0
while n < 5 :
n = n + 1
print 'thread %s --- %d' % (threading.current_thread().name,n)
time.sleep(1)
print 'end: %s' % threading.current_thread().name
if __name__ == '__main__':
t1 = threading.Thread(target=mydef,name='thread_1')
t2 = threading.Thread(target=mydef,name='thread_2')
t1.start()
t2.start()
t1.join()
t2.join()
B:Lock (线程锁,避免变量同时被多个线程操作)
import time,threading
number = 0
def change(n):
# 该数据同时被两个线程操作,造成数据的混乱
global number
number = number + n
number = number - n
def run(n):
for i in range(1000):
change(n)
print number ,'\n'
if __name__ == '__main__':
thread1 = threading.Thread(target=run,args=(5,))
thread2 = threading.Thread(target=run,args=(8,))
thread1.start()
thread2.start()
thread1.join()
thread2.join()
print number
# 使用 Lock() 实现变量的同步,将上边的run方法修改
# 即 全局变量的操作必须加锁
def run2(n):
for i in range(1000):
# 将该代码段锁住,是能同时被一个线程访问
lock.acquire()
try:
change(n)
finally:
# 释放线程锁
lock.release()
print number ,'\n'
C:多核CPU
多核可以同时执行多个线程。
但是在Python中,有GIL(Global Interpreter Lock)锁,故线程被上锁,是交替运行的。
所以,在多核CPU中运用线程是徒劳的。
3、ThreadLocal
在线程中, 局部变量的传递是通过方法的参数传递的,但是调用多层的方法时,会很麻烦。
使用ThreadLocal可以解决局部变量传递的问题。
import threading
# local是一个dict 键值对
local = threading.local()
def run(name):
# 设置传递局部变量参数
local.name = name
# 因为是局部变量,所以不需要设置锁
for i in range(1000):
addB()
def addB():
# 获取局部变量参数
name = local.name + '+B'
print '%s = %s \n' % (threading.current_thread().name,name)
if __name__ == '__main__':
p1 = threading.Thread(target=run,args=('p1',),name='thread_1')
p2 = threading.Thread(target=run,args=('p2',),name='thread_2')
p1.start()
p2.start()
p1.join()
p2.join()