Fork me on GitHub

python多任务处理

多任务解析

  • 什么叫“多任务”呢?简单地说,就是操作系统可以同时运行多个任务。 现在,多核CPU已经非常普及了,但是,即使过去的单核CPU,也可以执行 多任务。由于CPU执行代码都是顺序执行的,那么,单核CPU是怎么执行多 任务的呢?

  • 其实就是操作系统轮流让各个任务交替执行,任务1执行0.01秒,切换到任务 2,任务2执行0.01秒,再切换到任务3,执行0.01秒……这样反复执行下去。 表面上看,每个任务都是交替执行的,但是,由于CPU的执行速度实在是太 快了,我们感觉就像所有任务都在同时执行一样。

  • 真正的并行执行多任务只能在多核CPU上实现,但是,由于任务数量远远多 于CPU的核心数量,所以,操作系统也会自动把很多任务轮流调度到每个核 心上执行。

多任务表现形式

  • window下打开任务管理器可以很清晰看到多个进程在同时执行任务,qq、微信等都是已进程的形式寄存在window下。大多我们在写一些控制台程序真正执行的时候都是以进程调度。

  • 在linux下以fork的形式创建进程,简单写个实例:

多次fork创建,进程数会已指数倍增长。

`
import os
import time

num = 0
# 主进程创建了一个子进程
ret = os.fork()
if ret == 0:
        num+=1
        print('ret = 0,num=%d',num)
else:
        time.sleep(1)
        print('he,num=%d',num)

# 主进程会再次创建一个子进程,上面的子进程也会创建一个子进程
ret = os.fork()
if ret ==0:
        print('aaaaa')
else:
        print('bbbb')
`

python中多进程

如果你打算编写多进程的服务程序,Unix/Linux无疑是正确的选择。由于Windows没有fork调用,由于Python是跨平台的,当然也应该提供一个跨平台的多进程支持。 multiprocessing模块就是跨平台版本的多进程模块。 multiprocessing模块提供了一个Process类来代表一个进程对象

进程池调度

- 每次指定几个进程同时执行任务

`
from multiprocessing import Pool
import os
import time


def worker(num):
        print('pid = %d,num = %d'%(os.getpid(),num))
        time.sleep(2)


pool = Pool(3)

for i in range(10):
        print('%d'%i)
        pool.apply_async(worker,(i,))

pool.close()
pool.join()

`
  • apply_async非阻塞式调度,apply阻塞式调度

进程间通讯

  • 任何进程间资源都是独立的,所有一切都是不可以共享的。实现资源共享、进程间通讯比较常用的方式就是Queue。

  • 使用Queue可以解决Process创建的进程之间的通讯,但是无法解决进程池中进程之间通讯。

  • 进程池进程之间的通讯需要使用Manager.Queue()创建的队列。

实现基于多进程的文件拷贝

`
# coding:utf-8

from multiprocessing import Pool,Manager
import os

def CopyFile(oldPath,newPath,fileName,queue):
    fr = open(oldPath+'/'+fileName)
    fw = open(newPath+'/'+fileName,'w')

    # 当然如果是较大文件时,不要一次性读写
    content = fr.read()
    fw.write(content)

    fr.close()
    fw.close()

    queue.put(fileName)

def Main():
    oldPath = input('please input folder path:')
    newPath = oldPath+'-backups'
    os.makedirs(newPath)

    fileNames = os.listdir(oldPath)

    pool = Pool(5)
    queue = Manager().Queue()

    for name in fileNames:
        pool.apply_async(CopyFile,args=(oldPath,newPath,name,queue))

    num = 0
    allNum = len(fileNames)
    while num<allNum:
        queue.get()
        num += 1
        copyRate = num/allNum
        print('\r当前copy进度:%.2f%%'%(copyRate*100),end='')

    print('\n 已完成copy!')

if __name__ == '__main__':
    Main()
`

GitHub:基于多进程的文件拷贝

posted @ 2017-08-13 17:14  迁梦余光  阅读(3997)  评论(0编辑  收藏  举报