多任务的使用及区别

  多任务介绍

  现实生活中有很多的场景中的事情是同时进行的,比如开车的时候 手和脚共同来驾驶汽车,再比如唱歌跳舞

也是同时进行的

多任务的概念

  什么叫“多任务”呢?简单地说,就是操作系统可以同时运行多个任务。打个比方,你一边在用浏览

器上网,一边在听MP3,一边在用Word赶作业,这就是多任务,至少同时有3个任务正在运行。还

有很多任务悄悄地在后台同时运行着,只是桌面上没有显示而已

  现在,多核CPU已经非常普及了,但是再以前单核cpu 的时候也是可以实现多任务的单核cpu是怎么实现多任务的呢

在就是操作系统轮流让各个任务交替执行,任务1执行0.01秒,切换到任务2,任务2执行0.01秒,再切换到任务3,执行0.01秒,

这样一直反复下去 由于cpu执行的太快了 让我们感觉上就是同时执行的。在这里要提到一个知识点,并行与并发

并发:是指任务多余cpo核数,系统通过调用来实现多个任务同时运行 其实不说一起执行 只是切换任务的速度比较快 看上去执行时一起的

并行:任务数量等于cpu核数 任务才真的可以一起执行

一,线程

线程是实现多任务的一种方法

主线程
  主线程会等所有子线程结束后才结束
  使用 import threading 调用
  变量名 = threading.thread(target =函数)函数不用打括号
  变量名.start()开始

子线程
  定义一个方法 在主线程用threading.thread(target =函数)函数不用打括号调用

查看线程方法
  len(threading.enumerate())赋值给一个变量 并打印出来

线程的注意点

  封装
    先定义一个Thread 的类 继承threading.thread
    在类里定义一个run方法 run方法在start调用时自动执行
    创建一个类对象 调用start 自动执行run

  执行顺序
    线程的执行时无序的

线程共享全局变量
    如果多个线程同时对同一个全局变量操作,会出现资源竞争问题,从而数据结果会不正确

同步
  是一种概念 同步就是协同步调,按预定的先后次序进行运行

互斥锁
  当多个线程同时共享一个数据时需要进行同步控制 为了时多个线程安全使用数据的解决 我们可以使用互斥锁

  创建锁
    mutex = threading.Lock()
  锁定
    mutex.acquire
  释放
    mutex.release()  

  死锁

    在线程键共享多个资源是 如果两个线程分辨占有一部分资源并且同时等待对方子牙u你就会造成死锁

  如何避免死锁
    程序设计是要尽量避免
    添加超时时间等

二,进程

每一个程序运行起来都叫进程 也可以实现多任务

进程的状态
  就绪态
    运行的条件已经都满足了等待cpu执行
  执行态
    cpu正在执行功能
  等待态
    等待某些条件满足时 会返回到就绪态

进程的创建
  调用multiprocessoring模块

pid
  使用os模块 os.getpid查看当前进程号
  使用os模块 os.getppid查看主进程号
  在终端上 ps aux 查看所有进程
  在终端上 ps aux | gerp getpid 查看指定进程

process语法结构
  process可以进行传参

      

  process创建实例对象的常用方法
     

  process创建实例对象的常用属性

      

进程间不共享全局变量

  因为子进程是复制主程序产生了一个新的代码 所以他们之间的变量互不影响

进程与线程之间的不同以及联系

  进程是系统进行资源分配的一个独立单位 线程是cpu调度和分配的基本单位
  一个程序里至少有一个进程 一个进程里又至少又一个线程
  进程在执行过程中拥有独立的内存单元 而多个线程值共享一个
  线程不能独立运行 必须要在进程里

Queue
  调用multiprocessor模块里的Queue实现
  可以实现多个进程之间的数据共享
  先multiprocessor.Queue 创建个对象 用put输入 get输出

进程池 pool
  可以讲多个数据存储到池中 可以减少内存占用pool(n)
  使用.apply_async(worker,(i,))来传入 当达到指定数量时 会自动阻塞 由池队列等待

 三,协程

迭代器
  可迭代对象

    列表 字符串 等类型的数据只要可以通过for in 的循环语法来遍历的的使用的对象都叫可迭代对象

  判断是否可以迭代

    使用isinstance来判断一个对象是否可以迭代

  可迭代对象的本质

    可迭代对象的本质就是可以提供一个迭代期来帮助我们遍历 通过__iter__方法来向可迭代对象提供一个迭代器

  iter()函数 与next()函数

    可以通过iter()来调取可迭代对象里的__iter__方法 然后再用迭代器里的next()函数来获取数据

  判断一个对象是否具有迭代器

    可以使用isinstance()来判断是否由iterator对象

  迭代器

    具有__iter__方法 和next方法的函数

  for in 的本质 就是通过迭代对象 和迭代器来传递的

生成器
  在函数里出现yield时就不再是函数了 变成生成器了
  不再能被函数调用 要赋值后 直接库被for循环调用
  send 可以激活冻结的生成器 并且可以传递一个数据给yield关键字
  yield 可以获取打send发来的数据 并且赋值给变量

协程-yield
  最简单的实现协程 在函数里加上yield

协程-greenlet

  可以在生成器里直接互相调用了 在函数里写上变量.switch
  方法 将greenlet()赋值给一个变量
  赋值变量调用switch()开始

协程-gevent
  gevent是智能的 可以直接来回调用

进程,线程,协程区别

  1. 进程是资源分配的单位
  2. 线程是操作系统调度的单位
  3. 进程切换需要的资源很最大,效率很低
  4. 线程切换需要的资源一般,效率一般(当然了在不考虑GIL的情况下)
  5. 协程切换任务资源很小,效率高
  6. 多进程、多线程根据cpu核数不一样可能是并行的,但是协程是在一个线程中 所以是并发

猜你喜欢

转载自www.cnblogs.com/bt-bug/p/9109509.html