1.多进程
针对unix/linux操作系统会提供一个fork()系统调用,其调用一次,返回两次,因为操作系统自动把当前文件复制了一份,称为父进程和子进程
子进程永远返回0,而父进程返回子进程的ID,这样一个父进程可以fork出很多子进程,so父进程要记下每个子进程的ID,而子进程通过调用getppid()拿到父进程的ID
python中的os模块封装了常见的系统调用,其中包括fork
1)Mutiprocessing
跨平台版本的多进程模块,提供process类来代表一个进程对象
from multiprocessing import Process
import os
#子进程要执行的代码
def run_proc(name):
print("run child process %s(%s)..."%(name,os.getpgid()))
if _name_== '_main_':
print(("parent process %s"%os.getpgid()))
p = Process(target=run_proc,args=("test",))
print("child process will start")
p.start()
p.join()
print("child will end")
2)pool
如果启动大量的子进程,可以用进程池的方式批量创建子进程
from multiprocessing import Process
import os,time,random
#子进程要执行的代码
def long_time_task(name):
print("run child process %s(%s)..."%(name,os.getpgid()))
start=time.time()
time.sleep(random.random()*3)
end=time.time()
print("Task %s runs %0.2f seconds"%(name,(end-start)))
if _name_=='_main_':
print(("parent process %s"%os.getpgid()))
p = pool(4)
for i in range(5):
p.apply_async(long_time_task,args=(i,))
print("waiting for all subprocesses done")
p.start()
p.join()
print("All subprocesses done")'
3)子进程
subprocess模块可以方便的启动一个子进程
import subprocess
print("$ nslookup www.python.org")
r = subprocess.call(["nslookup","www.python.org"])
print("Exit code",r)
如果子进程还需要输入,则可以通过communicate()方法输入
import subprocess
print("$ nslookup")
p = subprocess.Popen(["nslookup"],stdin = subprocess.PIPE,stdout = subprocess.PIPE,stderr = subprocess.PIPE)
output,err = p.communicate(b'set q=mx\npython.org\nexit\n')
print(output.decode("utf-8"))
print("Exit code",p.returncode)
4)进程间通信
process之间需要通信,python的multiprocessing模块包装了底层的机制,提供了Queue\Pipes等多种方式来交换数据
以Queue为例,一个往Queue里面写入数据,一个从Queue里面读数据
def read(q):
print("process to read:%s"%os.getpgid())
while True:
value = q.get(True)
print("get %s from queue"%value)
if _name_ = "main_":
q =Queue()
pw =Process(target = write,args=(q,))
pr = Process(target=read,args=(q,))
pw.start()
pr.start()
pw.join()
pr.terminate()
2.多线程
python提供了连个模块,一个是_thread和threading,前者是低级模块,后者是高级模块,高级模块对低级模块进行了封装,绝大多数我们使用高级模块
import time,threading
def loop():
print("thread in 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 ended"%threading.current_thread().name)
print("thread %s is runing"%threading.current_thread().name)
t = threading.Thread(target=loop,name = "Looptaread")
t.start()
t.join()
print("thread %s ended"%threading.current_thread().name)
1)lock
多线程和多进程的最大区别在于,多进程中每一个变量都有各自的备份,备份在每一个进程中,互不影响,而在多线程中,所有变量由所有线程共享,线程之间共享的问题在于多个线程同时更改一个变量,我们用锁实现,即threading_lock
import threading
balance = 0
lock = threading.Lock()
def run_thread(n):
for i in range(1000):
#先获取锁
lock.acquire()
try:
change_it(n)
finally:
#释放锁
lock.release()