使用进程和线程
进程
创建进程
使用multiprocessing模块创建进程
Process([group [, target [, name [, args [, kwargs]]]]])
group:参数未使用,值始终未None
target:表示当前进程启动时执行的可调用对象
name:表示当前进程实例的别名
args:表示传递给target函数的参数元组
kwargs:表示传递给targe函数的参数字典
例:
form multiprocessing import Process
def test(interval):
print("我是子进程")
def main():
print("主进程开始")
p=Process(target=test, args = (1, ))
p.start()
print("主进程结束")
if __name__ == "main":
main()
- is_alive():判断进程实例是否还在执行
- join([timeout]):等待进程实例执行结束,等待多少秒
- start():启动进程实例
- run():如果没有给定target参数,对这个对象调用start()方法时,则执行对象中的run方法
- terminate():立即终止
- name:当前进程实例别名
- pid:当前进程实例的PID值
使用Process子类创建进程
对于简单任务,通常使用Process(target = test)方式实现多进程
处理复杂任务,通常定义一个类,继承Process类
from multiprocessing import Process
import time
import os
#继承Process类
class SubProcess(Process):
#重写了父类的__init__()方法
def __init__(self, interval, name = ""):
Process.__init__(self) #调用Process父类的初始化方法
self.interval = interval #追加了自己的内容
if name:
self.name = name
#重新了run()方法
def run(self):
t_start = time.time()
time.sleep(self.interval)
t_stop = time.time()
if __name__ = "__main__":
p1 = SubProcess(interval = 1, name = "mrsoft")
p2 = SubProcess(interval = 2)
p1.start() #启动进程p1
p2.start() #启动进程P2
p1.join() #等待p1进程结束
p2.join() #等待p2进程结束
使用进程池Pool创建进程
创建多个进程时,使用multiprocess模块中的pool类
- apply_async(func[, ags[, kwds]]):非阻塞方式调用func函数,args为传递func函数的参数列表,kwds为传递给func函数的关键字参数列表
- apply(func[, args[, kwds]]):阻塞方式调用func函数
- close():关闭pool,使其不再接收新任务
- terminate():立即终止
- join():主进程阻塞,等待子进程退出,必须在close或terminate之后使用
from multiprocessing import Pool
import os, time
def task(name):
print("子进程%s 执行task %s"%(os.getpid(), name))
time.sleep(1)
if __name__ = "__main__":
p = Pool(3)
for i in range(10):
p.apply_async(task, args(i,))
p.close()
p.join()
进程间通信
队列
先进先出
多进程队列的使用
可以使用multiprocessing模块的Queue实现多进程间的数据传递
- q = Queue(num):初始化,若num为0或负数,代表接收的消息数量没有上限
- q.qsize():返回当前队列包含的消息数量
- q.empty():判断队列是否为空,为空则返回True
- q.full():判断队列是否已满,已满则会True
- q.get([block[, timeout]]):获取队列中的消息,block默认是True
block = True && 未设置timeout:消息队列为空时阻塞在读取状态
block = True && 设置timeout:timeout时间若消息队列未空则抛Queue.Empty异常
block = False:消息队列未空则立刻抛Queue.Empty异常 - q.get_nowait():相当于q.get(False)
- q.put(item, [block[, timeout]]):将item消息写入队列,block默认时True
block = True && 未设置timeout:消息队列无空间可写时阻塞在写入状态
block = True && 设置timeout:等待timeout,如果还没有空间则抛Queue.Full异常
block = False:消息队列无空间可写时立即抛Queue.Full异常 - q.put_nowait(item):相当于q.put(item, False)
例:
from multiprocessing import Queue
if __name__ = "__main__":
q = Queue(3)
q.put("message1")
q.put("message2")
q.put("message3")
try:
q.put("message4", True, 2)
except:
print("Queue Full,count:%s"%q.qsize())
if not q.empty():
for i in range(q.size()):
print(q.get_nowait())
if not q.full():
q.put_nowait("message4")
使用队列在进程间通信
例:
from multiprocessing import Process, Queue
import time
def write_task(q):
if not q.full():
for i in range(5):
message = "msg" + str(i)
q.put(message)
def read_task(q):
time.sleep(1)
while not q.empty():
print(q.get(True, 2))
if __name__ = "__main__":
q = Queue()
pw = Process(target = write_task, args = (q, ))
pr = Process(target = read_task, args(q, ))
pw.start()
pr.start()
pw.join()
pr.join()
线程
创建线程
使用threading模块创建线程
Thread([group [, target [, name [, args [, kwargs]]]]])
- group:值恒为None
- target:表示一个可调用对象,线程启动时,run()方法将调用此对象
- name:表示当前线程名称
- args:表示传递给target函数的参数元组
- kwargs:表示传递给target函数的参数字典
例:
import threading, time
def process():
for i in range(3):
time.sleep(1)
priint("thread name is %s"%threading.current_thread().name)
if __name__ = "__main__":
threads = [threading.Thread(target = process) for i in range(4)] #创建4个线程,存入列表
for t in threads:
t.start() #开启线程
for t in threads:
t.join() #等待子线程结束
使用Thread子类创建线程
import threading, time
#创建子类SubThread,继承threading.Thread线程类,实例化线程,会自动调用父类的__init__()方法
class SubThread(threading.Thread):
def run(self):
for i in range(3):
time.sleep(1)
msg = "子线程" + self.name + str(i) #name中保存的是当前线程的名字
print(msg)
if __name__ = "__main__":
t1 = SubThread()
t2 = SubThread()
t1.start()
t2.start()
t1.join()
t2.join()
线程间通信
线程间共享全局变量
互斥锁
由于所有线程都可以随意更改全局变量,需要使用互斥锁,防止多个线程同时访问同一片内存
使用互斥锁
Lock类中有两个方法,acquire()锁定和release()释放
mutex = threading.Lock() #创建锁
mutex.acquire([blocking]) #锁定
mutex.release() #释放
使用队列在线程间通信
与进程中队列的使用方法相同
from queue import Queue
import random, threading, time
class Producer(threading.Thread):
def __init__(self, name, queue):
threading.Thread.__init__(self.name = name)
self.data = queue
def run(self):
for i in range(5):
print("%s, %d"%(self.getName(), i))
self.data.put(i)
time.sleep(random.random())
class Consumer(threading.Thread):
def __init__(self, name, queue):
threading.Thread.__init__(self, name = name)
self.data = queue
def run(self):
for i in range(5):
val = self.data.get()
print("%s, %d"%(self.getName(), val))
time.sleep(random.random())
if __name__ == "__main__":
queue = Queue()
producer = Producer("Producer", queue)
consumer = Consumer("Consumer", queue)
producer.start()
consumer.start()
producer.join()
consumer.join()