python线程、进程、协程介绍

                            线 程
并发: 任务数大于cpu的核数叫并发,多个任务交替执行, 并发看起来是一块儿运行实际上是一个假象。
并行: 任务数小于或者等于cpu的核数并行,并行才能真正意义上多个任务一块儿运行
1.import threading:调用功能可建立线程
2.threading.Thread(target=show_info, name="mythread",args = () ,kwargs={}):建立线程
  2.1 group: 线程组,默认值是None,目前只能使用None值
  2.2 target: 执行目标的函数
  2.3 name: 线程名, 默认起名字相似与: Thread-1, ....
  2.4 args:以元组的方式给函数传参
  2.5 kwargs: 以字典的方式给函数传参
3.threading.current_thread():扩展: -获取当前代码执行的线程对象
4.threading.enumerate():获取当前程序活动线程的列表
5.子线程.setDaemon(True):表示守住主线程, 主线程退出子线程直接销毁再也不执行代码
6.建立自定义线程就是建立一个类,再建立一个对象,而后对象.start()
7.子线程.join():让主线程等待写入线程执行完成之后程序再退出,线程同步,按照预约的顺序去执行代码,一个任务执行完成之后另一个任务才能执行
8.lock = threading.Lock():建立锁
  8.1 lock.acquire():上锁
  8.2 lock.release():释放锁
  8.3 互斥锁
    8.3.1 保证同一时刻只有一个线程去执行代码,其它线程没有抢到锁会等待
    8.3.2 提示:加上互斥锁,那个线程抢到锁咱们绝对不了由于,线程执行是无序
    8.3.3 注意点: 线程同步和加上互斥锁把多任务瞬间该成单任务,性能会降低python


                            进 程
1. 进程:通俗理解一个运行起来的程序或者软件叫作进程
  1.1 每次启动一个进程都想操做系统索要运行资源,进程是操做系统资源分配的基本单位
  1.2 默认状况下启动一个进程默认只有一条线程,这个线程主线程, 线程是依附在进程里面的,没程序员

  有进程就没有线程,进程能够有多个线程
  1.3 如何理解进程:能够把进程想成公司,公司会给员工提供办公资源(办公电脑,办公桌椅等资安全

  源), 真正干活的是员工, 公司比如进程,员工线程
2. 进程和线程的对比
  2.1 进程: 每次启动一个进程都须要向操做系统索要运行资源,进程是操做系统资源分配的基本单网络

  位
  2.2 线程: 执行代码的分支,线程是cpu调度的基本单位, 线程是依附在进程里面的,没有进程就多线程

  没有线程,默认一个进程只有一个线程,可是能够开辟多个线程
  2.3 进程不共享全局变量, 线程共享全局变量可是要注意资源竞争数据错误的问题, 可使用线并发

  程同步或者互斥锁
  2.4 多进程开发比单进程多线程开发稳定性要强, 由于某个进程死了不会影响其它进程的运行,但app

  是单进程多线程开发,若是这个进程死了,那么进程中的全部线程都不能再运行了
  2.5 多进程开发比单进程开发资源要分配的多,多线程能够利用进程中的资源,可是每次启动一个框架

  进程都须要向操做系统索要运行资源
3. import multiprocessing:调用功能可建立进程
4. 子线程.pid:扩展-获取当前进程的编号
5. multiprocessing.Process(group=None, target=show_info, name="myprocess", args=("小明", 20)):建立子进程
  5.1 group:进程组,默认值是None,目前只能使用None不能设置其它参数
  5.2 target: 执行目标函数
  5.3 name: 进程名称,默认的格式: Process-1,....
  5.4 args: 以元组方式传参
  5.5 kwargs: 以字典方式传参
6. 子进程.start():启动子进程,执行对应的任务
7. 子进程.pidos.getpid():都是获取子进程编号
8. os.getppid():获取父进程(主进程)编号
9. os.kill(os.getpid(), 9):# 扩展-根据进程编号杀死对应的进程,os.getpid()进程编号,9表示强制杀死
10. 子进程.join():主进程等待写入进程执行完成之后程序再往下继续执行
11. 子进程.daemon = True:设置守护主进程, 主进程退出后子进程直接销毁了。
12. 子进程.terminate():让子进程直接销毁
13. queue = multiprocessing.Queue(3):# 建立消息队列,3表示消息队列最大个数
  13.1 queue.put(' '):向变量名里面传输数据,队列满了在放入数据, 就不能放入数据了,直到消息异步

  队列有空闲位置才能再放入数据
  13.2 queue.put_nowait:不会等待队列有空闲位置再放入数据,若是数据放入不成功就直接崩async

  溃。建议: 放入数据使用put,由于比较安全不会崩溃

  13.3 queue.full():查看队列是不是满的。坑点: 只使用put放入数据直接判断队列是否为空获取的

  结果不正确,由于没有等队列把数据写完直接就取获取了,那么这是队列是空的

  13.4 queue.qsize():获得队列里面数据的个数,mac 版本不能使用qsize()
  13.5 queue.empty():判断队列是否为空,空获得True,有数据获得Flase
  13.6 queue.get():获取队列的数据,队列为空,使用get会等待,直到队列有数据之后再取值
  13.7 queue.get_nowait():队列为空,取值的时候不等待,可是取不到值那么直接崩溃了。建

  议:获取队列的数据统一get,由于能保证代码不会有问题

14. multiprocessing.Pool(3):建立进程池 3: 进程池中进程的最大个数。注:进程池:,池子里面放的都是进程,进程的建立有进程池负责,执行任务的时候循环利用指定进程大小个数执行对应的任务
  14.1 apply():表示同步执行,表示一个任务执行完成另一个任务才能执行
  14.2 apply_async():表示异步执行,异步是不会等待其它任务执行完成之后再去执行,多个任务一

  起执行
  14.3 pool.close():关闭进程池,再也不接收其它任务
  14.4 pool.join():主进程等待进程池执行完成之后再退出
15 queue = multiprocessing.Manager().Queue():建立进程池的queue
                            协 程
协程:又称为微线程,也能够说成用户级线程, 在不开辟线程的基础上能够完成多任务
如何理解协程: 只要在def里面只看到一个yield关键字表示就是协程
学习协程目的: 在单线程的基础上能够完成多任务,多个任务按照必定顺序交替执行
迭代:使用for循环遍历取值的过程就叫作迭代。可迭代对象有: 元组,列表,字典,字符串,集合,range;int对象不是可迭代对象
1.from collections import Iterable : 可迭代类型k,
2.isinstance((3, 5), Iterable):断定(3,5)是否是可迭代类型。扩展:-之后能够经过isinstance判断函数的参数或者方法的参数是不是指定类型,(3, 5)断定的对象,Iterable断定的类型
2.自定义可迭代对象
  2.1 在类里面提供了__iter__方法建立的对象就是可迭代对象。
  2.2 自定义迭代器对象: 在类里面提供__iter____next__的方法建立的对象就是迭代器对象
  2.3 迭代器的做用: 记录当前数据的位置之后获取下一个位置的值
  2.4 总结: 可迭代对象的本质:经过迭代器依次获取对象中的数据须要返回一个迭代器
  2.5 使用for遍历可迭代对象依次获取对应的数据
  2.6 扩展 raise StopIteration表示越界,抛出中止迭代的异常信息
3. iter函数:获取可迭代对象的迭代器, 会调用可迭代对象身上的__iter__方法
4. next函数:获取迭代器中下一个值,会调用迭代器对象身上的__next__方法
5.iter获取可迭代对象.的迭代器,获得的是<__main__.StudentIterator object at 0x00000000027A7828>
6.生成器: 是一个特殊的迭代器,也就是说生成器依然可使用next函数和for循环遍历取值
  6.1建立生成器方式1:my_generator = (i * 2 for i in range(10)) 建立生成器后for来遍历获得结果
  6.2建立生成器2:使用yield,只要在def里面看到yield表示生成器。代码执行yield会暂停,把结果返

  回给外界,再次启动生成器会在暂停的位置继续往下执行
  6.3代码执行到return关键字的时候会抛出中止迭代的异常,后面就是有数据也不会取了;生成器里

  面使用return关键字语法上没有问题,可是注意代码执行到return关键字会抛出中止迭代的异

  常;python3执行return, python2不支持。
  6.4 yield每次启动生成器yield都会返回一个值,也就是说屡次启动生成器能够返回屡次值;return

  只会返回一次值,而且抛出中止迭代异常,获取返回值经过捕获异常取到返回值
7.调用生成器的send方法
  7.1能够根据参数判断是否能够中止迭代,执行return关键字就能够中止
  7.2总结: send能够给生成器传参数,可是第一次启动生成器只能传None,通常第一次启动生成器

  使用next函数
8.greenlet: 为了更好的让程序员使用协程可使用greenlet,由于greent封装的yield
  8.1 变量名 = greenlet.greenlet(所执行的任务名):建立协程执行对应的任务
  8.2 变量名.switch():切换到第一个协程执行对应的任务
9.from gevent import monkey
  9.1 monkey.patch_all():须要打补丁,让gevent可以识别系统的耗时操做及网络延时操做
10. import gevent:gevent框架封装Greenlet,会根据耗时操做自动完成协程之间的切换执行
  10.1 pip3 install gevent :下载gevent
  10.2 变量名 = gevent.spawn(所执行的任务名):建立协程完成对应的任务
  10.3 变量名 .join():让主线程等待协程执行完成之后程序再退出
11. import urllib.request : 导入网络请求模块
11.1 urllib.request.urlopen():根据图片地址加载网络资源数据
11.2 gevent.spawn(download_img, img_url1, "1.jpg"):建立协程对象指定对应的任务
  11.2.1 函数名,
  11.2.2 函数对应的参数1: img_url1
  11.2.3 函数对应的参数2: 图片名
                           进程、线程、协程对比 1. 先有进程,而后进程里面能够建立多个线程,线程里面能够有多个协程 2. 进程之间不共享全局变量,线程之间共享全局变量,可是要注意资源竞争的问题 3. 多进程开发比单进程多线程开发稳定性要强,可是多进程开发比多线程开发资源开销要大 4. 线程之间执行时无序的,可是协程在不开辟线程的基础上能够完成多任务,多个任务按照必定顺序交替执行 5. 协程之后主要用在网络爬虫,网络请求,每开辟协程大概须要5k空间 6. 开辟一个线程大概须要512k空间,进程须要资源更多

相关文章
相关标签/搜索