子进程的创建:
pro = multiprocessing.Process(target=子进程需要执行的方法名, args="给子进程传递的参数")
执行子进程:
pro.start()
终止子进程的方法:
pro.terminate() terminate()方法不是立即终止进程,而是通过这个方法,通知cpu终止这个进程,具体什么时间终止这个进程,要看cpu调度什么时候执行这个任务,所以,一般在调动terminate()方法后,都会份上time.sleeo(0.1),是主进程睡眠一段时间,等待cpu执行终止进程的任务.以保证进程终止
等待所有进程执行完成的方法:
pro.join()
import multiprocessing
import os
import time
def func(*str1):
print("这是一个子进程")
# 获取本身的进程的id
print(os.getpid())
# 获取父进程的id
print(os.getppid())
# 打印父进程传递过来的参数
print(str1)
def func2(**kwargs):
print("这是一个子进程")
# 获取本身的进程的id
print(os.getpid())
# 获取父进程的id
print(os.getppid())
# 打印父进程传递过来的参数
print(kwargs)
if __name__ == '__main__':
# 创建一个子进程执行计划
pro = multiprocessing.Process(target=func, args=("给子进程传递的参数",))
pro2 = multiprocessing.Process(target=func2, kwargs={"参数1": "德玛西亚", "参数2": 4564})
# 创建字进程并执行子进程
pro.start()
pro2.start()
# 打印子进程的名字
print("子进程的名字%s" % pro.name)
# 判断子进程是否存活
print("子进程是否存活%s" % pro.is_alive())
# 直接终止子进程
pro.terminate()
pro.join()
# time.sleep(0.1)
print("子进程是否存活%s" % pro.is_alive())
# 调用terminate()方法终止子进程死活,不是立即终止,调用这个方法,通知cpu终止这个进程,
# 但是CPU可能等待一会才能终止进程
# 所以一般在调用terminate()方法后跟上sleep(0.1)使主进程睡眠一小段时间,等待CPU执行
# 或者调用join()方法,阻塞等待子线程终止.
# 对于一个操作系统来说,运行很多进程,每个进程都有一个随机的进程号 PID process identify
# 如果需要在进程内部打印出本进程的PID,使用os模块的os.getpid()
print(os.getpid())
# 阻塞等待子进程执行完成,同等待子线程执行完成方法相似"
pro.join()
print("子进程执行完成,打印这句话")
二.进程间不共享全局数据,进程相当于另一个程序,不会共享数据
import multiprocessing
import time
g_number = 10
def worker1(num):
global g_number
g_number += num
while True:
print("全局变量等于%d" % g_number)
if __name__ == '__main__':
pro1 = multiprocessing.Process(target=worker1, args=(100,))
pro2 = multiprocessing.Process(target=worker1, args=(20,))
pro1.start()
pro2.start()
三.多进程拷贝文件
import os
import multiprocessing
import time
def copy_file(file_name, src_path, dest_path, queue):
# 根据文件名打开文件,读取文件
src_file = open(src_path+"/"+file_name, "rb")
# 打开目的文件目录下文件,写入
dest_file = open(dest_path+"/"+file_name, "wb")
# 读取源文件
file_data = src_file.read()
# 写入文件
dest_file.write(file_data)
# 关闭流
src_file.close()
src_path.close()
# 将拷贝完的文件名放入对列,用于线程间通信
queue.put(file_name)
if __name__ == '__main__':
# 使用多进程,完成对指定文件的拷贝
# 1用户输入目录
src_path = input("请输入要复制的地址")
# 2.创建一个新的目录,存放拷贝之后的文件数据
dest_path = src_path + "备份"
os.mkdir(dest_path)
# 3.获取指定文件下的所有文件信息
file_list = os.listdir(src_path)
# 创建一个对列,用于线程间通信,主要作用为判断文件拷贝进行的程度
queue = multiprocessing.Queue()
# 4.传入源目录,目的目录文件名,使用给一个子进程完成对文件的拷贝
for file in file_list:
print(os.path.isfile(src_path+"/"+file))
if os.path.isfile(src_path+"/"+file):
# 遍历所有的文件名,为每个文件创建一个进程,进行拷贝
pro = multiprocessing.Process(target=copy_file, args=(file, src_path, dest_path, queue))
pro.start()
# 计算拷贝完的文件数量
count = 0
while True:
file_name = queue.get()
count += 1
# print("\r %s 拷贝完成" % file_name)
time.sleep(1)
print("\r 当前进度为%f%%" % ((count/len(file_list))*100), end='')
if count == len(file_list):
print("拷贝成功")
break
四.进程间通信
进程间通信使用对列进行通信
创建对列:
queue= multiprocessing.Queue(3) 参数为对列的长度
从对列中取数据:
queue.get() 默认阻塞取数据,如果没取到,就等待.先进先出,先放进去的先去出来,
像对列中添加数据:
queue.put() 添加数据,如果对列已经满了,默认等待,什么时候能向对列中添加数据了,就添加.
判断对列是否已经放满:
queue.full(),返回True和Flase
判断对列是否为空:
queue.empty() 返回True和False
获取对列中数据的数量,即对列的长度:
queue.qsize() window和linux中可以正常使用,mac中使用这个方法会崩溃
put(obj[, block[, timeout]])
obj表示数据对象
block表示是否阻塞等待 True表示阻塞等待 False表示不阻塞 不等待
timeout 表示如果等待 等待最长的时间
如果超时等待或者 不阻塞等待都没有获取到数据 则抛出异常
put(data,block=True,timeout=-1)
put(data,True,10)
put(data,False) 不等待 put_nowait(data)
如果超时放入 或者 非阻塞放入数据 没有完成任务 都会抛出异常
get(block=True, timeout=-1])
block表示是否阻塞等待 True表示阻塞等待 False表示不阻塞 不等待
timeout 表示如果等待 等待最长的时间 -1表示死等
get() == get(True,-1)
get(True,10) 最多超时等待10s 如果没有取到数据 就抛出异常
get(False) 不阻塞等待 直接获取数据 如果没有取到数据 就抛出异常
import multiprocessing
import time
def worker1(queue):
while True:
# emtiy()方法判断对列是否为空,为空返回true,否则返回false
if queue.empty():
print("对列为空,稍后再在取")
time.sleep(2)
else:
# get()-->从对列中取数据,如果没有数据,就会堵塞等待,直到与数据可以取
print(queue.get())
time.sleep(3)
if __name__ == '__main__':
# 创建一个对列,传入的参数是对列的长度
que = multiprocessing.Queue(3)
# 创建一个进程
pro = multiprocessing.Process(target=worker1,args=(que,))
# 启动进程
pro.start()
while True:
data = input()
# full()方法判断对列是否已满,如果已满,返回true,反之返回false
if que.full():
print("对列已满")
time.sleep(2)
else:
# put(数据对象) 如果对列满了 默认会阻塞等待对流有空间可以存的时候,存放数据
que.put(data)
# qsize()返回对列长度,在windoes和linux中可用,在mac中不可用
print(que.qsize())