Python的进程与队列

多任务:如果有多件事情是同时进行,我们把这种情况叫做多任务。Linux 是真正的多任务、多用户操作系统,windows是多任务操作系统,但不是真正意义上的多用户操作系统
串行做完一件事在做另一件事
并发和并行
并发(Concurrent):在多核系统里的,同时执行多个进程,一般会情况下会有些进程没有机会执行,这种情况是并发。
并行(Parallel):在多核系统里,同时执行多个进程,这些进程都有机会执行,这种情况是并行。
时间片轮转调度是一种最古老,最简单,最公平且使用最广的算法,又称RR调度。每个进程被分配一个时间段,称作它的时间片,即该进程允许运行的时间  
优先数调度算法常用于批处理系统中。在进程调度中,每次调度时,系统把处理机分配给就绪队列中优先数最高的进程。它又分为两种:非抢占式优先数算法和抢占式优先数算法。
非抢占式优先权算法:系统一旦把处理机分配给就绪队列中优先权最高的进程后,该进程便一直执行下去,直至完成。
抢占式优先权调度算法:系统同样把处理机分配给优先权最高的进程,使之执行.但在其执行期间,只要又出现了另一个其优先权更高的进程,进程调度程序就立即停止当前进程(原优先权最高的进程)的执行,重新将处理机分配给新到的优先权最高的进程。
系统的进程会比开发者开发的优先调度
多任务在程序中的实现--进程和线程
多任务系统中有3个功能单位:任务、进程和线程;
os.fork函数创建进程
程序和进程区别
程序:编写完毕的代码,在没有运行的时候,称之为程序(代码);
进程:正在运行着的代码,就成为进程,进程占用了内存和cpu等资源。
pid用来唯一标识一个进程
fork()可以在Python程序中轻松创建子进程(pid=0), 并且实现多任务,但是在windows上无法创建成功。
fork()函数用于生成子进程pid(返回值可以不是pid)=os.fork()生成的子进程是父进程的镜像,但是它们有各自的地址空间, 子进程复制一份父进程内存给自己,两个进程之间的执行是相互独立的;父进程和子进程执行顺序可以是不确定的、随机的、不可预测的。
在Unix/Linux(windows不支持)操作系统中,提供了一个fork()系统函数,代码从上往下执行到os.fork()时,普通的函数调用,调用一次,返回一次,但是fork()调用一次,返回两次。python的会调用操作系统会创建一个新的进程(子进程),然后复制父进程的所有信息到子进程中,然后父进程和子进程都会从fork()函数中得到一个返回值,在子进程中这个值一定是0,而父进程中返回的是刚好子进程的 id号。这样做的理由是,一个父进程可以fork出很多子进程,所以,父进程要记下每个子进程的ID
多进程中,每个进程中所有数据(包括全局变量)都各有拥有一份,互不影响。
fork时子进程获得父进程代码和数据段、共享库、堆和栈的拷贝,所以变量的地址也是一样的,并且在某一个进程中修改相同变量的值,在另外一个进程中的相同变量的值不会修改。
os.getpid()获得当前进程的pid     os.getppid当前父进程的pid
Linux创建进程最多达到65535个,进程号不能相同的
进程与进程之间数据不共享

Process语法结构  from multiprocessing import Process

p=Process(target=子进程函数,args=(2,))args传递函数的参数
创建子进程时,只需要传入一个子程序执行函数和函数的参数,创建一个Process实例对象,用start()方法启动,这样创建进程比fork()还要简单。
is_alive():判断进程实例是否还在执行;
join(timeout):timeout只让主进程等待多少秒;没有参数是指在进程执行完毕之后主进程再执行
start():启动进程实例(创建子进程);
run():创建子进程要重写run方法如果没有给定target参数,对这个对象调用start()方法时,就将执行对象中的run()方法; 直接调run只能是进行顺序执行不会开启进程,要调用start()启动run
terminate():不管任务是否完成,立即强制终止;子进程只要完成任务就会自己终止
Process类常用属性:
name:当前进程实例别名,默认为Process-N,N为从1开始递增的整数;
pid:当前进程实例的PID值;
进程池(Pool)
初始化Pool时,可以指定一个最大进程数,当有新的请求提交到Pool中时,如果池还没有满,那么就会创建一个新的进程用来执行该请求;但如果池中的进程数已经达到指定的最大值,那么该请求就会等待,直到池中有进程结束,才会创建新的进程来执行。
阻塞式:添加一个执行一个,执行完毕,并且返回才会添加下一个任务
非阻塞式:全部添加到队列中,立刻返回,并没有等他执行完毕,,当执行完毕后会有回调(由主程序调用),回调中携带结果
multiprocessing.Pool 常用函数解析
apply_async(func, args, kwds,callback) :使用非阻塞方式调用func并行执行,args为传递给func的参数列表,kwds为传递给func的关键字参数列表,callback回调函数(回复值)
,回调函数有参数,是由当前任务func的返回值当作参数由主进程调用;
apply(func[, args[, kwds]]):使用阻塞方式调用func堵塞方式必须等待上一个进程退出才能执行下一个进程
close():关闭Pool,使其队列不再接受其他新的任务;不加close会一直等待任务加入导致不会执行上面的任务
terminate():不管任务是否完成,立即终止,针对的是非阻塞式。
join():主进程阻塞,等待子进程的退出, 必须在close或terminate之后使用;
使用Queue实现进程间通信
Python中在multiprocessing模块的Queue类可以实现进程之间的数据传递,Queue本身是一个消息列队程序)、Manage支持管道通信、套接字( socket )等等实现进程间通信
Queue的参数说明
1.初始化Queue()对象时(例如:q=Queue()),若括号中没有指定最大可接收的消息数量,或数量为负值,那么就代表可接受的消息数量没有上限(直到内存的耗尽);
2.Queue.qsize():返回当前队列包含的消息数量;
3.Queue.empty():如果队列为空,返回True,反之False ;
4.Queue.full():如果队列满了,返回True,反之False;
5.Queue.get([block[, timeout]]):获取队列中的一条消息,然后将其从列队中移除,block默认值为True;
1)如果block使用默认值,且没有设置timeout(单位秒),消息列队如果为空,此时程序将被阻塞(停在读取状态),直到从消息列队读到消息为止,如果设置了timeout,则会等待timeout秒,若还没读取到任何消息,则抛出"Queue.Empty"异常;
2)如果block值为False,消息列队如果为空,则会立刻抛出"Queue.Empty"异常;
6.Queue.get_nowait():相当Queue.get(False);
7.Queue.put(item,[block[, timeout]]):将item消息写入队列,block默认值为True;
1)如果block使用默认值,且没有设置timeout(单位秒),消息列队如果已经没有空间可写入,此时程序将被阻塞(停在写入状态),直到从消息列队腾出空间为止,如果设置了timeout,则会等待timeout秒,若还没空间,则抛出"Queue.Full"异常;
2)如果block值为False,消息列队如果没有空间可写入,则会立刻抛出"Queue.Full"异常;
8.Queue.put_nowait(item):相当Queue.put(item, False);
如果使用进程池队列则进程池中的使用Manager()中的Queue
from multiprocessing import Manager,Pool
q = Manager().Queue()
\r 换行,光标在停留在上一行    % '%%'输出一个单一的'%'显示百分号
打印进度
import time
for i in range(1,101):
print("\r当前进度:%.2f%%"%i,end="")
time.sleep(0.02)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值