python多任务之进程

什么是进程?

当你想在电脑上听歌的时候,应该是先找到网易云音乐的应用程序,打开才能播放音乐。当我们双击打开的时候,操作系统骄傲那个程序装载到内存中,cpu为它分配资源,然后才能运行,运行起来的程序就被称为进程。注意:程序只有一个,但是进程可以有多个

进程的状态

在这里插入图片描述
在程序运行的过程中,由于被操作系统的调度算法控制,程序会进入几个状态:就绪,运行
和阻塞

(1)就绪(Ready)状态
当进程已分配到除CPU以外的所有必要的资源,只要获得处理机便可立即执行,这时的进程
状态称为就绪状态。
(2)执行/运行(Running)状态
当进程已获得处理机,其程序正在处理机上执行,此时的
进程状态称为执行状态。
(3)阻塞(Blocked)状态
正在执行的进程,由于等待某个事件发生而无法执行时,便放弃处
理机而处于阻塞状态。引起进程阻塞的事件可有多种,例如,等待I/O完成、申请缓冲区不
能满足、等待信件(信号)等。

实现进程

实现进程有两种方式,创建 multiprocessing的实例化对象继承process类

  • 继承process类
import os
from multiprocessing import Process
from urllib import request
# 1.继承process类
class Process_class(Process):
    # 2.使用父类的初始化方法
    # 因为Process类本身也有__init__方法,定义这个类相当于 重写这个方法
    def __init__(self,url):
        super().__init__()
        self.url = url
    # 3. 重写Process类的run方法
    def run(self):
        print("当前进程:",os.getpid())
        # 1.文件名
        file_name = self.url.split("/")[-1]
        # 2.网络请求
        response = request.urlopen(self.url)
        # 3. 获取响应内容
        content = response.read()
        # 4.保存图片
        with open(file_name, "wb") as f:
            f.write(content)
if __name__ == '__main__':
    url_list = [
        "http://www.langlang2017.com/img/banner1.png",
        "http://www.langlang2017.com/img/banner4.png"
    ]
    for url in url_list:
        p = Process_class(url)
        p.start()
    print("主进程",os.getppid())

  • 创建 multiprocessing的实例化对象
import os
from urllib import request
from multiprocessing import Process
def downloder(url,**kwargs):
    """
    下载器
    :param url: 图片网址
    :param kwargs: 字典参数
    :return: none
    """
    print("当前进程id",os.getpid())
    print("获取其父程序的id",os.getppid())
    print("关键参数",kwargs["pro"])
    # 1.文件名
    file_name = url.split("/")[-1]
    # 2.网络请求
    response = request.urlopen(url)
    # 3. 获取响应内容
    content = response.read()
    # 4.保存图片
    with open(file_name,"wb") as f:
        f.write(content)
if __name__ == '__main__':
      # for i in range(1,5):
      #     url = "http://www.langlang2017.com/img/banner%d.png"%i
      #     p = Process(target=downloder,args=(url,))
      #     p.start()

      # 姓名列表
      name_list = ["进程1--张铁蛋","进程2--张翠花"]
      # 进程列表
      p_list = []
      # 图片链接列表
      url_list = [
         "http://www.langlang2017.com/img/banner1.png",
         "http://www.langlang2017.com/img/banner4.png"
      ]
      i = 0
      for url in url_list:
          n = name_list[i]
          i+=1
          p = Process(target=downloder,name=n,args=(url,),kwargs={"pro":"最高级"})
          print("子进程(%s)将要执行。。。"%p.name)
          p.start()
          p_list.append(p)
      # 为了确保所有子进程结束
      for p in p_list:
          p.join()

      print("主进程id:",os.getpid())


进程之间的通讯

队列
刚才我们说了进程可以理解为复制了一份程序有加载到了内存了,进程之间是独立的,如果
我想两个进程之间进行通讯怎么办呢?我们可以使用Queue 队列,队列是一种先进先出的存
储数据结构
,就比如排队上厕所一个道理。
两个进程通讯,就是一个子进程往queue中写内容,另一个进程从queue中取出数据。就实现
了进程间的通讯了

1.  创建 queue队列对象 q = multiprocessing.Queue(3)  # 3表示只能存放3个数据
参数 :maxsize是队列中允许的大项数。如果省略此参数,则无大小限制。
返回值q 是队列对象 
2.  put()方法 ,向队列中存放数据。如果队列已满,此方法将阻塞至有空间可用为止。 
3. 3.  get()返回q中的一个项目。如果q为空,此方法将阻塞,直到队列中有项目可用为止。 
4. 4.  get_nowait(): 不等待,直接抛出异常 
5. 5.  full()如果q已满,返回为True 
6. 6.  q.empty() 如果调用此方法时 q为空,返回True

进程池

当需要创建的子进程数量不多时,我们可以直接利用multiporcessing中的Process动态生成
多个进程,创建进程池对象的时候可以指定一个大进程数,当有新的请求提交到进程池中,如果池中的进程数还没有满,那么就会创建一个新的进程用来执行该请求,但是如果池中的进程数满了,该请求就会等待,知道进程池中的进程有结束的了,才会使用这个结束的进程来执行新的任务

join 主进程等待所有子进程执行完毕,必须在close之后。
close 等待所有进程结束才关闭线程池

from multiprocessing import Pool
import time


def down_load(movie_name):
    for i in range(5):
        print('电影:{},下载进度{}%'.format(movie_name,(i/4* 100)))
        time.sleep(1)
def alert(movie_name):
    print('恭喜{}下载完成了...'.format(movie_name))


if __name__ == '__main__':
    movie_lst =['西红柿首富','功夫小子','功夫熊猫','叶问','功夫','战 狼','红海行动']
    pool = Pool(3)
    for movie_name in movie_lst:
        pool.apply_async(down_load, (movie_name,), callback=alert)
    pool.close()
    pool.join()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值