一文了解TTY子系统框架

二、TTY子系统框架

1、TTY子系统框架分析

该篇主要用来分析TTY子系统的框架,TTY框架图如下:

image-20221231220853840

TTY子系统位于标准字符驱动之下,其中包括:TTY核心层,TTY线路规程,TTY驱动层。

TTY Core:该核心层主要负责控制跨越一个tty设备的数据流和数据格式,使得TTY Driver能够以一致的方式处理 到硬件出自硬件 的数据。

TTY Line Discipline:线路规程,以特殊的方式对数据进行二次加工,通常表现为协议的转换,如:PPPBluetooth,以便可以虚拟的“插入”到任何tty设备。

TTY Driver:该层主要用于实现各类终端的驱动,用以控制实际硬件设备,用于收发数据。其有3种不通类型的驱动:**控制台,串口,pty**。其中,控制台和 pty 驱动已经被编写进内核。

下面是在网上的另一个TTY框架图,结合上图更加方便理解

image-20221021212536798

从上往下看,最上面是应用层,其次是字符设备驱动,然后是TTY核心层,TTY驱动层。

其中,

用户层:在用户空间,我们操作TTY的方法就是通过openreadwrite读写设备文件,如:/dev/tty/dev/console

通用字符设备驱动:对上,以字符设备驱动的形式,向应用程序提供统一接口open, read, write,以便输入输出数据

System Console Core:其主要有两个功能:

1)向系统提供控制台终端(Console Terminal) ,以便让用户登录进行交互操作。

2)提供printk功能,以便kernel代码进行日志输出。

System console core模块使用struct console结构抽象system console功能,具体的driver不需要关心console的内部逻辑,填充该接口并注册给kernel即可。

2、TTY数据处理流程

  • tty 核心从一个用户获取将要发送给一个 tty 设备的数据. 它接着传递它到一个 tty 线路规程驱动, 接着传递它到一个 tty 驱动. 这个 tty 驱动转换数据为可以发送给硬件的格式.
  • 从 tty 硬件收到的数据向上回流通过 tty 驱动, 进入 tty 线路规程驱动, 再进入 tty 核心, 在这里它被一个用户获取.
  • 有时 tty 驱动直接和 tty 核心通讯, 并且 tty 核心直接发送数据到tty 驱动, 但是大多数情况下 tty 线路规程有机会修改在 2 者之间发送的数据.

3、驱动的目录结构及核心文件

ketnel
│   └── driver
│   │   └── tty
│   │   │   └── serial  # 串口终端驱动  
│   │   │   │   └── 8250
│   │   │   │ │   ├── 8250_core.c  # 8250 串口核心层   
│   │   │   │ │   ├── 8250_port.c  # 8250 串口port抽象
│   │   │   │ │   ├── 8250_dma.c  # 8250 dma驱动
│   │   │   │ │   ├── 8250_dw.c  # 8250 device driver抽象 
│   │   │ └── vt   # 虚拟终端驱动
│   │   │ └── ipwireless # 无线终端驱动
│   │   │ └── hvc   # 虚拟控制台
│   │   │ ├── tty_xxx  #tty driver port 抽象
│   │   │ ├── n_xxx.c  # tty line discipline 线路规程相关文件

serial:该目录下为串口终端的驱动程序

hvc:hypervisor虚拟控制台

vt:目录下为虚拟终端的驱动程序

n_xxx.c:为线路规程的相关文件,也就是串口数据处理

tty_xxx:包括字符设备驱动的实现,ioctl

8250_xxx:为serial Driver

4、TTY在Linux下的分布

TTY是所有终端的统称,对于不同的终端,我们有不同的驱动程序,那么我们怎么知道当前系统中,哪个驱动被加载,哪个终端设备存在呢?

  • 查看所有终端

可以查看/proc/tty/drivers文件,这个文件可以包含当前存在的,不同tty驱动的列表,驱动的名字,驱动的主编号,次编号范围,tty驱动的类型。

/dev/tty             /dev/tty        5       0 system:/dev/tty
/dev/console         /dev/console    5       1 system:console
/dev/ptmx            /dev/ptmx       5       2 system
/dev/vc/0            /dev/vc/0       4       0 system:vtmaster
usbserial            /dev/ttyUSB   188   0-254 serial
serial               /dev/ttyS       4   64-67 serial
pty_slave            /dev/pts      136   0-255 pty:slave
pty_master           /dev/ptm      128   0-255 pty:master
pty_slave            /dev/ttyp       3   0-255 pty:slave
pty_master           /dev/pty        2   0-255 pty:master
unknown              /dev/tty        4    1-63 console
  • 设备模型的角度

所有当前注册的以及在内核中出现的tty设备,有他们自己的子目录 /sys/class/tty下面。

在他们tty设备的子目录下面的文件夹中,有一个dev文件,包含了分配给tty设备的主次编号。 如果驱动程序告诉内核与tty设备相关联的物理设备和驱动程序的位置,它就会创建回这些位置的符号链接。

/sys/class/tty/
|-- console
|   `-- dev
|-- ptmx
|   `-- dev
|-- tty
|   `-- dev
|-- tty0
|   `-- dev
   ... 
|-- ttyS1
|   `-- dev
|-- ttyS2
|   `-- dev
|-- ttyS3
|   `-- dev
   ...
|-- ttyUSB0
|   |-- dev
|   |-- device -> ../../../devices/pci0000:00/0000:00:09.0/usb3/3-1/3-1:1.0/ttyUSB0
|   `-- driver -> ../../../bus/usb-serial/drivers/keyspan_4
|-- ttyUSB1
|   |-- dev
|   |-- device -> ../../../devices/pci0000:00/0000:00:09.0/usb3/3-1/3-1:1.0/ttyUSB1
|   `-- driver -> ../../../bus/usb-serial/drivers/keyspan_4
|-- ttyUSB2
|   |-- dev
|   |-- device -> ../../../devices/pci0000:00/0000:00:09.0/usb3/3-1/3-1:1.0/ttyUSB2
|   `-- driver -> ../../../bus/usb-serial/drivers/keyspan_4
`-- ttyUSB3
    |-- dev
    |-- device -> ../../../devices/pci0000:00/0000:00:09.0/usb3/3-1/3-1:1.0/ttyUSB3
    `-- driver -> ../../../bus/usb-serial/drivers/keyspan_4
  • 字符设备的角度

每个tty设备都有一个struct cdev,以便用户空间可以访问。

/dev/tty

/dev/console

/dev/ttyS0

OK,TTY子系统框架以及目录结构分析就先了解到此,后续分析其主要的数据结构!

本文转载于网络 如有侵权请联系删除

相关文章

  • Mip22:一款高级网络钓鱼安全测试工具

    关于Mip22Mip22是一款功能强大的高级网络钓鱼安全测试工具,在该工具的帮助下,广大研究人员可以研究和测试组织内部抵御网络钓鱼攻击的能力和抗风险等级。该工具出于安全研究和教育目的而开发,请在授权测试的情况下使用该工具。功能介绍Mip22是一款先进的网络安全工具,适用于运行了GNU/Linux操作系统的计算机、平板电脑和Android设备。该工具支持以下技术方法和服务:1、自动化测试方法 2、手动测试方法 3、隧道配置 4、邮件服务 5、VPN指令 6、音频效果(适用于PC)工具安装在GNU/Linux操作系统上安装广大研究人员可以打开命令行终端窗口,然后运行下列命令将该项目源码克隆至本地,并给相应的脚本提供可执行权限:sudosu gitclonegit://github.com/makdosx/mip22.git chmod-R777mip22 cdmip22 bashmip22.sh复制在Android操作系统上安装打开Termux后,运行下列命令将该项目源码克隆至本地,并给相应的脚本提供可执行权限:gitclonegit://github.com/makdosx/mi

  • 只需一键!AI续写贝多芬未竟的《第十交响曲》

    【新智元导读】一位专注于用DL开发音乐的瑞士程序员用DL全自动续写了贝多芬的第十交响乐,并且把乐谱交给了瑞士洛桑管弦乐团向公众演奏。当管弦乐团指挥GuillaumeBerney挥下开场的第一个强拍时,瑞士洛桑音乐厅里响起的第一个和弦可能来自于贝多芬没有完成的《第十交响曲》。一般认为,现存的贝多芬《第十交响曲》底稿只有第一乐章的大部分,其后的部分则缺失。古典音乐界经常猜测贝多芬(Beethoven)在他的不朽的《第九交响曲》之后会继续创作什么,许多音乐学家和作曲家已经大胆为他续写了想象的乐谱片段。为了庆祝成立10周年,Berney和Nexus管弦乐队(BerneyandtheNexusorchestra)决定用人工智能制作一个四分钟的片段,并将其命名为“BeethovANNSymphony10.1”。创建它的人工神经网络基本上没有人工干预。“我们不知道这听起来会是什么样子,”伯尼在洛桑音乐会前向法新社承认。计算机程序设计师FlorianColombo花费了数年完成了这个神经网络,而配乐的最终版本在演出前几个小时才生成并打印出来。就像看着孩子出生坐在他的小公寓里,科伦坡可以看到洛桑老城和远

  • Python提取 “Excel文本框” 内容,这个需求头一次见,1000个表,10行代码!

    作者:黄伟呢来源:快学Python本文简介说实话,这个需求头一次碰到,黄同学相信对于大多数朋友来说,也是头一次碰到。“提取excel文本框中的内容”,对,你没有听错!我也不知道你碰到过没有,但是这确实是一位朋友提出的很好的问题。说实话,Python操作excel的库很多,但是我几乎没有找到实现这个需求的api。比如说,我最常使用的openpyxl库,也没有这个功能。最后查阅一番,只有xlwings这个库了!注意:这个库是第三方库,大家一定要提前安装,并且一定要使用最新版本!最新版本!最新版本!不然有些方法你无法使用。#打开cmd窗口,安装xlwings库 pipinstallxlwings #使用xlwings库之前,需要提前导入 importxlwingsasxw复制xlwings库相关知识首先,咱们看到的的xw.App()是xlwings库中的一个函数。xw.App(visible=False,add_book=False)复制其中:visible:True表示启动excel程序后显示程序窗口。如果为False,表示启动excel程序后,程序窗口在后台运行;add_book:Tr

  • 某厂面试:如何优雅使用 SPI 机制

    代码不多,文章可能有点长。朋友面试某厂问到的SPI机制,联想到自己项目最近写到的SPI场景,文章简要描述下SPI机制的发展历程产出背景 因为最近项目中使用分库分表以及数据加密使用到了ShardingSphere,所以决定这段时间看看源码实现。问我为什么要读源码?不看源码怎么提高逼格嘞,就是这么朴实无华~考虑到自己看微信文章的习惯,不喜欢代码太多的,看着逻辑有点不清晰。所以,以后的文章风格就是,少贴代码,画图+BBSharding-JdbcSPI看源码的历程,往往从点开Jar包的瞬间开始。好巧不巧,就看到源代码包下有个SPI包,处于好奇心就点了一点,嗯~代码果然很熟悉,还是那个配方原来的味道看了许久,陷入深深的沉思。内心小九九:这玩意好像之前看过,但是在哪我忘了,这到底是个啥?代码还是那个代码,只是它认识我,我不认识它了这一块的SPI接口是shrding-jdbc预留自定义加密器的接口看到这里相信就遇到过绝大多数技术同学都会遇到的一个问题,那就是认为自己会了,实际情况呢?不一定。所以,学习一门技术,一定要多看几遍,尝试去理解记忆。千万不要看一遍之后,眼高手低认为技术soeasy,然后隔十

  • OSPF详解-3 邻接、度量值

    **一、OSPF邻接关系 运行链路状态路由协议的路由器必须首先与选定的邻居路由器建立邻接关系,这是通过与邻居路由器交换Hello分组来实现的。1.邻接路由器建立步骤路由器建立邻接关系的步骤如下:1)路由器将Hello分组发送给邻居路由器,并接收来自邻居路由器的Hello分组。Hello分组的目标地址通常是组播地址。2)路由器通过交换Hello分组来获悉协议特定的参数,如检查邻居是否位于同一个区域中,Hello间隔是否相等。交换完Hello分组后,路由器宣称邻居处于正常运行状态。3)两台路由器使用Hello分组建立邻接关系后,它们通过LSA来同步LSDB,并确认已收到邻接路由器的LSA。至此,两台邻接路由器知道它们的LSDB已经同步。对OSPF而言,这意味着两台路由器已经处于完全邻接状态。4)必要时,路由器将新的LSA转发给其他邻接路由器,确保在整个区域内,链路状态信息都是完全同步的。2.点到点邻接点到点串行链路上的两台路由器之间建立完全邻接的关系,它们使用的封装类型通常是高级数据链路控制(HDLC)或点到点协议(PPP)。然而,在LAN链路等广播网络上,将选举一个指定路由器(DR)和一

  • Python踩坑指南(第二季)

    本期围绕jieba讲一个我遇到的实际问题,在同一个服务里,存在两个不同接口A和B,都用到了jieba分词,区别在于两者需要调用不同的词库,巧合中,存在以下情况:词库A:"干拌面" 词库B:"干拌","面"复制在服务启动的时候,由于词库A优先被加载了,再去加载词库B的时候发现,并没有加载成功:接口A中:jieba.load_userdict("A.txt")复制接口B中:jieba.load_userdict("B.txt")复制结果发现,在切干拌面这个词的时候,接口B中还是没有切成功。其实每次在我们加载jieba的时候,可以注意一下会出现以下info:Buildingprefixdictfromthedefaultdictionary... Dumpingmodeltofilecache/var/folders/hv/kfb7n4lj06590hqxjv6f3dd00000gn/T/jieba.cache Loadingmodelcost0.824seconds. Prefixdicth

  • DeepMind最新深度学习研究:超参选择利器-引入基于群体的训练

    【导读】机器学习的训练和优化是现代深度学习模型中最具有挑战性的方面,本文首先介绍了常用的深度学习超参数优化方法:随机搜索和手动优化,然后引入DeepMind关于深度学习模型超参数优化的最新研究进展:基于群体的训练(populationbasedtraining),它能够在更短的时间和更低的计算资源占用的情况下找到好的超参.相信会被引入到更多的深度学习框架中,文末附有paper地址和GitHub地址,感兴趣的朋友可以详细了解一下。What’sNewinDeepLearningResearch:IntroducingPopulationBasedTraining深度学习研究的新进展:基于群体的训练深度学习模型的训练和优化是任何现代机器智能(MI)解决方案中最具挑战性的方面。在许多情况下,数据科学家能够迅速为特定问题找到正确的算法集,然后要花费若干月找到模型的最优解。最近,DeepMind发表了一篇新的研究论文,其中提出了一种新的方法,用于训练和优化深度学习模型——称为基于群体的训练(populationbasedtraining)。传统深度学习模型的优化致力于:在避免急剧改变模型的核心组件

  • 统计学习方法概论

    1.统计学习统计学习的对象是数据,它从数据出发,提取数据的特征,抽象出数据的模型,发现数据中的知识,又回到对数据的分析与预测中去。统计学习关于数据的基本假设是同类数据具有一定的统计规律性,这是统计学习的前提。统计学习的目的就是考虑学习什么样的模型和如何学习模型。统计学习方法包括模型的假设空间、模型选择的准则以及模型学习的算法。实现统计学习的步骤如下:(1)得到一个有限的训练数据集合;(2)确定包含所有可能的模型的假设空间,即学习模型的集合;(3)确定模型选择的准则,即学习的策略;(4)实现求解最优模型的算法,即学习的算法;(5)通过学习方法选择最优模型;(6)利用学习的最优模型对新数据进行预测或分析。2.监督学习监督学习从训练数据中学习模型,对测试数据进行预测,训练集通常表示为人们根据输入、输出变量的不同类型,对预测任务给予不同的名称:输入变量和输出变量均为连续变量的预测问题称为回归问题;输出变量为有限个离散变量的预测问题称为分类问题;输入变量与输出变量均为变量序列的预测问题称为标注问题。监督学习假设输入与输出的随机变量X和Y遵循联合概率分布P(X,Y),P(X,Y)表示分布函数,或分

  • Java并发编程的艺术(十一)——线程池(2)

    Executor两级调度模型 在HotSpot虚拟机中,Java中的线程将会被一一映射为操作系统的线程。 在Java虚拟机层面,用户将多个任务提交给Executor框架,Executor负责分配线程执行它们; 在操作系统层面,操作系统再将这些线程分配给处理器执行。Executor结构 Executor框架中的所有类可以分成三类:任务 任务有两种类型:Runnable和Callable。任务执行器 Executor框架最核心的接口是Executor,它表示任务的执行器。 Executor的子接口为ExecutorService。 ExecutorService有两大实现类:ThreadPoolExecutor和ScheduledThreadPoolExecutor。执行结果 Future接口表示异步的执行结果,它的实现类为FutureTask。线程池Executors工厂类可以创建四种类型的线程池,通过Executors.newXXX即可创建。1.FixedThreadPoolpublicstaticExecutorServicenewFixedThreadPool(intnThread

  • apache域名绑定(appserv环境)

    假定你的服务器网站根目录下有两个子目录,一个为/appserv/www/web01,另一个为/appserv/www/web02。现在你想访问www.web01.com对应的目录是/appserv/www/web01,访问www.web02.com对应的目录是/appserv/www/web02。1.为你的服务器ip绑定连个域名分别为:www.web01.com;www.wei02.com (这个在服务器管理面板里可以设置。)2.打开appserv\apache\conf\httpd.conf文件,搜索 “Include conf/extra/httpd-vhosts.conf”,去掉前面的#号,这是为了引入了httpd-vhosts.conf虚拟主机配置文件。3.打开虚拟主机配置文件appserv\apache\conf\extra\httpd-vhosts.conf:去掉NameVirtualHost *:80 前面的#号,这是为了启用httpd-vhosts.conf文件,使原来httpd.conf中默认的配置失效。4.在httpd-vhosts.conf里面添加如下代码:<

  • antd4与antd3Form表单设计区别

    核心antd3思想:使用HOC(高阶组件)包裹form表单,HOC组件中的state存储所有的value值,定义设置值和获取值的方法 缺点:动一发牵全身,一个value值改变,因为这是顶级状态,所以所有的子组件都会因父组件的重新render而render,浪费了性能antd4思想:使用Context包裹form表单,自定义一个store类,存储所有的表单value值,定义设置值和获取值得方法,因为不是组件内部状态,需要自己定义更新函数,在每个Form.Item中定义forceUpdate()强制更新函数,当我们setValue值得时候,根据name值判断出要更新的Form.Item,可以调用该Item的更新函数更新,相比ant3节约了性能(个人觉得这个思想类似Vue了,涉嫌抄袭) ant4简单原理展示 基本用法,拷贝整理下可测试//FormPage页面函数组件和类组件略有差异,类组件会用到神奇的React.forwardRefapi和useImperativeHandlehook8l importReact,{useEffect,Component}from'react&#x

  • 逃逸分析(Escape Analysis)详解

    概念说明    逃逸分析,是一种可以有效减少Java程序中同步负载和内存堆分配压力的跨函数全局数据流分析算法。通过逃逸分析,JavaHotspot编译器能够分析出一个新的对象的引用的使用范围从而决定是否要将这个对象分配到堆上。逃逸分析的基本行为就是分析对象动态作用域。逃逸类型  方法逃逸(对象逃出当前方法)      当一个对象在方法中被定义后,它可能被外部方法所引用,例如作为调用参数传递到其他地方中。  线程逃逸((对象逃出当前线程)      这个对象甚至可能被其它线程访问到,例如赋值给类变量或可以在其它线程中访问的实例变量。使用逃逸分析  编译器可以对代码做如下优化: 同步省略或锁消除(SynchronizationElimination)。如果一个对象被发现只能从一个线程被访问到,那么对于这个对象的操作可以不考虑同步。将堆分配转化为栈分配(StackAllocation)。如果一个对象在子程序中被分配,要使指向该对象的指针永远不会逃逸,对象可能是栈分配的候选,而不是堆分配。分离对象或标量替换(ScalarReplacement)。有的对象可能不需要作为一个连续的内存结构存在也可

  • count(1) count(*)

    count详解 count(*)、count(1)将返回表格中所有存在的行的总数包括值为null的行 而count(列名)将返回表格中除去null以外的所有行的总数(有默认值的列也会被计入) distinct列名,得到的结果将是除去值为null和重复数据后的结果。 count(1)与count(*)比较 从执行计划来看,count(1)和count(*)的效果是一样的。但是在表做过分析之后,count(1)会比count(*)的用时少些(1w以内数据量),不过差不了多少。  如果你的表只有一个字段的话那count(*)就是比较快。 如果count(1)是聚集索引:id,那肯定是count(1)快。但是差的很小的。  因为count(*)自动会优化指定到那一个字段。所以没必要去count(1),用count(*),sql会帮你完成优化的因此:count(1)和count(*)基本没有差别!    count(1)andcount(字段) count(1)中的1并不是指第一个column 两者的主要区别是 (1)count(1)会统计表中的所有的记录

  • clickhouse

    hive-to-clickhouse hive->logstash->kafka->clickhouse logstash.conf input{ jdbc{ jdbc_driver_library=>"jars/hive-jdbc-2.1.1.jar,jars/libthrift-0.9.3.jar,jars/httpclient-4.4.jar,jars/httpcore-4.4.jar,jars/hive-service-2.1.1.jar,jars/hive-common-2.1.1.jar,jars/hive-metastore-2.1.1.jar,jars/hadoop-common-2.8.3.jar,jars/commons-logging-1.2.jar,jars/log4j-slf4j-impl-2.4.1.jar,jars/hive-service-rpc-2.1.1.jar,jars/commons-lang-2.6.jar,jars/commons-lang3-3.1.jar,jars/protobuf-java-2.5.0.jar,

  • [BZOJ3293] [Cqoi2011] 分金币 (贪心)

    Description   圆桌上坐着n个人,每人有一定数量的金币,金币总数能被n整除。每个人可以给他左右相邻的人一些金币,最终使得每个人的金币数目相等。你的任务是求出被转手的金币数量的最小值。 Input   第一行为整数n(n>=3),以下n行每行一个正整数,按逆时针顺序给出每个人拥有的金币数。 Output    输出被转手金币数量的最小值。 SampleInput 4 1 2 5 4 SampleOutput 4   样例解释   设四个人编号为1,2,3,4。第3个人给第2个人2个金币(变成1,4,3,4),第2个人和第4个人分别给第1个人1个金币。 HINT   N<=100000,总金币数<=10^9 Source Solution   同$BZOJ1045$,数据范围还小了不少,,,题解在这 1#include<bits/stdc++.h> 2usingnamespacestd; 3longlonga[100005],s[100005]; 4intmain() 5{ 6intn; 7longlong

  • 数据安全相关的专业术语

    本文不详细介绍具体的加密算法,仅仅罗列数据安全领域常见的专业术语,并作出简要释义和说明。大概可以分成两大类,一类是参与的相关方(就是人),另一类则是冷冰冰的词汇了。 密码学(cryptography)密码学是通过把消息编码使其不可读从而获取安全性的艺术与科学。 发送者(Sender)在传递消息的过程中,发出信息的一方被称为发送者,可以是人也可以是机器。 **接收者(receiver)**在传递消息的过程中,收到信息的一方被称为接收者,和发送者一样,接收者可以是具体的人或者是一台机器。 **消息(message)**传递的信息通常被称为消息,消息可以是字符串、文本、图片、音频、视频等数据。 窃听者(eavesdropper)发送者在把消息发送给接收者的时候,因为消息需要在在多个设备之间进行中转,所以在传达的过程中消息可能会被恶意的偷看,偷看消息内容的个体我们称为窃听者。 明文|原文(plaintext)基于安全方面的考量,在开发中进行数据交互的时候通常我们会对一些敏感的用户隐私数据进行加密处理,需要进行加密的消息我们称为明文或者是原文。 密文(ciphertext)采用特定方式对

  • Git-Tagging

    目录Git-Tagging1.ListingYourTags1.1Listingtheexistingtags1.2searchfortags1.3pulltags2.CreatingTags2.1AnnotatedTags2.2LightweightTags3.TaggingLater4.SharingTags5.DeletingTags6.CheckingoutTags Git-Tagging 1.ListingYourTags 1.1Listingtheexistingtags //任意一中 $gittag $gittag-l $gittag--list //执行结果 v1.0 v2.0 v2.1.0 v2.1.1 v2.1.2 v2.1.3 v2.2.0 v2.2.1 v3.0 v3.1 ... 复制 1.2searchfortags $gittag-l"v2.1*" //执行结果 v2.1.0 v2.1.1 v2.1.2 v2.1.3 复制 如果需要用到通配符,必须携带-l或则--list 1.3pulltags 获取远程tags,直接执行gitfetch即可 $g

  • 皮克斯

    所以图形学是重现未拍照片的技术吗

  • 列表推导式练习

    列表为L=[[1,2,3],[4,5,6],[7,8,9]] 需求1:输出[1,4,7] 需求2:输出[1,5,9] 实现方式: 1、需求1 (1)常规方法 L=[[1,2,3],[4,5,6],[7,8,9]]result1=[] foriinL: result1.append(i[0]) print(result1)复制 (2)列表推导式 L=[[1,2,3],[4,5,6],[7,8,9]] result=[i[0]foriinL] print(result)复制 2、需求2: (1)常规方法 L=[[1,2,3],[4,5,6],[7,8,9]] result3=[] foriinrange(len(L)): result3.append(L[i][i]) print(result3)复制 (2)列表推导式 L=[[1,2,3],[4,5,6],[7,8,9]]result2=[L[i][i]foriinrange(len(L))]print(result2)复制   Keepempoweringyourselfsuccessfully...

  • 草原上的卓玛壁纸.jpg

     

  • 读懂Netty的高性能架构之道

    Netty是一个高性能、异步事件驱动的NIO框架,它提供了对TCP、UDP和文件传输的支持,作为一个异步NIO框架,Netty的所有IO操作都是异步非阻塞的,通过Future-Listener机制,用户可以方便的主动获取或者通过通知机制获得IO操作结果。 作为当前最流行的NIO框架,Netty在互联网领域、大数据分布式计算领域、游戏行业、通信行业等获得了广泛的应用,一些业界著名的开源组件也基于Netty的NIO框架构建。 为什么选择Netty Netty是业界最流行的NIO框架之一,它的健壮性、功能、性能、可定制性和可扩展性在同类框架中都是首屈一指的,它已经得到成百上千的商用项目验证,例如Hadoop的RPC框架avro使用Netty作为底层通信框架;很多其他业界主流的RPC框架,也使用Netty来构建高性能的异步通信能力。 通过对Netty的分析,我们将它的优点总结如下: API使用简单,开发门槛低; 功能强大,预置了多种编解码功能,支持多种主流协议; 定制能力强,可以通过ChannelHandler对通信框架进行灵活地扩展; 性能高,通过与其他业界主流的NIO框架

相关推荐

推荐阅读