• 进程线程


    1.操作系统帮助开发者操作硬件

    2.程序员写好代码在操作系统上运行(依赖解释器)

    线程的基本使用
    def func(arg):

      print(arg)
    t = threading.Thread(target=func,args=(11,))

    t.start()  开始就绪

    print(111)

    主线程默认等子线程执行完毕

    t = threading.Thread(target=func,args=(11,))

    t.setDaemon(True)

    t.start()  主线程不再等子线程,主线程终止则所有线程终止

    join()  开发者可以控制主线程等待子线程(最多等待时间)

    t.start()

    t.join()  主线程等着,等到子线程执行完毕,才可以继续往下走

    t.join(2)  子线程最多等两秒

    lock = threading.RLock()

    lock.acquire()  加锁,此区域的代码同一时刻只能有一个线程执行

    lock.release()  释放锁

     

    Python 的 GIL锁

      python内置的一个全局解释器锁,锁的作用就是保证同一时刻一个进程中只有一个线程可以被CPU调度

    为什么有这把GIL锁

      Python语言的创始人在开发这门语言是,目的快速把语言开发出来,如果加上GIL锁,切换时按照100条字节指令来进行线程间的切换(编写起来简单)

    为什么要加GIL锁    为了线程安全

      非线程安全

      控制一段代码

    进程和线程的区别

      线程是CPU工作的最小单元

      进程为线程提供一个资源共享的空间  /是CPU资源分配的最小单元

      一个进程中可以有多个线程

      对于python来说它的进程和线程和其他语言有差异,是GIL锁,GIL锁保证一个进程中同一时刻只有线程被CPU调度

      

    IO操作不占用CPU

      

    进程和线程的使用准则

      计算密集型:多进程

      IO密集型:多线程

    锁:Lock  一次锁

    线程安全,多线程操作时,内部会让所有线程排队处理

    RLock  支持多锁锁解(一次放一个)递归锁

    lock = threading.BoudedSemaphore(一次放N个) 信号量

    Condition(一次放x个,动态的)

    Event(一次放所有)

    ct = threading.current_thread()  获取当前线程

    ct.getName()  获取名字

    线程池

    只有python3中有

    threading,local  为每一个线程开辟空间,存取数据

    import multiprocessing

    multiprocessing.Queue()  进程间数据共享

     进程池/线程池

    import time

    from concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutor

    def task(arg):
      time.sleep(2)
      print(arg)

    pool = ThreadPoolExeccutor(5)  限制一次五个线程#线程:ProcessPoolExecutor(5)  Windows需要加上 if __name__ == '__main__':

    for i in range(10)        进程建议几核就几个进程

      pool.submit(task,i)

    IO多路复用

    I  Input  O  Output  IO多路复用可以监听所有的IO请求的状态。socket,cmd终端

      作用:检测多个socket是否已经发生变化(是否连接成功/是否已经获取获取数据)(可读/可写)

    操作系统检测socket是否发生变化有三种模式:

    select:最多监听1024个socket;循环去检测

    poll:不限制监听socket个数;循环去检测(水平触发)

    epoll:不限制监听socket个数;回调方式(边缘触发)

    基于IO多路复用+socket实现并发请求(一个线程100个请求)

    用到的:IO多路复用 + socket非阻塞

    client.setblocking(False)   #非阻塞

    基于事件循环实现的异步非阻塞框架

    非阻塞:不等待  比如:创建socket对某个地址进行connect,获取接收数据recv时默认都会等待,连接成功后或接受到数据时,才会执行后续操作,如果设置setblocking(False),以上两个过程就不在等待,但是会报BlockingIOError的错误,只要捕获即可

       异步:执行完某个任务后,自动执行回调函数或自动执行某些操作(通知)   比如:做爬虫中向某个地址baidu.com发送请求,当请求执行完成之后自动执行回调函数

    同步阻塞

    阻塞:等

    同步:按照顺序逐步执行

    已经实现的模块:Twisted   基于事件循环实现的异步非阻塞框架

    提高并发的方案:

      多进程

      多线程

      异步非阻塞模块(Twisted)  scrapy框架(单线程完成并发)

    协程  greenlet

    协程是微线程,对一个线程进行分片,使得线程在代码块之间进行来回切换,而不是逐步执行

    import greenlet
    def f1():
    print(11)
    gr2.switch()
    print(22)
    gr2.switch()

    def f2():
    print(33)
    gr1.switch()
    print(44)

    gr1 = greenlet.greenlet(f1)
    gr2 = greenlet.greenlet(f2)
    gr1.switch()
     

    哈哈

    单纯的协程无用

    协程 + 遇到IO就切换  pip3 install gevent

    from gevent import monkey
    monkey.patch_all()
    import requests
    import gevent

    def get_page(url):
    ret = requests.get(url)
    print(url,ret.content)

    gevent.joinall([
    gevent.spawn(get_page,'https://www.python.org/'),#协程
    gevent.spawn(get_page,'https://www.yahoo.com/'),#协程
    gevent.spawn(get_page,'https://github.com/')#协程
    ])

    haha

    1.什么是协程?

    协程也可以成为“微线程”,就是开发者控制线程执行流程,控制先执行某段代码然后在切换到另外函数执行代码。。。来回切换

    遇到switch就切换

    2.协程可以提高并发吗?
    协程自己本身无法实现并发(甚至性能会降低)

    协程 + IO切换 性能提高

    3.进程,线程,协程 的区别?

    4.单线程提供并发:

      协程 + IO切换:gevent

      基于时间循环的异步非阻塞框架:Twisted

  • 相关阅读:
    Spring源码解析-AutowiredAnnotationBeanPostProcessor
    Spring源码解析-基于注解依赖注入
    Spring源码解析-事件
    Spring源码解析-AOP简单分析
    Spring源码解析-实例化bean对象
    Spring源码解析-配置文件的加载
    linux 条件判断式
    Assembly.LoadFrom加载程序集类型转换失败解决方法
    autodesk fbx sdk sample里面的工程无法调试解决方法
    Unity ---WidgetsUI CreateTileView Demo
  • 原文地址:https://www.cnblogs.com/nice777/p/11100423.html
Copyright © 2020-2023  润新知