Python进程.线程(同步异步阻塞)

# 进程:进程就是一个程序在内存中的运行,进程是资源分配的最小单位
# 线程:线程是cup调度的最小单位
# 计算:消耗cpu,cpu进行运算     
# io:  不消耗cpu
# 垃圾回收机制:垃圾回收线程专门干这个事,一个进程下多线程情况下,使用GIL,只有获得gil锁的线程才能执行
# 正常来讲,如果一个进程开个4个线程,4核cpu,也只有一个核在运行python,原因在于只有拿到GIL锁才能运行
# 开启多进程,充分利用cpu:   
计算密集型使用多进程,io密集型使用多线程
# 线程间变量共享----》多线程并发操作问题----》锁
# 多进程之间变量不共享----》进程间通信问题---》IPC---》进程queue,redis,消息队列

计算2s,计算3s,计算2s
计算2s,计算3s,计算2s
2+3+2+2+3+2


计算用2s,io用3s,计算2s 计算用2s,io用3s,计算2s
2+3+2+2+3+2
2+2+1+2+2

# 并发和并行
    -一个时间段内,多个任务在执行---》可以是一核,可以是多核
    -同一时刻,多个任务在执行----》一定是多核cpu

# 线程间切换,是操作系统决定的,耗费资源
# 程序员自己控制任务的切换,协程
# https://www.cnblogs.com/xfeiyun/p/15882626.html
# io操作:数据复制的过程中不会消耗CPU
1 内存分为内核缓冲区和用户缓冲区
2 用户的应用程序不能直接操作内核缓冲区,需要将数据从内核拷贝到用户才能使用
3 而IO操作、网络请求加载到内存的数据一开始是放在内核缓冲区的

# BIO – 阻塞模式I/O
用户进程从发起请求,到最终拿到数据前,一直挂起等待; 数据会由用户进程完成拷贝
'''
举个例子:一个人去 商店买一把菜刀,
他到商店问老板有没有菜刀(发起系统调用)
如果有(表示在内核缓冲区有需要的数据)
老板直接把菜刀给买家(从内核缓冲区拷贝到用户缓冲区)
这个过程买家一直在等待

如果没有,商店老板会向工厂下订单(IO操作,等待数据准备好)
工厂把菜刀运给老板(进入到内核缓冲区)
老板把菜刀给买家(从内核缓冲区拷贝到用户缓冲区)
这个过程买家一直在等待
是同步
'''

# NIO – 非阻塞模式I/O
用户进程发起请求,如果数据没有准备好,那么立刻告知用户进程未准备好;此时用户进程可选择继续发起请求、或者先去做其他事情,稍后再回来继续发请求,直到被告知数据准备完毕,可以开始接收为止; 数据会由用户进程完成拷贝
'''
举个例子:一个人去 商店买一把菜刀,
他到商店问老板有没有菜刀(发起系统调用)
老板说没有,在向工厂进货(返回状态)
买家去别地方玩了会,又回来问,菜刀到了么(发起系统调用)
老板说还没有(返回状态)
买家又去玩了会(不断轮询)
最后一次再问,菜刀有了(数据准备好了)
老板把菜刀递给买家(从内核缓冲区拷贝到用户缓冲区)

整个过程轮询+等待:轮询时没有等待,可以做其他事,从内核缓冲区拷贝到用户缓冲区需要等待
是同步io

同一个线程,同一时刻只能监听一个socket,造成浪费,引入io多路复用,同时监听读个socket
'''

#  IO Multiplexing - I/O多路复用模型
类似BIO,只不过找了一个代理,来挂起等待,并能同时监听多个请求; 数据会由用户进程完成拷贝
# 什么是IO多路复用?
IO 多路复用是一种同步IO模型,实现一个线程可以监视多个文件句柄;
一旦某个文件句柄就绪,就能够通知应用程序进行相应的读写操作;
没有文件句柄就绪就会阻塞应用程序,交出CPU。

### select poll epoll
#  1 select poll 和epoll都是io多路复用技术
select, poll , epoll都是io多路复用的机制。I/O多路复用就是通过一种机 制个进程可以监视多个描述符,一旦某个描述符就绪(一般是读就绪或者写就绪),能够通知程序进行相应的读写操作。但select, poll , epoll本质上都是同步I/O ,因为他们都需要在读写事件就绪后自己负责进行读写, 也就是说这个读写过程是阻塞的,而异步I/O则无需自己负责进行读写,异 步I/O的实现会负责把数据从内核拷贝到用户空间。

# 2 select
select函数监视的文件描述符分3类,分别是writefds、readfds、和 exceptfds。调用后select函数会阻塞,直到有描述副就绪(有数据可读、 可写、或者有except),或者超时(timeout指定等待时间,如果立即返回 设为null即可),函数返回。当select函数返回后,可以通过遍历fdset,来 找到就绪的描述符。
select目前几乎在所有的平台上支持,其良好跨平台支持也是它的一个 优点。select的一个缺点在于单个进程能够监视的文件描述符的数量存在最大限制,在Linux上一般为1024 ,可以通过修改宏定义甚至重新编译内核的 方式提升这一限制,但是这样也会造成效率的降低。
# 3 poll
不同于select使用三个位图来表示三个fdset的方式,poll使用一个 pollfd的指针实现。
pollfd结构包含了要监视的event和发生的event,不再使用select '参数-值'传递的方式。同时,pollfd并没有最大数量限制(但是数量过大后 性能也是会下降)。和select函数一样,poll返回后,需要轮询pollfd来获取就绪的描述符。
从上面看,select和poll都需要在返回后,通过遍历文件描述符来获取 已经就绪的socket。事实上,同时连接的大量客户端在一时刻可能只有很少的处于就绪状态,因此随着监视的描述符数量的增长,其效率也会线性下降

# 4 epoll
epoll是在linux2.6内核中提出的,是之前的select和poll的增强版本。相对 于select和poll来说,epoll更加灵活,没有描述符限制。epoll使用一个文 件描述符管理多个描述符,将用户关系的文件描述符的事件存放到内核的一个事件表中,这样在用户空间和内核空间的copy只需一次。

# 5 更好的例子理解
老师检查同学作业,一班50个人,一个一个问,同学,作业写完了没?select,poll
老师检查同学作业,一班50个人,同学写完了主动举手告诉老师,老师去检查 epoll

# 6 总结
在并发高的情况下,连接活跃度不高,epoll比select好,网站http的请求,连了就断掉
并发性不高,同时连接很活跃,select比epoll好,websocket的连接,长连接,游戏开发

并发并行,同步异步,阻塞非阻塞

# 1 并发
并发是指一个时间段内,有几个程序在同一个cpu上执行,但是同一时刻,只有一个程序在cpu上运行
跑步,鞋带开了,停下跑步,系鞋带
# 2 并行
指任意时刻点上,有多个程序同时运行在多个cpu上
跑步,边跑步边听音乐
# 3 同步:
指代码调用io操作时,必须等待io操作完成才返回的调用方式
# 4 异步
异步是指代码调用io操作时,不必等io操作完成就返回调用方式
# 6 阻塞
指调用函数时候,当前线程被挂起
# 6 非阻塞
指调用函数时候,当前线程不会被挂起,而是立即返回

# 区别:
同步和异步是消息通讯的机制
阻塞和非阻塞是函数调用机制
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: 库是否可行? 可以回答这个问题。Python线程调用异步库是可行的,但需要注意线程安全问题。异步库本身是为了解决 I/O 密集型任务而设计的,多线程可以提高 CPU 密集型任务的效率,但需要注意避免多线程之间的资源竞争和死锁等问题。建议使用 Python 的协程库 asyncio 来实现异步编程,同时使用 threading 或 multiprocessing 来实现多线程或多进程。 ### 回答2: Python中可以通过多线程调用异步操作来提高程序的并发能力和响应速度。 在Python中,可以使用`threading`模块来创建和管理多线程。多线程是一种并发执行的方式,它允许多个线程在同一时间内执行不同的任务。 同时,Python也支持异步编程,可以通过`asyncio`模块来进行异步操作。异步操作可以在等待某些IO操作完成时,让出CPU资源给其他任务,以提高效率。 我们可以将异步操作放在一个线程中进行执行。具体步骤如下: 1. 使用`threading`模块创建一个线程对象,并指定一个函数为线程的执行体。 2. 在该函数中,使用`asyncio`模块的相关方法来定义和执行异步操作,比如使用`async`关键字定义异步函数,使用`await`关键字阻塞等待异步操作的完成。 3. 启动线程,开始执行异步操作。 这样,我们就可以在一个线程中同时执行多个异步操作,提高程序的并发能力。 需要注意的是,由于Python的全局解释锁(GIL)的存在,使得多线程无法真正实现并行执行。因此,通过多线程调用异步来提高程序的性能,主要是通过异步操作的非阻塞特性来实现任务的并发执行,而不是真正的并行执行。 总结起来,Python通过多线程调用异步可以提高程序的并发能力和响应速度,但需要注意多线程无法真正实现并行执行的限制。 ### 回答3: Python中的多线程调用异步可以通过一些库和技巧来实现。 首先,要注意Python的全局解释器锁(GIL),它会限制同一时间只能有一个线程在解释器中执行Python字节码。因此,Python线程并不能真正实现并行计算,但可以用于处理I/O密集型任务。 要在Python中实现多线程调用异步,可以使用以下的方式之一: 1. asyncio库:asyncio是Python的异步I/O框架,它使用协程来实现异步编程。可以使用asyncio库在多个线程中调用异步函数。需要注意的是,在使用asyncio时,应该确保所有的I/O操作都是非阻塞的,否则会阻塞线程。 2. 多进程 + 异步库:Python中也可以通过多进程来实现并行的异步编程。可以使用multiprocessing库来创建多个进程,然后在每个进程中使用异步库来处理异步任务。 3. 线程池 + 异步库:Python中的concurrent.futures库提供了线程池和进程池的实现,可以通过线程池来实现多线程调用异步。可以使用ThreadPoolExecutor类来创建线程池,并将异步任务提交给线程池处理。 无论采用哪种方式,多线程调用异步都需要注意线程安全和资源共享的问题。需要使用锁和同步机制来保证线程安全,并避免竞态条件和死锁的发生。 综上所述,Python线程调用异步可以使用asyncio库、多进程和异步库、线程池和异步库等方式实现。具体选择哪种方式取决于实际需求和场景。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Lamb!

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值