一、进程
1、linux下使用fork()函数创建多进程,调用fork()函数时,linux操作系统可以返回两个进程,一个是本身,一个是子进程;
import os
os .fork() #创建一个子进程
os.getpod() #得到子进程的进程号(os模块的一个方法)
os.getppid() #得到父进程的进程号
2、跨平台的多进程模块multiprocessing,该模块提供了一个Process类来代表一个进程对象
from multiprocessing import Process
import os
def run(name):
print("%s process=(%s)"%(name,os.getpid()))
print ('Parent process %s',%os.getpid()) #打印父进程的进程号
p=Process(target=run,args=('test',)) #创建一个子进程对象,该对象需传入执行函数及函数的参数;
p.start() #用start()方法启动进程,会执行函数的内容打印子进程的进程号
p.join() #join()方法可以等待子进程结束后再继续往下运行;
3、进程池Pool类批量创建子进程apply_async()方法
from multiprocessing import Pool
import os ,time,radom
def(name):
print('task %s(%s)'%(name,os.getpid()))
p = Pool(4) #创建一个Pool对象,Pool对象需传入参数,参数默认大小是CPU的核数
for i in range(5):
p.apply_async(run,args = (i,))
p.close() #进程池在调用join前,需先调用close,调用close后就不能添加新的Process了;
p.join() #调用join()方法会等待所有子进程执行完毕,程序才会继续往下运行;
4、subprocess模块启动子进程使用call()方法,以及communicate()方法
import subprocess
r.subprocess.call(['nslookup','www.python.org') #
print ('Exit code:',r)
import subprocess
p = subprocess.Popen(['nsloopup'],stdin=subprocess.PIPE,stdout=subprocess,PIPE,stderr=subprocess.PIPE)
output,err = p.communicate(b'set q=mx python.org exit ')
print(output.decode('utf-8'))
print('Exit code:',p.returncode)
5、进程间通信以Queue对象为媒介来交换数据;进程间通信还可以通过Pipes来实现;
from multiprocessing import Process Queue
import os, time,random
def write(q): #往Queue里写数据的函数
for value in ['A','B','C']:
print('Put %s to queue...'% value)
q.put(value)
def read(q): #从Queue里读数据的函数
while Ture:
value = q.get(Ture)
print('Get %s from queue.'% value)
q = Queue() #父进程创建Queue并传递给各个子进程;
pw = Process(target=write,args=(q,))
pr = Process(target=read,args=(q,))
pw.start() #启动子进程
pr.start() #启动子进程
pw.join() #等待pw结束
pr.terminate() #pr进程是死循环,无法等待其结束,只能强行终止
二、线程
1、threading模块创建多线程,current_thread()函数返回当前线程的实例,
import time,threading
def loop():
print('thread %s is running...'%threading.current_thread().name)
n=0
while n<5:
n=n+1
print('thread %s >>>%s'%(threading,current_thread().name,n))
time.sleep(1)
print('thread %s is running...'%threading.current_thread().name) #主线程
t = threading.Thread(target=loop,name='LoopThread') #子线程
t.start()
t.join()
print('thread %s ended.'% threading.current_thread().name) #主线程
2、threading.Lock()对象实现创建锁,acquire()方法获取锁,release()方法释放锁
import time,threading
balance = 0
block = threading.Lock() #创建锁
def change_it(n):
global balance
balance = balance + n
balance = balance - n
def run_thread(n):
for i in range(10000):
lock.acquire() #获取锁
try:
change_it(n)
finally:
lock.release() #释放锁
t1 = threading.Thread(target=run_thread,args=(5,))
t2 = threading.Thread(target=run_thread,args=(8,))
t1.start()
t2.start()
t1.join()
t2.join()
print(balance)
3、多核cpu
c 、c++、java 写多线程的死循环可以把核心跑满,但python不会,python解释器执行时有一个GIL锁,每执行100条字节码,解释器会释放GIL锁,让别的线程执行,再多的线程也只能用到1个核;
4、ThreadLocal变量是全局变量,但每个线程都只能读写自己线程的独立副本,互不干扰。ThreadLocal解决了参数在一个线程中各个函数之间互相传递的问题。
import threading
local_school = threading.local() #创建全局Threading.local对象
def process_student():
std = local_school.student # 获取当前线程关联的student
print('Hello,%s(in %s)' %(std,threading.current_thread().name))
def process_thread(name):
local_school.student = name #绑定ThreadLocal的student
process_student()
t1 = threading.Thread(target = process_thread,args=('Alice',),name='Thread-A')
t2 = threading.Thread(target = process_thread,args=('Bob'),name='Thread-B')
t1.start()
t2.start()
t1.join()
t2.join()