进程的概念:
程序:例如xxx.py这是程序,是一个静态的
进程:一个程序运行起来后,代码+用到的资源称之为进程,他是操作系统分配资源的基本单元
不仅可以通过线程完成多任务,进程也是可以的
进程的状态:
工作中,任务数往往大于cpu的核数,即一定有一些任务正在执行,而另一些任务在等待cup进行执行,因此导致了有了不同的状态
就绪态:运行的条件都已经慢去,正在等在cpu执行
执行态:cpu正在执行其功能
等待态:等待某些条件满足,例如一个程序sleep了,此时就处于等待态
进程、线程对比
(1、一个程序至少有一个进程,一个进程至少有一个线程
(2、线程的划分尺度小于进程(资源比进程少),使得多线程程序的并发行高
(3、进程在执行过程中拥有独立的内存单元,而多个线程共享进(进程所分配的资源)内存,从而极大地提高了程序的运行效率
创建进程-multiprocessing模块
1、 由于python是跨平台的,自然应该提供一个跨平台的多进程支持。Multiprocessing模块就是跨平台版本的多进程模块
2、 Multiprocessing模块提供了一个Process类来表示一个进程对象,创建子进程时,只需要传入一个执行函数和函数的参数,创建一个Process实例,用start()方法启动,join()方法可以等待子进程结束后在继续往下运行,通常用于进程间的同步
Process语法结构
Process([group[,target[,name[,args[,kwargs]]]]])
target:如果传递了函数的引用,可以任务这个子进程就执行这里的代码
args:给target指定的函数传递的参数,以数组的方式传递
kwargs:给target指定的函数传递命名函数
name:给进程设定一个名字,可以不设定
group:指定进程组,大多数情况下用不到
Process创建的实例对象的常用方法:
start():启动子进程实例(创建子进程)
is_alive():判断主进程子进程是否还在活着
join([timeout]):是否等待子进程执行结束,或等待多少秒
terminate():不管任务是否完成,立即终止子进程
Process创建的实例对象的常用属性:
name:当前进程的别名,默认为Process-N,N为从1开始递增的整数
pid:当前进程的pid(进程号)
实例2- 打印进程pid
import multiprocessing
import os
import time
def run_proc():
"""子进程要执行的代码"""
# os.getpid获取当前进程的进程号
print('子进程运行中,pid=%d...' % os.getpid())
print('子进程将要结束...')
if __name__ == '__main__':
# os.getpid获取当前进程的进程号
print('父进程pid: %d' % os.getpid())
p = multiprocessing.Process(target=run_proc)
p.start()
进程间不共享全局变量
多进程中,同一个变量,各自有一份拷贝存在于每个进程中,互不影响
from multiprocessing import Process
import os
import time
nums = [11, 22]
def work1():
"""子进程要执行的代码"""
print("in process1 pid=%d ,nums=%s" % (os.getpid(), nums))
nums.append(33)
time.sleep(1)
|
print("in process1 pid=%d ,nums=%s" % (os.getpid(), nums))
def work2():
"""子进程要执行的代码"""
print("in process2 pid=%d ,nums=%s" % (os.getpid(), nums))
nums.append(44)
time.sleep(1)
print("in process2 pid=%d ,nums=%s" % (os.getpid(), nums))
if __name__ == '__main__':
p1 = Process(target=work1)
p1.start()
p1.join()
p2 = Process(target=work2)
p2.start()
p2.join()
nums.append(55)
print("in main process pid=%d, nums=%s" % (os.getpid(), nums))
进程间通信:
Process之间有时需要通信,可以使用multiprocessing模块的Queue实现多进程之间的数据传递,Queue本身是一个消息队列程序
初始化Queue()对象时(例如:q=Queue()),若括号中没有指定最大可接收的消息数量,或数量为负值,那么就代表可接受的消息数量没有上限(直到内存的尽头);
n Process之间有时需要通信,可以使用multiprocessing模块的Queue实现多进程之间的数据传递,Queue本身是一个消息队列程序
n 初始化Queue()对象时(例如:q=Queue()),若括号中没有指定最大可接收的消息数量,或数量为负值,那么就代表可接受的消息数量没有上限(直到内存的尽头);
n Queue.qsize():返回当前队列包含的消息数量;
n Queue.empty():如果队列为空,返回True,反之False ;
n Queue.full():如果队列满了,返回True,反之False;
n Queue.get([block[, timeout]]):获取队列中的一条消息,然后将其从列队中移除,block默认值为True;
n Queue.put(item,[block[, timeout]]):将item消息写入队列,block默认值为True;
from multiprocessing import Process, Queue
import time
# 写数据进程执行的代码:
def write(q):
for value in ['A', 'B', 'C']:
print('Put %s to queue...' % value)
q.put(value)
|
time.sleep(1)
# 读数据进程执行的代码:
def read(q):
while True:
if not q.empty():
value = q.get(True)
print('Get %s from queue.' % value)
time.sleep(1)
else:
break
if __name__=='__main__':
q = Queue() # 父进程创建Queue,并传给各个子进程:
pw = Process(target=write, args=(q,))
pr = Process(target=read, args=(q,))
pw.start() # 启动子进程pw,写入:
pw.join() # 等待pw结束:
pr.start() # 启动子进程pr,读取:
pr.join()
print('所有数据都写入并且读完')