1、Socket默认是否是阻塞的?阻塞体现在哪里?
Socket在默认情况下是阻塞的。阻塞体现在以下几个方面:
- 当对一个socket执行connect操作时,如果连接没有建立,程序会一直等待直到连接成功或失败。
- 当对一个socket执行recv操作时,如果没有数据可接收,程序会一直等待直到接收到数据。
2、如何将socket编程为非阻塞?
可以通过设置socket的阻塞选项来将其编程为非阻塞。
非阻塞
sock.setblocking(False)
3、IO多路复用的作用?
IO多路复用是一种处理多个IO操作的技术,它可以在单个线程中同时处理多个socket的IO操作。使用IO多路复用可以大大提高程序的效率和性能,因为不需要为每个socket创建一个新的线程或进程。检测多个socket是否发生変化。
操作系统检测socket是否发生変化,有三种模式(主要select.select、select.epoll):
select.select
(Windows支持)可以实现IO多路复用,它可以在多个socket之间进行轮询,以检测哪些socket可以进行读写操作。最多1024个socket;循环检测(水平触发)。- poll:不限制监听socket个数;循环检测(水平触发)。
select.epoll
(Windows不支持)是Linux系统下的IO多路复用实现方式,与select.select
类似,但是可以支持更多的socket数量。不限制监听socket个数;(回调方式触发)。
4、提高并发方案
4.1多线程
4.2多进程
4.3异步非阻塞模快(Twisted) ,scrapy框架(单线程完成并发)
什么是异步、非阻塞?
-非阻塞,不等待。 比如,创建socket对某个地址进行connec,获取连接、接收数据recv时默认都会等待;连接成功或接收到数据,才执行后面。
如果置setblocking(False),以上两个过程就不再等待,但是会抛出BlockingIOError的错误,只要捕获即可。
-异歩:通知,执行完成之后自动执行回调函数或自动执行某些操作(通知)。 比如做爬虫中向某个地址baidu.com发送请求,当请求执行完成之后自动执行回调函数。
Python模块:Twisted和Scrapy框架
- Twisted是一个异步网络框架,它提供了异步和非阻塞的编程模型,可以用于编写高性能的网络应用程序。
- Scrapy框架是一个基于Twisted的异步爬虫框架,它可以实现单线程并发爬取多个网站。
5、什么是同步阻塞?
同步阻塞是指程序按照顺序逐个执行任务,如果某个任务需要等待资源或数据就绪,程序会一直等待直到资源或数据就绪。例如,上面的代码示例中,程序会逐个遍历key list中的每个元素,并发送HTTP请求。如果请求需要等待响应,程序会一直等待直到响应返回。
python
import requests
key_list = ['xx','db','sb']
for item in key_list:
ret = requests.get('https://www.baidu.com/s?wd=%s' %item)
print(ret.text)
6、封装的例子和概念
在提供的代码中,有一个封装的概念示例:class Foo(object):
。在这个类中,__init__()
方法是构造函数,用于初始化对象的属性。append()
方法是对象的一个方法,用于向对象的数据列表中添加元素。通过实例化这个类并调用其方法,可以对列表进行操作。这种将操作和数据封装在一起的方式称为封装,这是面向对象编程中的一个重要概念。通过封装,可以隐藏对象的内部状态和实现细节,只暴露必要的接口,从而增强代码的可维护性和可复用性。
python
class Foo(object):
def __init__(self,data,girl):
self.row = data
self.girl = girl
def append(self,item):
self.row.append(item)
v=[Foo([11,22],'雪梨'),#毎个都有一个append方法
Foo([22,33],'冰糖'),#毎个都有一个append方法
Foo([33,44],'糖宝'),]#毎个都有一个append方法
for item in v:
item.append(123)
print(item.girl)