精华内容
下载资源
问答
  • 2019.08.09,华为其全球开发者大会上,正式向全球发布了全新的自有系统 HarmonyOS 鸿蒙——基于微内核的面向全场景的分布式操作系统。余承东现场表示, HarmonyOS...

    2019.08.09,华为在其全球开发者大会上,正式向全球发布了全新的自有系统 HarmonyOS 鸿蒙——基于微内核的面向全场景的分布式操作系统。余承东在现场表示, HarmonyOS 鸿蒙拥有分布架构、内核安全、生态共享、天生流畅四大优势,概括起来就是自研,速度快,安全,手机、汽车、智能家居等场景都可以用。

    从1946年第一台计算机诞生在宾夕法尼亚大学到现在,整个操作系统的发展就是一部相互纠缠不清、你中有我,我中有你的、包含各种爱恨情仇的进化史。全文比较长,希望大家能耐心读完。

    本应该是兄弟,但成了宿敌

    1981年,当乔布斯兴致冲冲的带着自己的好友比尔盖茨参观苹果新推出的图形操作系统麦金塔(Macintosh)的时候,他并不知道自己犯下多大的错误,把图形界面操作系统这样跨世纪的产品展示给了一个最不该告诉的人,这也为他们今后成为竞争对手埋下了种子。

    乔布斯的本意是想让比尔盖茨的微软为苹果新推出的麦金塔(Macintosh)计算机开发配套的应用软件,但是在演示时,比尔盖茨被麦金塔的图形操作界面和灵活方便的鼠标操作吸引,在心里盘算着定下了未来微软DOS系统的发展方向。

    回到公司后,比尔盖茨组建了两个项目组,一个为苹果的新系统开发配套的应用软件,一个研究开发微软的图形操作系统。这两个项目的结果,就是我们后来耳熟能详的Office(Word、Excel、PPT)办公软件和Windows操作系统。

    而麦金塔(Macintosh)系统则逐步演进,诞生了Darwin,MacOS,iOS等操作系统,用于我们现在的苹果电脑、苹果手机和苹果iPad。

    乔布斯和比尔盖茨

    偷师施乐的两个小偷

    对于比尔盖茨「剽窃」苹果图形界面操作系统的想法其实并不稀奇,就在这一年的2年前,也就是1979年,苹果的乔布斯带领苹果的技术和管理人员参观了施乐帕洛阿尔托研究中心。当施乐的工程师拉里·泰斯勒向他们演示图形界面和鼠标应用的时候,乔布斯就知道这是革命性的,这是未来个人计算机的发展方向,回到平果后,乔布斯就指示技术人员开始研究。

    说「偷」并不恰当,不管是对于乔布斯还是比尔盖茨,对于这类人来说,只要他们知道有这么个东西,并且证明被证明时可行的就对了。当然,苹果和微软在研发自己的图形操作系统的时候,都从施乐挖了大量的人员,这是后话。

    苹果的麦金塔计算机

    操作系统的鸿蒙时代

    并不是1946年发明了第一台计算机的时候就有了操作系统,那时候并没有。操作系统是人们在使用计算机的过程中,为了更好的提高资源利用率,增强计算机的性能,降低使用的复杂度,逐步发展起来的。

    未出现操作系统的时候,计算机的工作都是手工操作的,就是我们常听说的穿孔纸带,用手操作输入,计算机处理输出。这种方式刚开始还好,计算机没那么快吗,所以手工还可以跟得上,随着计算机硬件的发展,手工反而成了瓶颈,手速跟不上了,这是不能容忍的,因为这大大的降低了计算机的效率。

    要想提升效率,必须要摆脱手工操作,于是开始出现操作系统,最早出现的操作系统是批处理系统,可以自动的将工作建置、调度和序列化运行等工作。

    早期的操作系统是每一台不同型号的都有自己不同的操作系统,因此编写的程序都是特定计算机上使用的,无法移植到其他的计算机。还是发展的需要,到1964年,IBM推出了都共享同一操作系统的计算机,这样单一的操作系统就可以适用于整个System/360系列的计算机,这也为以后的操作系统发展提供了方向。

    1970年,AT&T贝尔实验室的丹尼斯·里奇与肯·汤普逊所创建的Unix系统,成为了以后大部分操作系统的鼻祖,比如苹果的、Android(安卓)的,Linux(Ubuntu、小红帽等),当然微软的MS-DOS和Window不是。

    1980年代前是操作系统诞生、起步的鸿蒙时代,这之后,尤其是Unix系统的诞生拉开了操作系统的诸侯争霸时代。

    贝尔实验室

    个人计算机双雄

    当前,我们看到的个人计算机,主要有两大类,一类时IBM兼容PC机,就是我们经常见到的电脑,组装电脑,组装机,笔记本;还有一类是Apple Macintosh ,也就是我们常说的苹果电脑,苹果笔记本。这两大计算机对应的操作系统一个就是我们常见的Windows操作系统,一个就是苹果操作系统,他们的老大一个是比尔盖茨、一个是乔布斯,很好的一对CP。

    微软1975年成立,发迹于为IBM PC个人机提供操作系统,这款操作系统就是通过收购改装的MS-DOS,依赖和IBM的绑定,微软赚了很多钱。

    如果我们也把MS-DOS看做软件,那么微软其实是一家软件公司(他们一直这么认为),这也就是为什么后来乔布斯要找微软帮其麦金塔计算机开发配套的应用软件的原因,微软的实力的确很强大。当然这次合作,也成了他们以后爱恨情仇的基础。

    微软的操作系统是和Unix不一样的,全新的操作系统。早期的Windows是基于MS-DOS架构的,一直用到Window 98、ME;后期的Windows是基于Window NT架构的,包括目前大家用的Window 7,8和10。

    苹果成立于1976年,主要产品有Apple I,Apple II以及后来的Macintosh。苹果的产品都是集成硬件、系统和软件一体的,和微软不一样,微软只有操作系统和软件,不做硬件。

    苹果早期的麦金塔操作系统是基于Mach内核的,后来为了解决诸多版本的问题,改为基于BSD Unix的内核,所以苹果的系统并不是全新的系统,也是类Unix的,所以我们很多Linux的软件也可以在苹果电脑里使用。

    后面苹果的发展,出现了iPod,iPhone,iPad这些产品,其实他们的操作系统差不多,都是基于麦金塔的修改,以更好的在不同的场景上发挥出更好的性能。

    作为面向个人用户场景的双雄,在这个赛道竞争非常激烈,你方上吧我登场,两个公司不光在个人计算机,在智能移动设备上也是打的火热,各有胜负,既生瑜何生亮。

    Mac VS Windows

    BSD Unix和Linux的爱恨情仇

    在这个世界里,既然有对就有错;有好就有坏;有矛就有盾;有商业,就有开源。在开源的世界里BSD的Unix和GNU的Linux影响深远,但这两个操作系统和贝尔实验室也有爱恨情仇。

    Linux的爸爸林纳斯·托瓦兹曾说,当时如果有可自由使用的386BSD,他就可能不会编写Linux,这是什么梗?要了解这段爱恨情仇,就要从BSD Unix和贝尔实验室的官司说起。

    我们上面提到过,Unix是贝尔实验室开发的操作系统,它是一个商业系统,不是随便就可以免费使用的。当时的贝尔实验室可能为了推广Unix,也可能是因为没有意识到Unix的价值,所以就以低廉甚至免费的价格把Unix源代码授权给很多研究机构和院校使用,这些机构和院校对Unix加以修改和扩展,就形成了所谓的「Unix 变种」,也就是类Unix,类Unix中最著名的就是加州大学柏克莱分校开发的BSD Unix。

    随着BSD Unix广泛的被使用,贝尔实验室也意识到Unix的商业价值,所以贝尔实验室就对之前的Unix和延伸变种申请了著作权权利,然后就开始了一场之久的著作权官司。

    这场官司一直打到1992年还没解决,远在芬兰正在就读赫尔辛基大学的林纳斯·托瓦兹这位小朋友坐不住了,这不行啊,不能自由的折腾操作系统了,你们打个毛啊,还能好好的玩耍不?于是乎,林纳斯·托瓦兹自己冲冠一怒,花了几个月的时间开发了自己的操作系统Linux。我只想说,同时九年义务教育,你咋这么优秀。

    Linux是一个自由开放源码的类Unix操作系统,基于GNU 通用公共许可证(GPL)协议,可以被自由使用,也可以用于商业,这对整个操作系统的发展做出了很大的贡献。Linux延伸的操作系统如服务器系统Red Hat(小红帽)、Centos、个人桌面系统Ubuntu以及移动操作系统Android(安卓)等,已经被广泛的用于各行各业,为了感谢林纳斯·托瓦兹的贡献,Red Hat及VA Linux这两家公司给了他价值2000万美元的股票期权。

    Linus Torvalds

    功能手机的没落,智能手机的崛起

    直到2007年,手机一直是诺基亚的天下,移动操作系统也被诺基亚的Symbian(塞班)系统独占鳌头,其他黑莓、Window Mobile等都是小头,塞班系统是当之无愧的大哥大,被无数开发者追捧。

    这一切直到iPhone 2007年横空出世,触摸式的操作,大大提升了用户体验,手机没有按键,没想到手机还能这么玩。

    iPhone的搭配的操作系统是iOS,被用于苹果的移动设备上,如iPad、iPhone、iTouch等。iOS移动操作系统是基于Darwin的,这也是一个类Unix的操作系统。但是iOS本身是闭源的,没有开放。

    基于iOS移动操作系统,开发者为其iOS开发软件,通过AppStore发布获取收益,同时为iOS用户(iPhone、iPad用户)提供软件服务,丰富用户的体验,苹果打造了属于它自己的整个移动生态环境。

    苹果手机的崛起,标志着以诺基亚为代表的功能机的没落,以苹果为代表的智能机的崛起。

    Nokia

    苹果和谷歌的裂痕

    苹果封闭的生态,高昂的价格,也给其他竞争者留下了发展的空间,同样是2007年,Google(谷歌)联合其他84家硬件制造商成立了「开放手持设备联盟」共同研发和改良Android(安卓),Google以Apache的协议开放了Android的源代码,这样所有的第三方生产商如华为、小米等都可以基于Android操作系统来制造自己的智能手机,并且价格比苹果低,这大大加速了Android(安卓)的普及,形成了和iOS两足鼎立的现代移动智能操作系统的局面。

    Android(安卓) ,2003年10月由安迪·鲁宾(Andy Rubin)创建,是一款基于Linux的移动智能操作系统,2005年被Google以高于5000万美元的价格收购,自此成为Google进军移动领域的核武器。

    Google和苹果本来是很好的很作伙伴,两家公司在地图、搜索等方面有着很好的合作,但是因为Android(安卓)和iOS,安卓手机和苹果手机,两家公司有了裂痕,这也说明,没有永远的朋友,只有永远的利益。

    Android Apple

    行业不能被打败,只能被颠覆

    一部操作系统发展史,一部爱恨情仇进化史,分分合合,合合分分,你衍生了我,我终结了你,无法适应时代的就要被颠覆,也只能被颠覆,改是改不好的,华为深谙此道,所以发布会说鸿蒙系统是基于微内核的面向全场景的分布式操作系统,不同于Android和iOS,所以我们也期待着。

    本文为原创文章,转载注明出处,欢迎扫码关注公众号`flysnow_org`或者网站http://www.flysnow.org ,第一时间看后续精彩文章。觉得好的话,请猛击文章右下角「在看」,感谢支持。

    扫码关注

    展开全文
  • !MySQL 82 张图带你飞

    千次阅读 2021-01-26 09:27:24
    之前两篇文章带你了解了 MySQL 的基础语法和 MySQL 的进阶内容,那么这篇文章我们来了解一下 MySQL 的高级内容。 其他文章: 138 张图带你 MySQL 入门 47 张图带你 MySQL 进阶!!! 炸!MySQL 82 张图带你飞! ...

    之前两篇文章带你了解了 MySQL 的基础语法和 MySQL 的进阶内容,那么这篇文章我们来了解一下 MySQL 中的高级内容。

    其他文章:

    138 张图带你 MySQL 入门

    47 张图带你 MySQL 进阶!!!

    炸裂!MySQL 82 张图带你飞!

    本文思维导图如下。

    事务控制和锁定语句

    我们知道,MyISAM 和 MEMORY 存储引擎支持表级锁定(table-level locking),InnoDB 存储引擎支持行级锁定(row-level locking),BDB 存储引擎支持页级锁定(page-level locking)。各个锁定级别的特点如下

    页级锁:销和加锁时间界于表锁和行锁之间;会出现死锁;锁定粒度界于表锁和行锁之间,并发度一般

    表级锁:表级锁是对整张表进行加锁,MyISAM 和 MEMORY 主要支持表级锁,表级锁加锁快,不会出现死锁,锁的粒度比较粗,并发度最低

    行级锁:行级锁可以说是 MySQL 中粒度最细的一种锁了,InnoDB 支持行级锁,行级锁容易发生死锁,并发度比较好,同时锁的开销也比较大。

    MySQL 默认情况下支持表级锁定和行级锁定。但是在某些情况下需要手动控制事务以确保整个事务的完整性,下面我们就来探讨一下事务控制。但是在探讨事务控制之前我们先来认识一下两个锁定语句

    锁定语句

    MySQL 的锁定语句主要有两个 LockunLock,Lock Tables 可用于锁定当前线程的表,就跟 Java 语法中的 Lock 锁的用法是一样的,如果表锁定,意味着其他线程不能再操作表,直到锁定被释放为止。如下图所示

    lock table cxuan005 read;
    

    我们锁定了 cxuan005 的 read 锁,然后这时我们再进行一次查询,看看是否能够执行这条语句

    select * from cxuan005 where id = 111;
    

    可以看到,在进行 read 锁定了,我们仍旧能够执行查询语句。

    现在我们另外起一个窗口,相当于另起了一个线程来进行查询操作。

    select * from cxuan005;
    

    这是第二个窗口执行查询的结果,可以看到,在一个线程执行 read 锁定后,其他线程仍然可以进行表的查询操作。

    那么第二个线程能否执行更新操作呢?我们来看一下

    update cxuan005 set info='cxuan' where id = 111;
    

    发生了什么?怎么没有提示结果呢?其实这个情况下表示 cxuan005 已经被加上了 read 锁,由于当前线程不是持有锁的线程,所以当前线程无法执行更新。

    解锁语句

    现在我们把窗口切换成持有 read 锁的线程,来进行 read 锁的解锁

    unlock tables;
    

    在解锁完成前,进行更新的线程会一直等待,直到解锁完成后,才会进行更新。我们可以看一下更新线程的结果。

    可以看到,线程已经更新完毕,我们看一下更新的结果

    select * from cxuan005 where id = 111;
    

    如上图所示,id = 111 的值已经被更新成了 cxuan。

    事务控制

    事务(Transaction) 是访问和更新数据库的基本执行单元,一个事务中可能会包含多个 SQL 语句,事务中的这些 SQL 语句要么都执行,要么都不执行,而 MySQL 它是一个关系型数据库,它自然也是支持事务的。事务同时也是区分关系型数据库和非关系型数据库的一个重要的方面。

    在 MySQL 事务中,主要涉及的语法包含 SET AUTOCOMMIT、START TRANSACTION、COMMIT 和 ROLLBACK 等。

    自动提交

    在 MySQL 中,事务默认是自动提交(Autocommit)的,如下所示

    show variables like 'autocommit';
    

    在自动提交的模式下,每个 SQL 语句都会当作一个事务执行提交操作,例如我们上面使用的更新语句

    update cxuan005 set info='cxuan' where id = 111;
    

    如果想要关闭数据库的自动提交应该怎么做呢?

    其实,MySQL 是可以关闭自动提交的,你可以执行

    set autocommit = 0;
    

    然后我们再看一下自动提交是否关闭了,再次执行一下 show variables like ‘autocommit’ 语句

    可以看到,自动提交已经关闭了,再次执行

    set autocommit = 1;
    

    会再次开启自动提交。

    这里注意一下特殊操作。

    在 MySQL 中,存在一些特殊的命令,如果在事务中执行了这些命令,会马上强制执行 commit 提交事务;比如 DDL 语句(create table/drop table/alter/table)、lock tables 语句等等。

    不过,常用的 select、insert、update 和 delete命令,都不会强制提交事务。

    手动提交

    如果需要手动 commit 和 rollback 的话,就需要明确的事务控制语句了。

    典型的 MySQL 事务操作如下

    start transaction;
    ... # 一条或者多条语句
    commit;
    

    上面代码中的 start transaction 就是事务的开始语句,编写 SQL 后会调用 commit 提交事务,然后将事务统一执行,如果 SQL 语句出现错误会自动调用 Rollback 进行回滚。

    下面我们就通过示例来演示一下 MySQL 的事务,同样的,我们需要启动两个窗口来演示,为了便于区分,我们使用 mysql01 和 mysql02 来命名。

    我们用 start transaction 命令启动一个事务,然后再 cxuan005 表中插入一条数据,此时 mysql02 不做任何操作。涉及的 SQL 语句如下。

    start transaction;
    

    然后执行

    select * from cxuan005;
    

    查询一下 cxuan005 中的数据

    嗯。。。很多长度太长了,现在我们把所有的 info 数据都更新为 cxuan 。

    update cxuan005 set info='cxuan';
    

    更新完毕后,我们先不提交事务,分别在 mysql01 和 mysql02 中进行查询,发现只有 mysql01 窗口中的查询已经生效,而 mysql02 中还是更新前的数据

    现在我们在 mysql01 中 commit 当前事务,然后在 mysql02 中查询,发现数据已经被修改了。

    除了 commit 之外,MySQL 中还有 commit and chain 命令,这个命令会提交当前事务并且重新开启一个新的事务。如下代码所示

    start transaction; # 开启一个新的事务
    insert into cxuan005(id,info) values (555,'cxuan005'); # 插入一条数据
    commit and chain; # 提交当前事务并重新开启一个事务
    

    上面是一个事务操作,在 commit and chain 键入后,我们可以再次执行 SQL 语句

    update cxuan005 set info = 'cxuan' where id = 555;
    commit;
    

    然后再次查询

    select * from cxuan005;
    

    执行后,可以发现,我们仅仅使用了一个 start transaction 命令就执行了两次事务操作。

    如果在手动提交的事务中,你发现有一条 SQL 语句写的不正确或者有其他原因需要回滚,那么此时你就会用到 rollback 语句,它会回滚当前事务,相当于什么也没发生。如下代码所示。

    start transaction;
    delete from cxuan005 where id = 555;
    rollback;
    

    这里切忌一点:delete 删除语句一定要加 where ,不加 where 语句的删除就是耍流氓。

    在同一个事务操作中,最好使用相同存储引擎的表,如果使用不同存储引擎的表后,rollback 语句会对非事务类型的表进行特别处理,因此 commit 、rollback 只能对事务类型的表进行提交和回滚。

    我们提交的事务一般都会被记录到二进制的日志中,但是如果一个事务中包含非事务类型的表,那么回滚操作也会被记录到二进制日志中,以确保非事务类型的表可以被复制到从数据库中。

    这里解释一下什么是事务表和非事务表

    事务表和非事务表

    事务表故名思义就是支持事务的表,支不支持事务和 MySQL 的存储类型有关,一般情况下,InnoDB 存储引擎的表是支持事务的,关于 InnoDB 的知识,我们会在后面详细介绍。

    非事务表相应的就是不支持事务的表,在 MySQL 中,存储引擎 MyISAM 是不支持事务的,非事务表的特点是不支持回滚。

    对于回滚的话,还要讲一点就是 SAVEPOINT,它能指定事务回滚的一部分,但是不能指定事务提交的一部分。 SAVEPOINT 可以指定多个,在满足不同条件的同时,回滚不同的 SAVEPOINT。需要注意的是,如果定义了两个相同名称的 SAVEPOINT,则后面定义的 SAVEPOINT 会覆盖之前的定义。如果 SAVEPOINT 不再需要的话,可以通过 RELEASE SAVEPOINT 来进行删除。删除后的 SAVEPOINT 不能再执行 ROLLBACK TO SAVEPOINT 命令。

    我们通过一个示例来进行模拟不同的 SAVEPOINT

    首先先启动一个事务 ,向 cxuan005 中插入一条数据,然后进行查询,那么是可以查询到这条记录的

    start transaction;
    insert into cxuan005(id,info) values(666,'cxuan666');
    select * from cxuan005 where id = 666;
    

    查询之后的记录如下

    然后我们定义一个 SAVEPOINT,如下所示

    savepoint test;
    

    然后继续插入一条记录

    insert into cxuan005(id,info) values(777,'cxuan777');
    

    此时就可以查询到两条新增记录了,id 是 666 和 777 的记录。

    select * from cxuan005 where id = 777;
    

    那么我们可以回滚到刚刚定义的 SAVEPOINT

    rollback to savepoint test;
    

    再次查询 cxuan005 这个表,可以看到,只有 id=666 的这条记录插入进来了,说明 id=777 这条记录已经被回滚了。

    此时我们看到的都是 mysql01 中事务还没有提交前的状态,所以这时候 mysql02 中执行查询操作是看不到 666 这条记录的。

    然后我们在 mysql01 中执行 commit 操作,那么此时在 mysql02 中就可以查询到这条记录了。

    SQL 安全问题

    SQL 安全问题应该是我们程序员比较忽视的一个地方了。日常开发中,我们一般只会关心 SQL 能不能解决我们的业务问题,能不能把数据查出来,而对于 SQL 问题,我们一般都认为这是 DBA 的活,其实我们 CRUD 程序员也应该了解一下 SQL 的安全问题。

    SQL 注入简介

    SQL 注入就是利用某些数据库的外部接口将用户数据插入到实际的 SQL 中,从而达到入侵数据库的目的。SQL 注入是一种常见的网络攻击的方式,它不是利用操作系统的 BUG 来实现攻击的。SQL 主要是针对程序员编写时的疏忽来入侵的。

    SQL 注入攻击有很大的危害,攻击者可以利用它读取、修改或者删除数据库内的数据,获取数据库中的用户名和密码,甚至获得数据库管理员的权限。并且 SQL 注入一般比较难以防范。

    SQL Mode

    MySQL 可以运行在不同的 SQL Mode 模式下,不同的 SQL Mode 定义了不同的 SQL 语法,数据校验规则,这样就能够在不同的环境中使用 MySQL ,下面我们就来介绍一下 SQL Mode。

    SQL Mode 解决问题

    SQL Mode 可以解决下面这几种问题

    • 通过设置 SQL Mode,可以完成不同严格程度的数据校验,有效保障数据的准确性。
    • 设置 SQL Mode 为 ANSI 模式,来保证大多数 SQL 符合标准的 SQL 语法,这样应用在不同数据库的迁移中,不需要对 SQL 进行较大的改变
    • 数据在不同数据库的迁移中,通过改变 SQL Mode 能够更方便的进行迁移。

    下面我们就通过示例来演示一下 SQL Mode 用法

    我们可以通过

    select @@sql_mode;
    

    来查看默认的 SQL Mode,如下是我的数据库所支持的 SQL Mode

    涉及到很多 SQL Mode,下面是这些 SQL Mode 的解释

    ONLY_FULL_GROUP_BY:这个模式会对 GROUP BY 进行合法性检查,对于 GROUP BY 操作,如果在SELECT 中的列,没有在 GROUP BY 中出现,那么将认为这个 SQL 是不合法的,因为列不在 GROUP BY 从句中

    同样举个例子,我们现在查询一下 cxuan005 的 id 和 info 字段。

    select id,info from cxuan005;
    

    这样是可以运行的

    然后我们使用 GROUP BY 字句进行分组,这里只对 info 进行分组,我们看一下会出现什么情况

    select id,info from cxuan005 group by info;
    

    我们可以从错误原因中看到,这条 SQL 语句是不符合 ONLY_FULL_GROUP_BY 的这条 SQL Mode 的。因为我们只对 info 进行分组了,没有对 id 进行分组,我们把 SQL 语句改成如下形式

    select id,info from cxuan005 group by id,info;
    

    这样 SQL 就能正确执行了。

    当然,我们也可以删除 sql_mode = ONLY_FULL_GROUP_BY 的这条 Mode,可以使用

    SET sql_mode=(SELECT REPLACE(@@sql_mode,'ONLY_FULL_GROUP_BY',''));
    

    来进行删除,删除后我们使用分组语句就可以放飞自我了。

    select id,info from cxuan005 group by info;
    

    但是这种做法只是暂时的修改,我们可以修改配置文件 my.ini 中的 sql_mode= STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION

    STRICT_TRANS_TABLES:这就是严格模式,在这个模式下会对数据进行严格的校验,错误数据不能插入,报error 错误。如果不能将给定的值插入到事务表中,则放弃该语句。对于非事务表,如果值出现在单行语句或多行语句的第1行,则放弃该语句。

    当使用 innodb 存储引擎表时,考虑使用 innodb_strict_mode 模式的 sql_mode,它能增量额外的错误检测功能。

    NO_ZERO_IN_DATE:这个模式影响着日期中的月份和天数是否可以为 0(注意年份是非 0 的),这个模式也取决于严格模式是否被启用。如果这个模式未启用,那么日期中的零部分被允许并且插入没有警告。如果这个模式启用,那么日期中的零部分插入被作为 0000-00-00 并且产生一个警告。

    这个模式需要注意下,如果启用的话,需要 STRICT_TRANS_TABLESNO_ZERO_IN_DATE 同时启用,否则不起作用,也就是

    set session sql_mode='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE';
    

    然后我们换表了,使用 cxuan003 这张表,表结构如下

    我们主要测试日期的使用,在 cxuan003 中插入一条日期为 0000-00-00 的数据

    insert into cxuan003 values(111,'study','0000-00-00');
    

    发现能够执行成功,但是把年月日各自变为 0 之后再进行插入,则会插入失败。

    insert into cxuan003 values(111,'study','2021-00-00');
    

    insert into cxuan003 values(111,'study','2021-01-00');
    

    这些组合有很多,我这里就不再细致演示了,读者可以自行测试。

    如果要插入 0000-00-00 这样的数据,必须设置 NO_ZERO_IN_DATENO_ZERO_DATE

    ERROR_FOR_DIVISION_BY_ZERO:如果这个模式未启用,那么零除操作将会插入空值并且不会产生警告;如果这个模式启用,零除操作插入空值并产生警告;如果这个模式和严格模式都启用,零除从操作将会产生一个错误。

    NO_AUTO_CREATE_USER:禁止使用 grant 语句自动创建用户,除非认证信息被指定。

    NO_ENGINE_SUBSTITUTION:此模式指定当执行 create 语句或者 alter 语句指定的存储引擎没有启用或者没有编译时,控制默认存储引擎的自动切换。默认是启用状态的。

    SQL Mode 三种作用域

    SQL Mode 按作用区域和时间可分为 3。个级别,分别是会话级别,全局级别,配置(永久生效)级别

    我们上面使用的 SQL Mode 都是 会话级别,会话级别就是当前窗口域有效。它的设置方式是

    set @@session.sql_mode='xx_mode'
    set session sql_mode='xx_mode'
    

    全局域就是当前会话关闭不失效,但是在 MySQL 重启后失效。它的设置方式是

    set global sql_mode='xx_mode';
    set @@global.sql_mode='xx_mode';
    

    配置域就是在 vi /etc/my.cnf 里面添加

    [mysqld]
    sql-mode = "xx_mode"
    

    配置域在保存退出后,重启服务器,即可永久生效。

    SQL 正则表达式

    正则表达式相信大家应该都用过,不过你在 MySQL 中用过正则表达式吗?下面我们就来聊一聊 SQL 中的正则表达式。

    正则表达式(Regular Expression) 是指一个用来描述或者匹配字符串的句法规则。正则表达式通常用来检索和替换某个文本中的文本内容。很多语言都支持正则表达式,MySQL 同样也不例外,MySQL 利用 REGEXP 命令提供给用户扩展的正则表达式功能。下面是 MySQL 中正则表达式的一些规则。

    下面来演示一下正则表达式的用法

    • ^ 在字符串的开始进行匹配,根据返回的结果来判断是否匹配,1 = 匹配,0 = 不匹配。下面尝试匹配字符串 aaaabbbccc 是否以字符串 a 为开始

      select 'aaaabbbccc' regexp '^a';
      

    • 同样的,$ 会在末尾处进行匹配,如下所示

      select 'aaaabbbccc' regexp 'c$';
      

    • . 匹配单个任意字符

      select 'berska' regexp '.s', 'zara' regexp '.a';
      

    • [...] 表示匹配括号内的任意字符,示例如下

      select 'whosyourdaddy' regexp '[abc]';
      

    • [^...] 匹配括号内不包含的任意字符,和 [...] 是相反的,如果有任何匹配不上,返回 0 ,全部匹配上返回 1。

      select 'x' regexp '[^xyz]';
      

    • n* 表示匹配零个或者多个 n 字符串,如下

      select 'aabbcc' regexp 'd*';
      

    没有 d 出现也可以返回 1 ,因为 * 表示 0 或者多个。

    • n+ 表示匹配 1 个或者 n 个字符串

      select 'aabbcc' regexp 'd+';
      

    • n? 的用法和 n+ 类似,只不过 n? 可以匹配空串

    常见 SQL 技巧

    RAND() 函数

    大多数数据库都会提供产生随机数的函数,通过这些函数可以产生随机数,也可以使用从数据库表中抽取随机产生的记录,这对统计分析来说很有用。

    在 MySQL 中,通常使用 RAND() 函数来产生随机数。RAND() 和 ORDER BY 组合完成数据抽取功能,如下所示。

    我们新建一张表用于数据检索。

    CREATE TABLE `clerk_Info` (
      `id` int(11) NOT NULL,
      `name` varchar(255) DEFAULT NULL,
      `salary` decimal(10,2) DEFAULT NULL,
      `companyId` int(10) DEFAULT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=latin1
    

    然后插入一些数据,插入完成后的数据如下。

    然后我们可以使用 RAND() 函数进行随机检索数据行

    select * from clerk_info order by rand();
    

    检索完成后的数据如下

    多次查询后发现每次检索的数据顺序都是随机的。

    这个函数多用于随机抽样,比如选取一定数量的样本在进行随机排序,需要用到 limit 关键字。

    GROUP BY + WITH ROLLUP

    我们经常使用 GROUP BY 语句,但是你用过 GROUP BYWITH ROLLUP 一起使用的吗?使用 GROUP BY 和 WITH ROLLUP 字句可以检索出更多的分组集合信息。

    我们仍旧对 clerk_info 表进行操作,我们对 name 和 salary 进行分组统计工资总数。

    select name,sum(salary) from clerk_info group by name with rollup;
    

    可以看到上面的表按照 name 进行分组,然后再对 money 进行统计。

    也就是说 GROUP BY 语句执行完成后可以满足用户想要的任何一个分组以及分组组合的聚合信息值。

    这里需要注意一点,不能同时使用 ORDER BY 字句对结果进行排序,ROLLUP 和 ORDER BY 是互斥的。

    数据库名、表名大小写问题

    在 MySQL 中,数据库中的每个表至少对应数据库目录中的一个文件,当然这取决于存储引擎的实现了。不同的操作系统对大小写的敏感性决定了数据库和表名的大小写的敏感性。在 UNIX 操作系统中是对大小写敏感的,因此数据库名和表名也是具有敏感性的,而到了 Windows 则不存在敏感性问题,因为 Windows 操作系统本身对大小写不敏感。列、索引、触发器在任何平台上都对大小写不敏感。

    在 MySQL 中,数据库名和表名是由 lower_case_tables_name 系统变量决定的。可以在启动 mysqld 时设置这个系统变量。下面是 lower_case_tables_name 的值。

    如果只在一个平台上使用 MySQL 的话,通常不需要修改 lower_case_tables_name 变量。如果想要在不同系统系统之间迁移表就会涉及到大小写问题,因为 UNIX 中 clerk_info 和 CLERK_INFO 被认为是两个不同的表,而 Windows 中则认为是一个。在 UNIX 中使用 lower_case_tables_name=0, 而在 Windows 中使用lower_case_tables_name=2,这样可以保留数据库名和表名的大小写,但是不能保证所有的 SQL 查询中使用的表名和数据库名的大小写相同。如果 SQL 语句中没有正确引用数据库名和表名的大小写,那么虽然在 Windows 中能正确执行,但是如果将查询转移到 UNIX 中,大小写不正确,将会导致查询失败。

    外键问题

    这里需要注意一个问题,InnoDB 存储引擎是支持外键的,而 MyISAM 存储引擎是不支持外键的,因此在 MyISAM 中设置外键会不起作用。

    MySQL 常用函数

    下面我们来了解一下 MySQL 函数,MySQL 函数也是我们日常开发过程中经常使用的,选用合适的函数能够提高我们的开发效率,下面我们就来一起认识一下这些函数

    字符串函数

    字符串函数是最常用的一种函数了,MySQL 也是支持很多种字符串函数,下面是 MySQL 支持的字符串函数表

    函数功能
    LOWER将字符串所有字符变为小写
    UPPER将字符串所有字符变为大写
    CONCAT进行字符串拼接
    LEFT返回字符串最左边的字符
    RIGHT返回字符串最右边的字符
    INSERT字符串替换
    LTRIM去掉字符串左边的空格
    RTRIM去掉字符串右边的空格
    REPEAT返回重复的结果
    TRIM去掉字符串行尾和行头的空格
    SUBSTRING返回指定的字符串
    LPAD用字符串对最左边进行填充
    RPAD用字符串对最右边进行填充
    STRCMP比较字符串 s1 和 s2
    REPLACE进行字符串替换

    下面通过具体的示例演示一下每个函数的用法

    • LOWER(str) 和 UPPER(str) 函数:用于转换大小写

    • CONCAT(s1,s2 … sn) :把传入的参数拼接成一个字符串

    上面把 c xu an 拼接成为了一个字符串,另外需要注意一点,任何和 NULL 进行字符串拼接的结果都是 NULL。

    • LEFT(str,x) 和 RIGHT(str,x) 函数:分别返回字符串最左边的 x 个字符和最右边的 x 个字符。如果第二个参数是 NULL,那么将不会返回任何字符串

    • INSERT(str,x,y,instr) : 将字符串 str 从指定 x 的位置开始, 取 y 个长度的字串替换为 instr。

    • LTRIM(str) 和 RTRIM(str) 分别表示去掉字符串 str 左侧和右侧的空格

    • REPEAT(str,x) 函数:返回 str 重复 x 次的结果

    • TRIM(str) 函数:用于去掉目标字符串的空格

    • SUBSTRING(str,x,y) 函数:返回从字符串 str 中第 x 位置起 y 个字符长度的字符串

    • LPAD(str,n,pad) 和 RPAD(str,n,pad) 函数:用字符串 pad 对 str 左边和右边进行填充,直到长度为 n 个字符长度

    • STRCMP(s1,s2) 用于比较字符串 s1 和 s2 的 ASCII 值大小。如果 s1 < s2,则返回 -1;如果 s1 = s2 ,返回 0 ;如果 s1 > s2 ,返回 1。

    • REPLACE(str,a,b) : 用字符串 b 替换字符串 str 种所有出现的字符串 a

    数值函数

    MySQL 支持数值函数,这些函数能够处理很多数值运算。下面我们一起来学习一下 MySQL 中的数值函数,下面是所有的数值函数

    函数功能
    ABS返回绝对值
    CEIL返回大于某个值的最大整数值
    MOD返回模
    ROUND四舍五入
    FLOOR返回小于某个值的最大整数值
    TRUNCATE返回数字截断小数的结果
    RAND返回 0 - 1 的随机值

    下面我们还是以实践为主来聊一聊这些用法

    • ABS(x) 函数:返回 x 的绝对值

    • CEIL(x) 函数: 返回大于 x 的整数

    • MOD(x,y),对 x 和 y 进行取模操作

    • ROUND(x,y) 返回 x 四舍五入后保留 y 位小数的值;如果是整数,那么 y 位就是 0 ;如果不指定 y ,那么 y 默认也是 0 。

    • FLOOR(x) : 返回小于 x 的最大整数,用法与 CEIL 相反

    • TRUNCATE(x,y): 返回数字 x 截断为 y 位小数的结果, TRUNCATE 知识截断,并不是四舍五入。

    • RAND() :返回 0 到 1 的随机值

    日期和时间函数

    日期和时间函数也是 MySQL 中非常重要的一部分,下面我们就来一起认识一下这些函数

    函数功能
    NOW返回当前的日期和时间
    WEEK返回一年中的第几周
    YEAR返回日期的年份
    HOUR返回小时值
    MINUTE返回分钟值
    MONTHNAME返回月份名
    CURDATE返回当前日期
    CURTIME返回当前时间
    UNIX_TIMESTAMP返回日期 UNIX 时间戳
    DATE_FORMAT返回按照字符串格式化的日期
    FROM_UNIXTIME返回 UNIX 时间戳的日期值
    DATE_ADD返回日期时间 + 上一个时间间隔
    DATEDIFF返回起始时间和结束时间之间的天数

    下面结合示例来讲解一下每个函数的使用

    • NOW(): 返回当前的日期和时间

    • WEEK(DATE) 和 YEAR(DATE) :前者返回的是一年中的第几周,后者返回的是给定日期的哪一年

    • HOUR(time) 和 MINUTE(time) : 返回给定时间的小时,后者返回给定时间的分钟

    • MONTHNAME(date) 函数:返回 date 的英文月份

    • CURDATE() 函数:返回当前日期,只包含年月日

    • CURTIME() 函数:返回当前时间,只包含时分秒

    • UNIX_TIMESTAMP(date) : 返回 UNIX 的时间戳

    • FROM_UNIXTIME(date) : 返回 UNIXTIME 时间戳的日期值,和 UNIX_TIMESTAMP 相反

    • DATE_FORMAT(date,fmt) 函数:按照字符串 fmt 对 date 进行格式化,格式化后按照指定日期格式显示

    具体的日期格式可以参考这篇文章 https://blog.csdn.net/weixin_38703170/article/details/82177837

    我们演示一下将当前日期显示为年月日的这种形式,使用的日期格式是 %M %D %Y

    • DATE_ADD(date, interval, expr type) 函数:返回与所给日期 date 相差 interval 时间段的日期

    interval 表示间隔类型的关键字,expr 是表达式,这个表达式对应后面的类型,type 是间隔类型,MySQL 提供了 13 种时间间隔类型

    表达式类型描述格式
    YEARYY
    MONTHMM
    DAYDD
    HOUR小时hh
    MINUTEmm
    SECONDss
    YEAR_MONTH年和月YY-MM
    DAY_HOUR日和小时DD hh
    DAY_MINUTE日和分钟DD hh : mm
    DAY_SECOND日和秒DD hh :mm :ss
    HOUR_MINUTE小时和分hh:mm
    HOUR_SECOND小时和秒hh:ss
    MINUTE_SECOND分钟和秒mm:ss
    • DATE_DIFF(date1, date2) 用来计算两个日期之间相差的天数

    查看离 2021 - 01 - 01 还有多少天

    流程函数

    流程函数也是很常用的一类函数,用户可以使用这类函数在 SQL 中实现条件选择。这样做能够提高查询效率。下表列出了这些流程函数

    函数功能
    IF(value,t f)如果 value 是真,返回 t;否则返回 f
    IFNULL(value1,value2)如果 value1 不为 NULL,返回 value1,否则返回 value2。
    CASE WHEN[value1] THEN[result1] …ELSE[default] END如果 value1 是真,返回 result1,否则返回 default
    CASE[expr] WHEN[value1] THEN [result1]… ELSE[default] END如果 expr 等于 value1, 返回 result1, 否则返回 default

    其他函数

    除了我们介绍过的字符串函数、日期和时间函数、流程函数,还有一些函数并不属于上面三类函数,它们是

    函数功能
    VERSION返回当前数据库的版本
    DATABASE返回当前数据库名
    USER返回当前登陆用户名
    PASSWORD返回字符串的加密版本
    MD5返回 MD5 值
    INET_ATON(IP)返回 IP 地址的数字表示
    INET_NTOA(num)返回数字代表的 IP 地址

    下面来看一下具体的使用

    • VERSION: 返回当前数据库版本

    • DATABASE: 返回当前的数据库名

    • USER : 返回当前登录用户名

    • PASSWORD(str) : 返回字符串的加密版本,例如

    • MD5(str) 函数:返回字符串 str 的 MD5 值

    • INET_ATON(IP): 返回 IP 的网络字节序列

    • INET_NTOA(num)函数:返回网络字节序列代表的 IP 地址,与 INET_ATON 相对

    总结

    这篇文章我带你手把手撸了一波 MySQL 的高级内容,其实说高级也不一定真的高级或者说难,其实就是区分不同梯度的东西。

    你的支持就是我撸文的动力!我是 cxuan,我们下篇文章见。

    另外,添加我的微信 becomecxuan,加入每日一题群,每天一道面试题分享,更多内容请参见我的 Github,成为最好的 bestJavaer

    我自己肝了六本 PDF,微信搜索「程序员cxuan」关注公众号后,在后台回复 cxuan ,领取全部 PDF,这些 PDF 如下

    六本 PDF 链接

    展开全文
  • 原创 shell取文件的某一的某一列的方法之一 ...
    原创

    在shell中取文件的某一行的某一列的方法之一

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
    本文链接: https://blog.csdn.net/yugemengjing/article/details/82415307
                </div>
                                                    <!--一个博主专栏付费入口-->
             
             <!--一个博主专栏付费入口结束-->
            <link rel="stylesheet" href="https://csdnimg.cn/release/phoenix/template/css/ck_htmledit_views-4a3473df85.css">
                                        <link rel="stylesheet" href="https://csdnimg.cn/release/phoenix/template/css/ck_htmledit_views-4a3473df85.css">
                <div class="htmledit_views" id="content_views">
                                            <p>需求:根据配置文件检测板子是否配置成功……</p>
    
    
     
    1. #!/bin/bash
    2. standFile= "$1"
    3. num=`cat $standFile | wc -l`
    4. for((i=1;i<= $num;i++))
    5. do
    6. for rl in $i
    7. do
    8. # 读取standFile文件的第i行第1列的值,并赋给tmp1
    9. tmp1=$(awk -v hang= "${i}" 'NR==hang {print $1}' ${standFile})
    10. # 读取standFile文件的第i行第3列的值,并赋给tmp2
    11. tmp2=$(awk -v hang= "${i}" 'NR==hang {print $3}' ${standFile})
    12. res= "`xmlconfig r $tmp1`"
    13. fin_res= ${res##*=}
    14. # 对比
    15. if [ $fin_res == $tmp2 ]
    16. then
    17. echo "$tmp1 is success"
    18. else
    19. echo "$tmp1 is failed"
    20. fi
    21. done
    22. done

     

    文章最后发布于: 2018-09-05 10:13:40
                <!--打赏开始-->
                            <div class="reward-user-box" style="margin-top: -12px;">
                    <span class="reward-word" style="color:#B4B4B4 !important">有 <span class="num">0</span> 个人打赏</span>
                                        <a target="_blank" href="https://im.csdn.net/im/main.html?userName=yugemengjing" data-report-click="{&quot;mod&quot;:&quot;popu_810&quot;,&quot;dest&quot;:&quot;私信&quot;}" data-report-view="{&quot;mod&quot;:&quot;popu_810&quot;,&quot;dest&quot;:&quot;私信&quot;}" id="profile-content-alink">
                         <div class="reward-fexd" id="">
                    <!-- iconcsdnc-bookmark -->
                    <svg class="reward-icon" aria-hidden="true">
    				<use xlink:href="#csdnc-envelope"></use>
    			    </svg>
                    <div>私信求帮助</div>
                    </div>
                    </a>
                   
                </div>
                        <!--打赏结束-->
            <div class="recommend-box"><div class="recommend-item-box type_blog clearfix" data-report-view="{&quot;mod&quot;:&quot;popu_387&quot;,&quot;dest&quot;:&quot;https://blog.csdn.net/u010043538/article/details/73277086&quot;,&quot;strategy&quot;:&quot;BlogCommendFromMachineLearnPai2&quot;,&quot;index&quot;:&quot;0&quot;}" data-report-click="{&quot;mod&quot;:&quot;popu_387&quot;,&quot;dest&quot;:&quot;https://blog.csdn.net/u010043538/article/details/73277086&quot;,&quot;strategy&quot;:&quot;BlogCommendFromMachineLearnPai2&quot;,&quot;index&quot;:&quot;0&quot;}">
    <div class="content" style="width: 962px;">
    	<a href="https://blog.csdn.net/u010043538/article/details/73277086" target="_blank" rel="noopener" title="Linux:使用awk命令获取文本的某一行,某一列">
    	<h4 class="text-truncate oneline" style="width: 802px;">
    			Linux:使用awk命令获<em>取</em>文本的某<em>一行</em>,某一<em>列</em>		</h4>
    	<div class="info-box d-flex align-content-center">
    		<p class="date-and-readNum oneline">
    			<span class="date hover-show">06-15</span>
    			<span class="read-num hover-hide">
    				阅读数 
    				1万+</span>
    			</p>
    		</div>
    	</a>
    	<p class="content" style="width: 962px;">
    		<a href="https://blog.csdn.net/u010043538/article/details/73277086" target="_blank" rel="noopener" title="Linux:使用awk命令获取文本的某一行,某一列">
    			<span class="desc oneline">1、打印文件的第一列(域)awk'{print$1}'filename2、打印文件的前两列(域)awk'{print$1,$2}'filename3、打印完第一列,然后打印第二列awk'{print$...</span>
    		</a>
    		<span class="blog_title_box oneline ">
    								<span class="type-show type-show-blog type-show-after">博文</span>
    										<a target="_blank" rel="noopener" href="https://blog.csdn.net/u010043538">来自:	<span class="blog_title"> 孙琨SealSun</span></a>
    											</span>
    	</p>
    </div>
    </div>
    
    还能输入1000个字符
    <div class="comment-list-container">
    	<a id="comments"></a>
    	<div class="comment-list-box">
    	</div>
    	<div id="commentPage" class="pagination-box d-none"></div>
    	<div class="opt-box text-center">
    		<div class="btn btn-sm btn-link-blue" id="btnMoreComment"></div>
    	</div>
    </div>
    

    shell实现:读文件一行,sed操作文件一行

    06-25 阅读数 2万+

    写法一:#!/bin/bashwhilereadlinedoecho$line#这里可根据实际用途变化done 博文 来自: jk110333的专栏

    <div class="recommend-item-box recommend-recommend-box"><div id="kp_box_59" data-pid="59"><script type="text/javascript">
    (function() {
        var s = "_" + Math.random().toString(36).slice(2);
        document.write('<div style="" id="' + s + '"></div>');
        (window.slotbydup = window.slotbydup || []).push({
            id: "u3491668",
            container:  s
        });
    })();
    

    文件出指定行(shell)

    05-18

    我有一个>1G的文件,打开肯定是不行的,太麻烦了。 我现在想将指定的行取出来备份到一个文件,然后从文件中将该指定的行删除! 请问怎么写。 现在我想取出来是这样取的(如取2571): head -257 论坛

    shell脚本之按行读文件

    05-26 阅读数 849

    1 #!/bin/bash 2 #按行读取文件 3 while... 博文 来自: I_love_blog的博客

    <div class="recommend-item-box recommend-recommend-box"><div id="kp_box_60" data-pid="60"><iframe src="https://adaccount.csdn.net/#/preview/261?m=bncppbQAJEQiHpcEDtiJySHAJcLEALJQtAAmUHiXApJQbtEHADbApEbXcEpitHSAiEQSLtiASSJWSDviAtoiJffbJDXJynHDnpQQ&amp;k=" scrolling="no" width="100%" height="75px" frameborder="0"></iframe><img class="pre-img-lasy" data-src="https://kunyu.csdn.net/1.png?d=2&amp;k=&amp;m=bncppbQAJEQiHpcEDtiJySHAJcLEALJQtAAmUHiXApJQbtEHADbApEbXcEpitHSAiEQSLtiASSJWSDviAtoiJffbJDXJynHDnpQQ"></div></div>
    
    		<div class="recommend-item-box blog-expert-recommend-box" style="display: block;">
    		<div class="d-flex">
    			<div class="blog-expert-recommend">
    				<div class="blog-expert">
    					<div class="blog-expert-flexbox" data-report-view="{&quot;mod&quot;:&quot;popu_709&quot;,&quot;dest&quot;:&quot;https://blog.csdn.net/yugemengjing/article/details/82415307&quot;}"><div class="blog-expert-item"><div class="blog-expert-info-box"><div class="blog-expert-img-box" data-report-click="{&quot;mod&quot;:&quot;popu_709&quot;,&quot;dest&quot;:&quot;https://blog.csdn.net/yugemengjing/article/details/82415307&quot;}"><a href="https://blog.csdn.net/u010043538" target="_blank"><img src="https://profile.csdnimg.cn/1/9/A/3_u010043538" username="u010043538" alt="squeue2019" title="squeue2019"></a><span data-report-click="{&quot;mod&quot;:&quot;popu_710&quot;,&quot;dest&quot;:&quot;https://blog.csdn.net/yugemengjing/article/details/82415307&quot;}"><span class="blog-expert-button-follow btn-red-follow" data-name="u010043538" data-nick="squeue2019">关注</span></span></div><div class="info"><span data-report-click="{&quot;mod&quot;:&quot;popu_709&quot;,&quot;dest&quot;:&quot;https://blog.csdn.net/yugemengjing/article/details/82415307&quot;}"><a href="https://blog.csdn.net/u010043538" target="_blank"><h5 class="oneline" title="squeue2019">squeue2019</h5></a></span>  <p></p><p class="article-num" title="109篇文章"> 109篇文章</p><p class="article-num" title="排名:千里之外"> 排名:千里之外</p><p></p></div></div></div><div class="blog-expert-item"><div class="blog-expert-info-box"><div class="blog-expert-img-box" data-report-click="{&quot;mod&quot;:&quot;popu_709&quot;,&quot;dest&quot;:&quot;https://blog.csdn.net/yugemengjing/article/details/82415307&quot;}"><a href="https://blog.csdn.net/jk110333" target="_blank"><img src="https://profile.csdnimg.cn/4/B/8/3_jk110333" username="jk110333" alt="siaisjack" title="siaisjack"></a><span data-report-click="{&quot;mod&quot;:&quot;popu_710&quot;,&quot;dest&quot;:&quot;https://blog.csdn.net/yugemengjing/article/details/82415307&quot;}"><span class="blog-expert-button-follow btn-red-follow" data-name="jk110333" data-nick="siaisjack">关注</span></span></div><div class="info"><span data-report-click="{&quot;mod&quot;:&quot;popu_709&quot;,&quot;dest&quot;:&quot;https://blog.csdn.net/yugemengjing/article/details/82415307&quot;}"><a href="https://blog.csdn.net/jk110333" target="_blank"><h5 class="oneline" title="siaisjack">siaisjack</h5></a></span>  <p></p><p class="article-num" title="208篇文章"> 208篇文章</p><p class="article-num" title="排名:1000+"> 排名:1000+</p><p></p></div></div></div><div class="blog-expert-item"><div class="blog-expert-info-box"><div class="blog-expert-img-box" data-report-click="{&quot;mod&quot;:&quot;popu_709&quot;,&quot;dest&quot;:&quot;https://blog.csdn.net/yugemengjing/article/details/82415307&quot;}"><a href="https://blog.csdn.net/wuzhiwuweisun" target="_blank"><img src="https://profile.csdnimg.cn/5/6/B/3_wuzhiwuweisun" username="wuzhiwuweisun" alt="wuzhiwuweisun" title="wuzhiwuweisun"></a><span data-report-click="{&quot;mod&quot;:&quot;popu_710&quot;,&quot;dest&quot;:&quot;https://blog.csdn.net/yugemengjing/article/details/82415307&quot;}"><span class="blog-expert-button-follow btn-red-follow" data-name="wuzhiwuweisun" data-nick="wuzhiwuweisun">关注</span></span></div><div class="info"><span data-report-click="{&quot;mod&quot;:&quot;popu_709&quot;,&quot;dest&quot;:&quot;https://blog.csdn.net/yugemengjing/article/details/82415307&quot;}"><a href="https://blog.csdn.net/wuzhiwuweisun" target="_blank"><h5 class="oneline" title="wuzhiwuweisun">wuzhiwuweisun</h5></a></span>  <p></p><p class="article-num" title="35篇文章"> 35篇文章</p><p class="article-num" title="排名:千里之外"> 排名:千里之外</p><p></p></div></div></div><div class="blog-expert-item"><div class="blog-expert-info-box"><div class="blog-expert-img-box" data-report-click="{&quot;mod&quot;:&quot;popu_709&quot;,&quot;dest&quot;:&quot;https://blog.csdn.net/yugemengjing/article/details/82415307&quot;}"><a href="https://blog.csdn.net/Nicole1024" target="_blank"><img src="https://profile.csdnimg.cn/3/6/E/3_nicole1024" username="Nicole1024" alt="陌上花開#" title="陌上花開#"></a><span data-report-click="{&quot;mod&quot;:&quot;popu_710&quot;,&quot;dest&quot;:&quot;https://blog.csdn.net/yugemengjing/article/details/82415307&quot;}"><span class="blog-expert-button-follow btn-red-follow" data-name="Nicole1024" data-nick="陌上花開#">关注</span></span></div><div class="info"><span data-report-click="{&quot;mod&quot;:&quot;popu_709&quot;,&quot;dest&quot;:&quot;https://blog.csdn.net/yugemengjing/article/details/82415307&quot;}"><a href="https://blog.csdn.net/Nicole1024" target="_blank"><h5 class="oneline" title="陌上花開#">陌上花開#</h5></a></span>  <p></p><p class="article-num" title="13篇文章"> 13篇文章</p><p class="article-num" title="排名:千里之外"> 排名:千里之外</p><p></p></div></div></div></div>
    				</div>
    			</div>
    		</div>
    	</div>
    
    <div class="recommend-item-box recommend-recommend-box"><div id="kp_box_61" data-pid="61"><iframe src="https://adaccount.csdn.net/#/preview/787?m=JcfvbSHLDcoiJSHAAJbLcSiUXSvbpttSJHbbXcHiSALJtEpipyJmLiiyntSLntbHQWtJbbEbiDpDpJpmDDUboSpLSHScLnvnJESQ&amp;k=" scrolling="no" width="100%" height="75px" frameborder="0"></iframe><img class="pre-img-lasy" data-src="https://kunyu.csdn.net/1.png?d=2&amp;k=&amp;m=JcfvbSHLDcoiJSHAAJbLcSiUXSvbpttSJHbbXcHiSALJtEpipyJmLiiyntSLntbHQWtJbbEbiDpDpJpmDDUboSpLSHScLnvnJESQ"></div></div>
    

    shell文件第几行 第几的值

    07-04 阅读数 1万+

    shell读取文件第几行第几列的值 博文 来自: wengyupeng 蜗牛一步一步向前。。。

    shell文件指定行的操作

    09-18 阅读数 1252

    shell对文件指定行的操作awksed命令 博文 来自: weixin_42558057的博客

    shell根据关键字获文件一行的行号

    06-04 阅读数 288

    为什么80%的码农都做不了架构师?&gt;&gt;&gt;... 博文 来自: weixin_33694620的博客

    <div class="recommend-item-box recommend-recommend-box"><div id="kp_box_62" data-pid="62"><iframe src="https://adaccount.csdn.net/#/preview/786?m=nSScfvEpLHALDEESScJJnLoHAcUtJEXJEEbUbHXSnnDbLEnHyJAnpmbXLSpLpLtnHQSWbJcbvEnJoJScpfpJEScobLnpSHcAnvJQ&amp;k=" scrolling="no" width="100%" height="75px" frameborder="0"></iframe><img class="pre-img-lasy" data-src="https://kunyu.csdn.net/1.png?d=2&amp;k=&amp;m=nSScfvEpLHALDEESScJJnLoHAcUtJEXJEEbUbHXSnnDbLEnHyJAnpmbXLSpLpLtnHQSWbJcbvEnJoJScpfpJEScobLnpSHcAnvJQ"></div></div>
    
    <div class="recommend-item-box recommend-recommend-box"><div id="kp_box_63" data-pid="63"><iframe src="https://adaccount.csdn.net/#/preview/263?m=JAcQLQHEcpDbJySHcinQmtbbtvHpXiAnJbUtbbpLHEttDAttLXnpUJAHLbSQbtWncvbStpAcyLnLbtAJEUJSiSAStASnXbHDbQLQ&amp;k=" scrolling="no" width="100%" height="75px" frameborder="0"></iframe><img class="pre-img-lasy" data-src="https://kunyu.csdn.net/1.png?d=2&amp;k=&amp;m=JAcQLQHEcpDbJySHcinQmtbbtvHpXiAnJbUtbbpLHEttDAttLXnpUJAHLbSQbtWncvbStpAcyLnLbtAJEUJSiSAStASnXbHDbQLQ"></div></div>
    
    <div class="recommend-item-box recommend-recommend-box"><div id="kp_box_64" data-pid="64"><script type="text/javascript">
    (function() {
        var s = "_" + Math.random().toString(36).slice(2);
        document.write('<div style="" id="' + s + '"></div>');
        (window.slotbydup = window.slotbydup || []).push({
            id: "u3600856",
            container:  s
        });
    })();
    

    <div class="recommend-item-box recommend-recommend-box"><div id="kp_box_65" data-pid="65"><script type="text/javascript">
        (function() {
            var s = "_" + Math.random().toString(36).slice(2);
            document.write('<div style="" id="' + s + '"></div>');
            (window.slotbydup = window.slotbydup || []).push({
                id: "u4221803",
                container: s
            });
        })();
    

    程序员实用工具网站

    09-04 阅读数 19万+

    目录

    1、搜索引擎

    2、PPT

    3、图片操作

    4、文件共享

    5、应届生招聘

    6、程序员面试题库

    7、办公、开发软件

    8、高清图片、视频素材网站

    9、项目开源

    10、算法

    11、在…


    博文



    <div class="recommend-item-box recommend-recommend-box"><div id="kp_box_66" data-pid="66"><iframe src="https://adaccount.csdn.net/#/preview/575?m=cLALQvEbbLHicnAEALcyiiJHcDiEADSctHJnXbJXAHiJvtyiJvEHbtnSAAEQEWQiifLvLStmpLLvQvAESiUHtEnAJScLLbSQpinQ&amp;k=" scrolling="no" width="100%" height="75px" frameborder="0"></iframe><img class="pre-img-lasy" data-src="https://kunyu.csdn.net/1.png?d=2&amp;k=&amp;m=cLALQvEbbLHicnAEALcyiiJHcDiEADSctHJnXbJXAHiJvtyiJvEHbtnSAAEQEWQiifLvLStmpLLvQvAESiUHtEnAJScLLbSQpinQ"></div></div>
    

    我的 Input框 不可能这么可爱

    09-03 阅读数 1万+

    作者:陈大鱼头 github: KRISACHAN

    &lt;input /&gt; 标签是我们日常开发中非常常见的替换元素了,但是最近在刷 whattwg 跟 MDN 的时候发现 跟 &lt;in…


    博文



    我花了一夜用数据结构给女朋友写个H5走迷宫游戏

    09-21 阅读数 17万+

    起因

    又到深夜了,我按照以往在csdn和公众号写着数据结构!这占用了我大量的时间!我的超越妹妹严重缺乏陪伴而 怨气满满!

    而女朋友时常埋怨,认为数据结构这么抽象难懂的东西没啥作用,常会问道…


    博文



    这篇文章很长,但绝对是精华,相信我,读完以后,你会知道学历不好的解决方案…


    博文



    nginx学习,看这一篇就够了:下载、安装。使用:正向代理、反向代理、负载均衡。常用命令和配置文件

    10-25 阅读数 1万+

    文章目录前言一、nginx简介1. 什么是 nginx 和可以做什么事情2.Nginx 作为 web 服务器3. 正向代理4. 反向代理5. 动静分离6.动静分离二、Nginx 的安装三、 Ngin... 博文

    <div class="recommend-item-box recommend-recommend-box"><div><iframe scrolling="no" src="//pos.baidu.com/s?hei=90&amp;wid=900&amp;di=u3491668&amp;ltu=https%3A%2F%2Fblog.csdn.net%2Fyugemengjing%2Farticle%2Fdetails%2F82415307&amp;psi=c2e7e1d9c6e80790a16911560b3f4ff9&amp;par=1696x910&amp;dai=4&amp;col=zh-CN&amp;tlm=1574611174&amp;ant=0&amp;ltr=https%3A%2F%2Fblog.csdn.net%2Fyugemengjing%2Fcategory_6934804.html&amp;prot=2&amp;cfv=0&amp;dtm=HTML_POST&amp;ps=5434x511&amp;tpr=1574611174626&amp;cmi=2&amp;cja=false&amp;ti=%E5%9C%A8shell%E4%B8%AD%E5%8F%96%E6%96%87%E4%BB%B6%E7%9A%84%E6%9F%90%E4%B8%80%E8%A1%8C%E7%9A%84%E6%9F%90%E4%B8%80%E5%88%97%E7%9A%84%E6%96%B9%E6%B3%95%E4%B9%8B%E4%B8%80&amp;psr=1696x954&amp;cce=true&amp;pcs=1677x804&amp;tcn=1574611175&amp;drs=1&amp;cpl=1&amp;dis=0&amp;cec=UTF-8&amp;chi=1&amp;ccd=24&amp;ari=2&amp;dc=3&amp;pss=1677x5898&amp;dri=1&amp;pis=-1x-1&amp;cdo=-1&amp;exps=111000,110011" width="900" height="90" frameborder="0"></iframe></div><script type="text/javascript" src="//rabc1.iteye.com/production/res/rxjg.js?pkcgstj=jm"></script></div>
    

    【安全】Web渗透测试(全流程)

    10-29 阅读数 4604

    1 信息收集

    1.1域名、IP、端口

    域名信息查询:信息可用于后续渗透

    IP信息查询:确认域名对应IP,确认IP是否真实,确认通信是否正常

    端口信息查询:NMap扫描,确认开放端口
    如果不…


    博文



    动…


    博文



    <div class="recommend-item-box recommend-recommend-box"><div id="_2ak6qmtun3m"><div id="ahziza" style="display:none;"></div><iframe scrolling="no" src="//pos.baidu.com/s?hei=90&amp;wid=900&amp;di=u3491668&amp;ltu=https%3A%2F%2Fblog.csdn.net%2Fyugemengjing%2Farticle%2Fdetails%2F82415307&amp;psi=c2e7e1d9c6e80790a16911560b3f4ff9&amp;pis=-1x-1&amp;cec=UTF-8&amp;drs=1&amp;dc=3&amp;cdo=-1&amp;exps=111000,110011&amp;ltr=https%3A%2F%2Fblog.csdn.net%2Fyugemengjing%2Fcategory_6934804.html&amp;ps=5940x511&amp;ccd=24&amp;cfv=0&amp;ant=0&amp;cja=false&amp;dis=0&amp;chi=1&amp;col=zh-CN&amp;ari=2&amp;cce=true&amp;pcs=1677x804&amp;prot=2&amp;tlm=1574611174&amp;cpl=1&amp;pss=1677x5993&amp;tcn=1574611175&amp;cmi=2&amp;tpr=1574611174626&amp;psr=1696x954&amp;ti=%E5%9C%A8shell%E4%B8%AD%E5%8F%96%E6%96%87%E4%BB%B6%E7%9A%84%E6%9F%90%E4%B8%80%E8%A1%8C%E7%9A%84%E6%9F%90%E4%B8%80%E5%88%97%E7%9A%84%E6%96%B9%E6%B3%95%E4%B9%8B%E4%B8%80&amp;dtm=HTML_POST&amp;dri=2&amp;par=1696x910&amp;dai=5" width="900" height="90" frameborder="0"></iframe></div><script type="text/javascript" src="//rabc1.iteye.com/production/res/rxjg.js?pkcgstj=jm"></script></div>
    

    Linux/C/C++ 不可错过的好书

    10-24 阅读数 1万+

    来源:公众号【编程珠玑】

    作者:守望先生

    ID:shouwangxiansheng

    前言

    经常有读者让我推荐书籍,这次我就把我私藏的计算机书单分享给你们!不过由于时间匆忙,不会进行更加详细…


    博文



    漫话:什么是 https ?这应该是全网把 https 讲的最好的一篇文章了

    10-26 阅读数 3万+

    今天这篇文章,讲通过对话的形式,让你由浅入深着知道,为什么 Https 是安全的。

    一、对称加密

    一禅:在每次发送真实数据之前,服务器先生成一把密钥,然后先把密钥传输给客户端。之后服务器给客…


    博文



    史上最全的mysql基础教程

    10-28 阅读数 1万+

    启动与停止

    启动mysql服务
    sudo /usr/local/mysql/support-files/mysql.server start
    停止mysql服务
    sudo /usr/loc…


    博文



    敲黑板!!!读了这篇文章,你将知道如何才能进大厂,如何实现财务自…


    博文



    史上最全正则表达式语法,文末附常用表达式!

    10-28 阅读数 5945

    废话少说,直接开始学习!

    一、元字符

    元字符是构造正则表达式的一种基本元素。

    . :匹配除换行符以外的任意字符

    w:匹配字母或数字或下划线或汉字

    s:匹配任意的空白符

    d:匹配数字

    b:…


    博文



    一文搞懂什么是TCP/IP协议

    10-28 阅读数 2万+

    什么是TCP/IP协议?

    计算机与网络设备之间如果要相互通信,双方就必须基于相同的方法.比如如何探测到通信目标.由哪一边先发起通信,使用哪种语言进行通信,怎样结束通信等规则都需要事先确定.不同的硬件…


    博文



    中国麻将:世界上最早的区块链项目

    10-29 阅读数 4万+

    中国麻将:世界上最早的区块链项目

    最近区块链这个玩意又被市场搞的很是火热,相信大部分人都不太清楚这玩意到底是怎么样的一个概念,它来了,它来了,它到底是啥~ 国家都开始发文支持了,下面是一个通俗易懂的…


    博文



    比特币原理详解

    10-29 阅读数 2万+

    一、什么是比特币

    比特币是一种电子货币,是一种基于密码学的货币,在2008年11月1日由中本聪发表比特币白皮书,文中提出了一种去中心化的电子记账系统,我们平时的电子现金是银行来记账,因为银行的背后是…


    博文



    Python 基础(一):入门必备知识

    10-30 阅读数 1万+

    Python 入门必备知识,你都掌握了吗? 博文

    根据我们的经验,程序员兼职主要分为三种:兼职职位众包、项目整包和自由职业者驻场。

    所谓的兼职职位众…


    博文



    Ngrok: 超简单的内网穿透,了解一下 ?

    10-31 阅读数 6629

    【1】什么是内网穿透?

    首先,我们生活中的网络从应用上可以分为内网和外网;

    内网就是你自己的网络环境,就你自己能访问,比如你本地测试进行的localhost;

    外网就不言而喻了,你看网页,视频等…


    博文



    二、Python运算符、条件结构、循环结构

    三、Python函数

    四、做一次综合练习,做一个控制台…


    博文



    刷了几千道算法题,这些我私藏的刷题网站都在这里了!

    11-08 阅读数 2万+

    遥想当年,机缘巧合入了 ACM 的坑,周边巨擘林立,从此过上了"天天被虐似死狗"的生活…

    然而我是谁,我可是死狗中的战斗鸡,智力不够那刷题来凑,开始了夜以继日哼哧哼哧刷题的日子,从此"读题与提交…


    博文



    JavaScript 为什么能活到现在?

    11-08 阅读数 1496

    作者 | 司徒正美

    责编 |郭芮

    出品 | CSDN(ID:CSDNnews)

    JavaScript能发展到现在的程度已经经历不少的坎坷,早产带来的某些缺陷是永久性的,因此浏览器才有禁用Ja…


    博文



                    <div class="recommend-item-box type_hot_word">
                    <div class="content clearfix" style="width: 962px;">
                        <div class="float-left">
                                                                                <span>
                                <a href="https://blog.csdn.net/yilovexing/article/details/80577510" target="_blank">
                                python</a>
                            </span>
                                                        <span>
                                <a href="https://blog.csdn.net/slwbcsdn/article/details/53458352" target="_blank">
                                json</a>
                            </span>
                                                        <span>
                                <a href="https://blog.csdn.net/csdnnews/article/details/83753246" target="_blank">
                                java</a>
                            </span>
                                                        <span>
                                <a href="https://blog.csdn.net/qq_35077512/article/details/88952519" target="_blank">
                                mysql</a>
                            </span>
                                                        <span>
                                <a href="https://blog.csdn.net/pdcfighting/article/details/80297499" target="_blank">
                                pycharm</a>
                            </span>
                                                        <span>
                                <a href="https://blog.csdn.net/sinyu890807/article/details/97142065" target="_blank">
                                android</a>
                            </span>
                                                        <span>
                                <a href="https://blog.csdn.net/gexiaoyizhimei/article/details/100122368" target="_blank">
                                linux</a>
                            </span>
                                                        <span>
                                <a href="https://download.csdn.net/download/xhg_gszs/10978826" target="_blank">
                                json格式</a>
                            </span>
                                                    
                                                                                <span>
                                <a href="https://www.csdn.net/gather_13/MtzaAgxsLWRvd25sb2Fk.html" target="_blank">
                                c# tcp通信客户端类</a>
                            </span>
                                                        <span>
                                <a href="https://www.csdn.net/gather_15/MtzaAgysLWRvd25sb2Fk.html" target="_blank">
                                c# 数字转时间</a>
                            </span>
                                                        <span>
                                <a href="https://www.csdn.net/gather_11/MtzaAgzsLWRvd25sb2Fk.html" target="_blank">
                                c# 读json</a>
                            </span>
                                                        <span>
                                <a href="https://www.csdn.net/gather_13/MtzaAg0sLWRvd25sb2Fk.html" target="_blank">
                                c# 释放文件</a>
                            </span>
                                                        <span>
                                <a href="https://www.csdn.net/gather_14/MtzaAg1sLWRvd25sb2Fk.html" target="_blank">
                                c#某个数的模</a>
                            </span>
                                                        <span>
                                <a href="https://www.csdn.net/gather_1b/MtzaAg2sLWRvd25sb2Fk.html" target="_blank">
                                c# 更改exe生成名称</a>
                            </span>
                                                        <span>
                                <a href="https://www.csdn.net/gather_18/MtzaAg3sLWRvd25sb2Fk.html" target="_blank">
                                c#程序文件写入性能太差</a>
                            </span>
                                                        <span>
                                <a href="https://www.csdn.net/gather_1a/MtzaAg4sLWRvd25sb2Fk.html" target="_blank">
                                c#给定5个商品</a>
                            </span>
                                                        <span>
                                <a href="https://www.csdn.net/gather_1e/MtzaAg5sLWRvd25sb2Fk.html" target="_blank">
                                c# 异步委托 性能</a>
                            </span>
                                                        <span>
                                <a href="https://www.csdn.net/gather_29/MtzaEgxsLWJsb2cO0O0O.html" target="_blank">
                                c#满足条件跳出循环</a>
                            </span>
                                                                            </div>
                    </div>
                    </div>
                                    <div class="recommend-loading-box">
                    <img src="https://csdnimg.cn/release/phoenix/images/feedLoading.gif">
                </div>
                <div class="recommend-end-box">
                    <p class="text-center">没有更多推荐了,<a href="https://blog.csdn.net/" class="c-blue c-blue-hover c-blue-focus">返回首页</a></p>
                </div>
            </div>
                            <div class="template-box">
                    <span>©️2019 CSDN</span><span class="point"></span>
                <span>皮肤主题: 大白</span>
                <span> 设计师:
                                            CSDN官方博客                                    </span>
                </div>
                    </main>
        <aside class="blog_container_aside">
    <!--主页引入-->
            <div id="asideProfile" class="aside-box">
    <!-- <h3 class="aside-title">个人资料</h3> -->
    <div class="profile-intro d-flex">
        <div class="avatar-box d-flex justify-content-center flex-column">
            <a href="https://blog.csdn.net/yugemengjing">
                <img src="https://profile.csdnimg.cn/F/E/C/3_yugemengjing" class="avatar_pic" username="yugemengjing">
                                    <img src="https://g.csdnimg.cn/static/user-reg-year/2x/3.png" class="user-years">
                            </a>
            
        </div>
        <div class="user-info d-flex flex-column profile-intro-name-box">
            <div>
                                <span class="name csdn-tracking-statistics tracking-click " style="display:block" data-report-click="{&quot;mod&quot;:&quot;popu_379&quot;}" username="yugemengjing">
                    <a href="https://blog.csdn.net/yugemengjing" class="" id="uid" title="baiduoWang">
                        baiduoWang                    </a>
                </span>
                            </div>
            <div class="profile-intro-name-boxFooter">
                                    <div class="personal-home-page" style="right:-96px;"><a target="_blank" href="https://me.csdn.net/yugemengjing">TA的个人主页 &gt;</a></div>
                                <div class="profile-intro-name-boxOpration">
                                            <div class="profile-personal-letter">
                            <a id="profile-personal-alink" class="profile-personal-alink" href="https://im.csdn.net/im/main.html?userName=yugemengjing" target="_blank" rel="noopener">私信</a>
                        </div>
                        <div class="opt-box d-flex  flex-column">
                            <span class="csdn-tracking-statistics tracking-click" data-report-click="{&quot;mod&quot;:&quot;popu_379&quot;}">
                                                                    <a class="btn btn-sm btn-red-hollow attention" id="btnAttent" style="padding:0;">关注</a>
                                                            </span>
                        </div>
                                    </div>
            </div>
        </div>
    </div>
    <div class="data-info d-flex item-tiling">
                <dl class="text-center" title="62">
                            <dt><a href="https://blog.csdn.net/yugemengjing?t=1">原创</a></dt>
                <dd><a href="https://blog.csdn.net/yugemengjing?t=1"><span class="count">62</span></a></dd>
                    </dl>
        <dl class="text-center" id="fanBox" title="107">
            <dt>粉丝</dt>
            <dd><span class="count" id="fan">107</span></dd>
        </dl>
        <dl class="text-center" title="105">
            <dt>获赞</dt>
            <dd><span class="count">105</span></dd>
        </dl>
        <dl class="text-center" title="39">
            <dt>评论</dt>
            <dd><span class="count">39</span></dd>
        </dl>
        <dl class="text-center" title="126438">
            <dt>访问</dt>
            <dd><span class="count">12万+</span></dd>
        </dl>
    </div>
    <div class="grade-box clearfix">
        <dl class="aside-box-footerClassify">
            <dt>等级:</dt>
            <dd>
                <a href="https://blog.csdn.net/home/help.html#level" title="4级,点击查看等级说明" target="_blank">
                    <svg class="icon icon-level" aria-hidden="true">
                        <use xlink:href="#csdnc-bloglevel-4"></use>
                    </svg>
                </a>
            </dd>
        </dl>
        <dl>
            <dt>周排名:</dt>
            <dd>
                <a class="grade-box-rankA" href="https://blog.csdn.net/rank/writing_rank" target="_blank">
                    2万+                </a>
            </dd>
        </dl>
        <dl>
            <dt>积分:</dt>
            <dd title="1465">
                1465            </dd>
        </dl>
        <dl title="44279">
            <dt>总排名:</dt>
            <dd>
                <a class="grade-box-rankA" href="https://blog.csdn.net/rank/writing_rank_total" target="_blank">
                    4万+                </a>
            </dd>
        </dl>
    </div>
    <div class="aside-box-footer">
                    <div class="badge-box d-flex">
                <div class="profile-medal">勋章:</div>
                <div class="badge d-flex">
                                                                                                        <div class="icon-badge" title="持之以恒">
                                    <div class="mouse-box">
                                        <img src="https://g.csdnimg.cn/static/user-medal/chizhiyiheng.png" alt="">
                                        <div class="icon-arrow"></div>
                                    </div>
                                    <div class="grade-detail-box">
                                        <div class="pos-box">
                                            <div class="left-box d-flex justify-content-center align-items-center flex-column">
                                                <img src="https://g.csdnimg.cn/static/user-medal/chizhiyiheng.png" alt="">
                                                <p>持之以恒</p>
                                            </div>
                                            <div class="right-box">
                                                授予每个自然月内发布4篇或4篇以上原创或翻译IT博文的用户。不积跬步无以至千里,不积小流无以成江海,程序人生的精彩需要坚持不懈地积累!                                            </div>
                                        </div>
                                    </div>
                                </div>
                                                                                        </div>
                <script>
                    (function($) {
                        setTimeout(function() {
                            $('div.icon-badge.show-moment').removeClass('show-moment');
                        }, 5000);
                    })(window.jQuery)
                </script>
            </div>
                
    </div>
    

    热门文章

    • 				<a href="https://blog.csdn.net/yugemengjing/article/details/82469785">
                                                  shell编程100例                    </a>
      				<p class="read">阅读数 <span>44086</span></p>
      			</li>
      						<li>
      
      				<a href="https://blog.csdn.net/yugemengjing/article/details/78389352">
                                                  如何将图片储存在MySQL数据库中                    </a>
      				<p class="read">阅读数 <span>26431</span></p>
      			</li>
      						<li>
      
      				<a href="https://blog.csdn.net/yugemengjing/article/details/68954277">
                                                  判断强连通图、单向连通图、弱连通图                    </a>
      				<p class="read">阅读数 <span>9562</span></p>
      			</li>
      						<li>
      
      				<a href="https://blog.csdn.net/yugemengjing/article/details/72791445">
                                                  生产者消费者问题                    </a>
      				<p class="read">阅读数 <span>3578</span></p>
      			</li>
      						<li>
      
      				<a href="https://blog.csdn.net/yugemengjing/article/details/72790945">
                                                  进程控制                    </a>
      				<p class="read">阅读数 <span>2976</span></p>
      			</li>
      				</ul>
      </div>
      

    最新评论

    	<div class="aside-box">
    		<div id="kp_box_57" data-pid="57"><script async="" src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
    

    			<div class="aside-box">
    		<div class="persion_article">
    		<div class="right_box footer_box csdn-tracking-statistics" data-report-view="{&quot;mod&quot;:&quot;popu_475&quot;}">        <div class="contact-box" id="footer-contact-box"><div class="img-box"><img src="https://csdnimg.cn/pubfooter/images/csdn-cxrs.png" alt="程序人生" style="padding: 6px;width: 98px;height: 98px;"><p class="app-text">程序人生</p></div><div class="img-box fr"><a href="https://blog.csdn.net/csdnnews?utm_source=csdn_footer" target="_blank"><img style="padding: 6px;width: 98px;height: 98px;" src="//csdnimg.cn/pubfooter/images/csdn-zx.png" alt="CSDN资讯"></a><p class="app-text">CSDN资讯</p></div></div>        <div class="contact-info">        <p><svg width="16" height="16" xmlns="http://www.w3.org/2000/svg"><path d="M2.167 2h11.666C14.478 2 15 2.576 15 3.286v9.428c0 .71-.522 1.286-1.167 1.286H2.167C1.522 14 1 13.424 1 12.714V3.286C1 2.576 1.522 2 2.167 2zm-.164 3v1L8 10l6-4V5L8 9 2.003 5z" fill="#5c5c5c" fill-rule="evenodd"></path></svg><a href="mailto:webmaster@csdn.net" target="_blank"><span class="txt">kefu@csdn.net</span></a>        <em class="width126"><svg t="1538013544186" width="17" height="17" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="23556" xmlns:xlink="http://www.w3.org/1999/xlink"><defs><style type="text/css"></style></defs><path d="M902.60033922 650.96445566c-18.0718526-100.84369837-94.08399771-166.87723736-94.08399771-166.87723737 10.87530062-91.53186599-28.94715402-107.78733693-28.94715401-107.78733691C771.20003413 93.08221664 517.34798062 98.02553561 511.98620441 98.16348824 506.65661791 98.02553561 252.75857992 93.08221664 244.43541101 376.29988138c0 0-39.79946279 16.25547094-28.947154 107.78733691 0 0-75.98915247 66.03353901-94.0839977 166.87723737 0 0-9.63372291 170.35365477 86.84146124 20.85850523 0 0 21.70461757 56.79068296 61.50407954 107.78733692 0 0-71.1607951 23.19910867-65.11385185 83.46161052 0 0-2.43717093 67.16015592 151.93232126 62.56172014 0 0 108.5460788-8.0932473 141.10300432-52.14626271H526.33792324c32.57991817 44.05301539 141.10300431 52.1462627 141.10300431 52.14626271 154.3235077 4.59843579 151.95071457-62.56172013 151.95071457-62.56172014 6.00095876-60.26250183-65.11385185-83.46161053-65.11385185-83.46161052 39.77647014-50.99665395 61.4810877-107.78733693 61.4810877-107.78733692 96.45219231 149.49514952 86.84146124-20.85850523 86.84146125-20.85850523" p-id="23557" fill="#5c5c5c"></path></svg><a href="http://wpa.b.qq.com/cgi/wpa.php?ln=1&amp;key=XzgwMDE4MDEwNl80ODc3MzVfODAwMTgwMTA2XzJf" class="qqcustomer_s" target="_blank"><span class="txt">QQ客服</span></a></em></p>        <p><em class="width126"><svg t="1538012951761" width="17" height="17" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="23083" xmlns:xlink="http://www.w3.org/1999/xlink"><defs><style type="text/css"></style></defs><path d="M466.4934485 880.02006511C264.6019863 859.18313878 107.13744214 688.54706608 107.13744214 481.14947309 107.13744214 259.68965394 286.68049114 80.14660493 508.14031029 80.14660493s401.00286817 179.54304901 401.00286814 401.00286816v1.67343191C908.30646249 737.58941724 715.26799489 943.85339507 477.28978337 943.85339507c-31.71423369 0-62.61874229-3.67075386-92.38963569-10.60739903 30.09478346-11.01226158 56.84270313-29.63593923 81.5933008-53.22593095z m-205.13036267-398.87059202a246.77722444 246.77722444 0 0 0 493.5544489 0 30.85052691 30.85052691 0 0 0-61.70105383 0 185.07617062 185.07617062 0 0 1-370.15234125 0 30.85052691 30.85052691 0 0 0-61.70105382 0z" p-id="23084" fill="#5c5c5c"></path></svg><a href="http://bbs.csdn.net/forums/Service" target="_blank"><span class="txt">客服论坛</span></a></em>        <svg t="1538013874294" width="17" height="17" style="" viewBox="0 0 1194 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="23784" xmlns:xlink="http://www.w3.org/1999/xlink"><defs><style type="text/css"></style></defs><path d="M1031.29689505 943.85339507h-863.70679012A71.98456279 71.98456279 0 0 1 95.60554212 871.86883228v-150.85178906c0-28.58329658 16.92325492-54.46750945 43.13135785-65.93861527l227.99160176-99.75813425c10.55341735-4.61543317 18.24580594-14.0082445 20.72896295-25.23643277l23.21211998-105.53417343a71.95757195 71.95757195 0 0 1 70.28414006-56.51881307h236.95255971c33.79252817 0 63.02360485 23.5090192 70.28414004 56.51881307l23.21211997 105.53417343c2.48315701 11.25517912 10.17554562 20.62099961 20.72896296 25.23643277l227.99160177 99.75813425a71.98456279 71.98456279 0 0 1 43.13135783 65.93861527v150.85178906A71.98456279 71.98456279 0 0 1 1031.26990421 943.85339507z m-431.85339506-143.94213475c143.94213474 0 143.94213474-48.34058941 143.94213474-107.96334876s-64.45411922-107.96334877-143.94213474-107.96334877c-79.51500637 0-143.94213474 48.34058941-143.94213475 107.96334877s0 107.96334877 143.94213475 107.96334876zM1103.254467 296.07330247v148.9894213a35.97878598 35.97878598 0 0 1-44.15700966 35.03410667l-143.94213473-33.57660146a36.0057768 36.0057768 0 0 1-27.80056231-35.03410668V296.1002933c-35.97878598-47.98970852-131.95820302-71.98456279-287.91126031-71.98456279S347.53801649 248.11058478 311.53223967 296.1002933v115.385829c0 16.73431906-11.52508749 31.25538946-27.80056233 35.03410668l-143.94213473 33.57660146A35.97878598 35.97878598 0 0 1 95.63253297 445.06272377V296.07330247C162.81272673 152.13116772 330.77670658 80.14660493 599.47049084 80.14660493s436.63077325 71.98456279 503.81096699 215.92669754z" p-id="23785" fill="#5c5c5c"></path></svg>400-660-0108 </p>        <p style="text-align:center">工作时间 8:30-22:00</p>        </div>        <div class="bg-gray">            <div class="feed_copyright">            <p><a class="right-dotte" href="//www.csdn.net/company/index.html#about" target="_blank">关于我们</a><a href="//www.csdn.net/company/index.html#recruit" target="_blank" class="right-dotte">招聘</a><a href="//www.csdn.net/company/index.html#contact" target="_blank" class="right-dotte">广告服务</a>            <a href="https://www.csdn.net/gather/A" target="_blank" class="footer_baidu">            网站地图</a></p>            <p class="fz12_baidu"><a href="https://zn.baidu.com/cse/home/index" target="_blank"><svg width="13" height="14" xmlns="http://www.w3.org/2000/svg"><path d="M8.392 7.013c1.014 1.454 2.753 2.8 2.753 2.8s1.303 1.017.47 2.98c-.833 1.962-3.876.942-3.876.942s-1.122-.36-2.424-.072c-1.303.291-2.426.181-2.426.181s-1.523.037-1.957-1.888c-.434-1.927 1.52-2.982 1.666-3.161.145-.183 1.159-.873 1.81-1.963.653-1.09 2.608-1.962 3.984.181zm1.23 5.706V9.346H8.64v2.534h-.937s-.3-.044-.356-.285V9.33l-.925.015v2.518s.042.627.925.855h2.277zm-3.685.013V7.951l-.896-.014v1.295H3.987s-1.054.086-1.422 1.28c-.129.798.114 1.266.156 1.368.043.099.383.682 1.238.852h1.978zm-2.433-1.45c-.087-.286.013-.613.057-.741.042-.128.228-.427.61-.54h.855v1.948h-.797s-.555-.029-.725-.668zm6.877-8.775c-.143.909-.865 2.108-1.99 1.962-1.121-.144-1.375-1.16-1.267-2.179C7.214 1.458 8.21.18 9.007.364c.796.18 1.52 1.235 1.374 2.143zm-4.09-.345c0 1.197-.68 2.164-1.52 2.164S3.25 3.36 3.25 2.162C3.25.967 3.932 0 4.77 0c.842 0 1.52.967 1.52 2.162zm4.854 2.09c1.34 0 1.701 1.309 1.701 1.743 0 .438.182 2.29-1.485 2.326-1.667.037-1.737-1.126-1.737-1.96 0-.874.179-2.11 1.52-2.11zm-7.93.581c.045.398.253 2.217-1.27 2.544C.427 7.704-.14 5.947.028 5.124c0 0 .18-1.78 1.412-1.89.98-.085 1.7.986 1.774 1.6z" fill="#999" fill-rule="evenodd"></path></svg><em>百度提供站内搜索</em></a>&nbsp;<a href="http://www.miibeian.gov.cn/publish/query/indexFirst.action" target="_blank" class="ml14">京ICP备19004658号</a></p>            <p class="fz12_baidu">©1999-2019 北京创新乐知网络技术有限公司 </p>            </div>        </div>        <div class="allow-info-box">        <p><a href="https://csdnimg.cn/cdn/content-toolbar/csdn-ICP.png" target="_blank">经营性网站备案信息</a>        <em class="width126"><a href="http://www.cyberpolice.cn/" target="_blank"><span>网络110报警服务</span></a></em></p>        <p><a href="http://www.bjjubao.org/" target="_blank"><span>北京互联网违法和不良信息举报中心</span></a></p>        <p><a href="http://www.12377.cn/" target="_blank"><span>中国互联网举报中心</span></a><a href="https://download.csdn.net/index.php/tutelage/" target="_blank"><span style="margin-left:8px">家长监护</span></a><a href="https://blog.csdn.net/blogdevteam/article/details/90369522" target="_blank"><span style="margin-left:8px">版权申诉</span></a></p>        </div>        </div></div>
    	</div>
    </div>
    
    展开全文
  • 驱动的信号处理 fasync_struct结构体 fasync函数 kill_fasync函数 应用程序对异步通知的处理 阻塞/非阻塞简介   阻塞操作是指执行设备操作时,若不能获得资源,则挂起进程直到满足可操作的条件再进行操作。...

    工科生一枚,热衷于底层技术开发,有强烈的好奇心,感兴趣内容包括单片机,嵌入式Linux,Uboot等,欢迎学习交流!
    爱好跑步,打篮球,睡觉。
    欢迎加我QQ1500836631(备注CSDN),一起学习交流问题,分享各种学习资料,电子书籍,学习视频等。

    阻塞/非阻塞简介

      阻塞操作是指在执行设备操作时,若不能获得资源,则挂起进程直到满足可操作的条件后再进行操作。被挂起的进程进入睡眠状态,被从调度器的运行队列移走,直到等待的条件被满足。而非阻塞操作的进程在不能进行设备操作时,并不挂起,它要么放弃,要么不停地查询,直至可以进行操作为止。

    阻塞/非阻塞例程

      阻塞方式

    int fd;
    int data = 0;
    fd = open("/dev/xxx_dev", O_RDWR); /* 阻塞方式打开 */
    ret = read(fd, &data, sizeof(data)); /* 读取数据 */
    

      非阻塞方式

    int fd;
    int data = 0; 
    fd = open("/dev/xxx_dev", O_RDWR | O_NONBLOCK); /* 非阻塞方式打开 */ 
    ret = read(fd, &data, sizeof(data)); /* 读取数据 */
    

    等待队列简介

      等待队列是内核中一个重要的数据结构。阻塞方式访问设备时,如果设备不可操作,那么进程就会进入休眠状态。等待队列就是来完成进程休眠操作的一种数据结构。

    等待队列相关函数

    定义等待队列

    wait_queue_head_t my_queue;
    

      wait_queue_head_t是__wait_queue_head结构体的一个typedef。

    初始化等待队列头

    void init_waitqueue_head(wait_queue_head_t *q)
    

      参数q就是要初始化的等待队列头,也可以使用宏 **DECLARE_WAIT_QUEUE_HEAD (name)**来一次性完成等待队列头的定义的初始化。

    定义并初始化一个等待队列项

    DECLARE_WAITQUEUE(name, tsk)
    

      name就是等待队列项的名字,tsk表示这个等待队列项属于哪个任务进程,一般设置为current,在 Linux内核中 current相当于一个全局变量,表示当前进程。因此宏DECLARE_WAITQUEUE就是给当前正在运行的进程创建并初始化了一个等待队列项。

    将队列项添加到等待队列头

    void add_wait_queue(wait_queue_head_t *q, wait_queue_t *wait)
    

      q:等待队列项要加入的等待队列头
      wait:要加入的等待队列项
      返回值:无

    将队列项从等待队列头移除

    void remove_wait_queue(wait_queue_head_t *q, wait_queue_t *wait)
    

      q:要删除的等待队列项所处的等待队列头
      wait:要删除的等待队列项。
      返回值:无

    等待唤醒

    void wake_up(wait_queue_head_t *q) 
    void wake_up_interruptible(wait_queue_head_t *q)
    

      q:就是要唤醒的等待队列头,这两个函数会将这个等待队列头中的所有进程都唤醒
      wake_up函数可以唤醒处于 TASK_INTERRUPTIBLE和 TASK_UNINTERRUPTIBLE状态的进程,而wake_ up_ interruptible函数只能唤醒处于 TASK_INTERRUPTIBLE状态的进程

    等待事件

    wait_event(wq, condition)
    

      等待以wq为等待队列头的等待队列被唤醒,前提是 condition条件必须满足(为真),否则一直阻塞。此函数会将进程设置为TASK _UNINTERRUPTIBLE状态

    wait_event_timeout(wq, condition, timeout)
    

      功能和 wait_event类似,但是此函数可以添加超时时间,以 jiffies为单位。此函数有返回值,如果返回0的话表示超时时间到,而且 condition为假。为1的话表示 condition为真,也就是条件满足了。

    wait_event_interruptible(wq, condition)
    

      与 wait event函数类似,但是此函数将进程设置为 TASK_INTERRUPTIBLE,就是可以被信号打断

    wait_event_interruptible_timeout(wq, condition, timeout)
    

      与 wait event timeout函数类似,此函数也将进程设置为 TASK_INTERRUPTIBLE,可以被信号打断

    轮询

      当应用程序以非阻塞的方式访问设备时,会一遍一遍的去查询我们的设备是否可以访问,这个查询操作就叫做轮询。内核中提供了poll,epoll,select函数来处理轮询操作。当应用程序在上层通过poll,epoll,select函数来查询设备时,驱动程序中的poll,epoll,select函数就要在底层实现查询,如果可以操作的话,就会从读取设备的数据或者向设备写入数据。

    select

      函数原型

    int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout)
    

      nfds:要操作的文件描述符个数。
      readifds、 writefds和 exceptfds:这三个指针指向描述符集合,这三个参数指明了关心哪些描述符、需要满足哪些条件等等,这三个参数都是fd_set类型的, fd_set类型变量的每一个位都代表了一个文件描述符。 readfds用于监视指定描述符集的读变化,也就是监视这些文件是否可以读取,只要这些集合里面有一个文件可以读取,那么 seclect就会返回一个大于0的值表示文件可以读取。如果没有文件可以读取,那么就会根据 timeout参数来判断是否超时。可以将 reads设置为NULL,表示不关心任何文件的读变化。 writefds和 reads类似,只是 writers用于监视这些文件是否可以进行写操作。 exceptfds用于监视这些文件的异常
      timeout:超时时间,当我们调用 select函数等待某些文件描述符可以设置超时时间,超时时间使用结构体 timeval表示,结构体定义如下所示:

    struct timeval { 
    long tv_sec; /* 秒 */
    long tv_usec; /* 微妙 */ 
    };
    

      当 timeout为NULL的时候就表示无限期的等待返回值。0,表示的话就表示超时发生,但是没有任何文件描述符可以进行操作;-1,发生错误;其他值,可以进行操作的文件描述符个数。
      操作fd_set变量的函数

    void FD_ZERO(fd_set *set) 
    void FD_SET(int fd, fd_set *set) 
    void FD_CLR(int fd, fd_set *set) 
    int FD_ISSET(int fd, fd_set *set)
    

      FD_ZERO用于将 fd set变量的所有位都清零, FD_SET用于将 fd_set变量的某个位置1,也就是向 fd_set添加一个文件描述符,参数fd就是要加入的文件描述符。 FD_CLR用户将 fd_set变量的某个位清零,也就是将一个文件描述符从 fd_set中删除,参数fd就是要删除的文件描述符。 FD_ISSET用于测试 fd_set的某个位是否置1,也就是判断某个文件是否可以进行操作,参数fd就是要判断的文件描述符。

    
    void main(void) 
    {  int ret, fd; /* 要监视的文件描述符 */ 
        fd_set readfds; /* 读操作文件描述符集 */
        struct timeval timeout; /* 超时结构体 */ 
        fd = open("dev_xxx", O_RDWR | O_NONBLOCK); /* 非阻塞式访问 */ 
        FD_ZERO(&readfds); /* 清除readfds */ 
        FD_SET(fd, &readfds); /* 将fd添加到readfds里面 */ 
         /* 构造超时时间 */ 
         timeout.tv_sec = 0; 
         timeout.tv_usec = 500000; /* 500ms */ 
         ret = select(fd + 1, &readfds, NULL, NULL, &timeout); 
         switch (ret) { 
            case 0: /* 超时 */ 
                printf("timeout!\r\n");
                break; 
            case -1: /* 错误 */ 
                printf("error!\r\n"); 
                break; 
            default: /* 可以读取数据 */ 
            if(FD_ISSET(fd, &readfds))   /* 判断是否为fd文件描述符 */ 
              {
                   /* 使用read函数读取数据 */ 
              } 
             break; 
        } 
     }
    

    poll

      在单个线程中, select函数能够监视的文件描述符数量有最大的限制,一般为1024,可以修改内核将监视的文件描述符数量改大,但是这样会降低效率!这个时候就可以使用poll函数, poll函数本质上和 select没有太大的差别,但是poll函数没有最大文件描述符限制,Linx应用程序中poll函数原型如下所示:

    int poll(struct pollfd *fds, nfds_t nfds, int timeout)
    

      函数参数和返回值含义如下
      fds:要监视的文件描述符集合以及要监视的事件,为一个数组,数组元素都是结构体 polled类型的, pollfd结构体如下所示

    struct pollfd 
    { 
    	int fd; /* 文件描述符 文件描述符 文件描述符 */ 
    	short events; /* 请求的事件 请求的事件 请求的事件 */
    	short revents; /* 返回的事件 返回的事件 返回的事件 */ 
    };
    

      fd是要监视的文件描述符,如果f无效的话那么 events监视事件也就无效,并且 revents返回0。 events是要监视的事件,可监视的事件类型如下所示

    POLLIN		//有数据可以读取。
    POLLPRI		//有紧急的数据需要读取。
    POLLOUT		//可以写数据POLLERR指定的文件描述符发生错误POLLHUP指定的文件描述符挂起POLLNVAL无效的请求POLLRDNORM等同于 POLLIN
    

      revents:返回参数,也就是返回的事件,有Linux内核设置具体的返回事件。
      nfds:poll函数要监视的文件描述符数量
      timeout:超时时间,单位为ms
      返回值:返回 revents域中不为0的 polled结构体个数,也就是发生事件或错误的文件描述符数量;0,超时;-1,发生错误,并且设置errno为错误类型

    void main(void)
    { 
       int ret; 
       int fd; /* 要监视的文件描述符 */
       struct pollfd fds;
       fd = open(filename, O_RDWR | O_NONBLOCK); /* 非阻塞式访问 */ 
        /* 构造结构体 */ 
       fds.fd = fd; 
       fds.events = POLLIN; /* 监视数据是否可以读取 */
       ret = poll(&fds, 1, 500); /* 轮询文件是否可操作,超时500ms */ 
        if (ret)
         { /* 数据有效 */ 
          /* 读取数据 */ 
         } else if (ret == 0) 
         { 
             /* 超时 */ 
         } else if (ret < 0) 
         {
              /* 错误 */ 
         } 
     }
    

    epoll

      传统的 selcet和poll函数都会随着所监听的fd数量的增加,出现效率低下的问题,而且poll函数每次必须遍历所有的描述符来检查就绪的描述符,这个过程很浪费时间。为此,epoll因运而生,epoll就是为处理大并发而准备的,一般常常在网络编程中使用epoll函数。应用程序需要先使用 epoll_create函数创建一个 epoll句柄, epoll create函数原至如下.

    int epoll_create(int size)
    

      函数参数和返回值含义如下:
      size;从 Linux2.6.8开始此参数已经没有意义了,随便填写一个大于0的值就可以
      返回值:epoll句柄,如果为-1的话表示创建失败,epoll句柄创建成功以后使用,epoll ctl函数向其中添加要监视的文件描述符以及监视的事ct函数原型如下所示

    int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event)
    

      函数参数和返回值含义如下
      epfd;要操作的epoll句柄,也就是使用 epoll_create函数创建的epoll句柄。
      p:表示要对epfd( epoll句柄)进行的操作,可以设置为

    EPOLL CTL ADD		//向印fd添加文件参数d表示的描述符EPOLL CTL MOD修改参数fd的 event事件。
    EPOLL CTL DEL		//从f中删除过l描述符
    

      fd:要监视的文件描述
      event:要监视的事件类型,为 epoll_event结构体类型指针, epoll_event结构体类型如下所

    struct epoll_event 
    {
     	uint32_t events; /* epoll事件 */ 
    	epoll_data_t data; /* 用户数据 用户数据 */ 
    };
    

      结构体 epoll_event的 events成员变量表示要监视的事件,可选的事件如下所示

    EPOLLIN			//有数据可以读取EPOLLOUT可以写数据
    EPOLLPRI		//有紧急的数据需要读取EPOLLERI指定的文件描述符发生错误。
    EPOLLHUP		//指定的文件描述符挂起POLLET设置epo为边沿触发,默认触发模式为水平触发王
    POLLONESHOT		//一次性的监视,当监视完成以后还需要再次监视某个fd,那么就需要将fd重新添加到 epoll 里面
    

      上面这些事件可以进行“或”操作,也就是说可以设置监视多个事件返回值:0,成功;-1,失败,并且设置errno的值为相应的错误码。一切都设置好以后应用程序就可以通过 epoll_wait函数来等待事件的发生,类似 select函数。 epoll_wait函数原型如下所示

    int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout)
    

      函数参数和返回值含义如下
      epfd:要等待的 epoll
      events:指向 epoll_event结构体的数组,当有事件发生的时候Iimx内核会填写 events,调用者可以根据 events判断发生了哪些事件。
      prevents:events数组大小,必须大于0
      timeout:超时时间,单位为ms返回值:0,超时;-1,错误;其他值,准备就绪的文件描述符数量。
      epoll更多的是用在大规模的并发服务器上,因为在这种场合下 select和poll并不适合。当设计到的文件描述符(fd比较少的时候就适合用 selcet和pl本章我们就使用 sellect和poll这两个函数

    异步通知概念

      阻塞与非阻塞访问、poll函数提供了较好的解决设备访问的机制,但是如果有了异步通知,整套机制则更加完整了。
      异步通知的意思是:一旦设备就绪,则主动通知应用程序,这样应用程序根本就不需要查询设备状态,这一点非常类似于硬件上“中断”的概念,比较准确的称谓是“信号驱动的异步I/O”。信号是在软件层次上对中断机制的一种模拟,在原理上,一个进程收到一个信号与处理器收到一个中断请求可以说是一样的。信号是异步的,一个进程不必通过任何操作来等待信号的到达,事实上,进程也不知道信号到底什么时候到达。
      阻塞I/O意味着一直等待设备可访问后再访问,非阻塞I/O中使用poll()意味着查询设备是否可访问,而异步通知则意味着设备通知用户自身可访问,之后用户再进行I/O处理。由此可见,这几种I/O方式可以相互补充。

    Linux信号

      异步通知的核心就是信号,在 arch/xtensa/include/uapi/asm/signal.h文件中定义了Linux所支持的所有信号

    #define SIGHUP      1/* 终端挂起或控制进程终止 */ 
    #define SIGINT      2/* 终端中断(Ctrl+C组合键) */ 
    #define SIGQUIT     3 /* 终端退出(Ctrl+\组合键) */
    #define SIGILL      4/* 非法指令 */ 
    #define SIGTRAP     5/* debug使用,有断点指令产生 */
    #define SIGABRT     6/* 由abort(3)发出的退出指令 */ 
    #define SIGIOT      6 /* IOT指令 */ 
    #define SIGBUS      7 /* 总线错误 */ 
    #define SIGFPE      8 /* 浮点运算错误 */ 
    #define SIGKILL     9 /* 杀死、终止进程 */ 
    #define SIGUSR1     10 /* 用户自定义信号1 */ 
    #define SIGSEGV     11 /* 段违例(无效的内存段) */
    #define SIGUSR2     12 /* 用户自定义信号2 */ 
    #define SIGPIPE     13 /* 向非读管道写入数据 */ 
    #define SIGALRM     14 /* 闹钟 */
    #define SIGTERM     15 /* 软件终止 */
    #define SIGSTKFLT   16 /* 栈异常 */
    #define SIGCHLD     17 /* 子进程结束 */
    #define SIGCONT     18 /* 进程继续 */
    #define SIGSTOP     19 /* 停止进程的执行,只是暂停 */
    #define SIGTSTP     20 /* 停止进程的运行(Ctrl+Z组合键) */ 
    #define SIGTTIN     21 /* 后台进程需要从终端读取数据 */ 
    #define SIGTTOU     22 /* 后台进程需要向终端写数据 */
    #define SIGURG      23 /* 有"紧急"数据 */
    #define SIGXCPU     24 /* 超过CPU资源限制 */ 
    #define SIGXFSZ     25 /* 文件大小超额 */ 
    #define SIGVTALRM   26 /* 虚拟时钟信号 */ 
    #define SIGPROF     27 /* 时钟信号描述 */
    #define SIGWINCH    28 /* 窗口大小改变 */ 
    #define SIGIO       29 /* 可以进行输入/输出操作 */
    #define SIGPOLL SIGIO 
     /* #define SIGLOS 29 */ 
    #define SIGPWR      30 /* 断点重启 */ 
    #define SIGSYS      31 /* 非法的系统调用 */ 
    #define SIGUNUSED   31 /* 未使用信号 */
    

    异步通知代码

      我们使用中断的时候需要设置中断处理函数,同样的,如果要在应用程序中使用信号,那么就必须设置信号所使用的信号处理函数,在应用程序中使用 signal函数来设置指定信号的处理函数, signal函数原型如下所示

    void (*signal(int signum, void (*handler))(int)))(int);
    

      该函数原型较难理解,它可以分解为:

    typedef void (*sighandler_t)(int);
    sighandler_t signal(int signum, sighandler_t handler));
    

      第一个参数指定信号的值,第二个参数指定针对前面信号值的处理函数,若为SIG_IGN,表示忽略该信号;若为SIG_DFL,表示采用系统默认方式处理信号;若为用户自定义的函数,则信号被捕获到后,该函数将被执行。
      如果signal调用成功,它返回最后一次为信号signum绑定的处理函数的handler值,失败则返回SIG_ERR。

    驱动中的信号处理

    fasync_struct结构体

      首先我们需要在驱动程序中定义个 fasync_struct结构体指针变量, fasync_struct结构体内容如下

    struct fasync_struct 
    { spinlock_t fa_lock; 
    int magic; 
    int fa_fd; 
    struct fasync_struct *fa_next; 
    struct file *fa_file; 
    struct rcu_head fa_rcu; 
    };
    

      一般将 fasync_struct结构体指针变量定义到设备结构体中,比如在xxx_dev结构体中添加一个 fasync_struct结构体指针变量,结果如下所示

    struct xxx_dev 
    { 
    	struct device *dev; 
    	struct class *cls;
    	struct cdev cdev;
     ...... 
    	 struct fasync_struct *async_queue; /* 异步相关结构体 */
     }; 
    

    fasync函数

      如果要使用异步通知,需要在设备驱动中实现file_ operations操作集中的 fasync函数,此函数格式如下所示:

    int (*fasync) (int fd, struct file *filp, int on)
    

      fasync函数里面一般通过调用 fasync_helper函数来初始化前面定义的 fasync_struct结构体指针, fasync_helper函数原型如下

    int fasync_helper(int fd, struct file * filp, int on, struct fasync_struct **fapp)
    

      fasync_helper函数的前三个参数就是 fasync函数的那三个参数,第四个参数就是要初始化的 fasync_ struct结构体指针变量。当应用程序通过结构体指针变量。当应用程序通过“ fcntl(fd, F_SETFL, flags | FASYNC)”改变fasync标记的时候,驱动程序 file_operations操作集中的 fasync函数就会执行。

    struct xxx_dev 
    { 
    	......
    	struct fasync_struct *async_queue; /* 异步相关结构体 */ 
    }; 
    static int xxx_fasync(int fd, struct file *filp, int on)
    {
    	 struct xxx_dev *dev = (xxx_dev)filp->private_data; 
    	 if (fasync_helper(fd, filp, on, &dev->async_queue) < 0) 
    	 return -EIO; 
    	 return 0; 
     } 
    	 static struct file_operations xxx_ops =
     { 
       	...... 
      	.fasync = xxx_fasync,
    	  ...... 
     };
    

      在关闭驱动文件的时候需要在file_ operations操作集中的 release函数中释放 fasyn_fasync struct的释放函数同样为 fasync_helper, release函数参数参考实例如下

    static int xxx_release(struct inode *inode, struct file *filp) 
     { 
     	return xxx_fasync(-1, filp, 0); /* 删除异步通知 */
     }
    
    static struct file_operations xxx_ops =
     { 
    	...... 
    	.release = xxx_release, 
     };
    

      第3行通过调用示例代码 xxx_fasync函数来完成 fasync_struct的释放工作,但是,其最终还是通过 fasync_helper函数完成释放工作。

    kill_fasync函数

      当设备可以访问的时候,驱动程序需要向应用程序发出信号,相当于产生“中断” kill_fasync函数负责发送指定的信号, kill_fasync函数原型如下所示

    void kill_fasync(struct fasync_struct **fp, int sig, int band)
    

      函数参数和返回值含义如下:
      fasync struct 要操作的文件指针
      sig:要发送的信号
       band:可读时设置为 POLL IN,可写时设置为 POLL OUT。
      返回值:无。

    应用程序对异步通知的处理

      应用程序对异步通知的处理包括以下三步
      1、注册信号处理函数应用程序根据驱动程序所使用的信号来设置信号的处理函数,应用程序使用 signal函数来设置信号的处理函数。前面已经详细的讲过了,这里就不细讲了。
      2、将本应用程序的进程号告诉给内核使用fcntl(fd, F_SETOWN, getpid)将本应用程序的进程号告诉给内核
      3、开启异步通知使用如下两行程序开启异步通知:

    flags = fcntl(fd, F_GETFL); /* 获取当前的进程状态*/ 
    fcntl(fd, F_SETFL, flags | FASYNC); /* 开启当前进程异步通知功能 */
    

      重点就是通过 fcntl函数设置进程状态为 FASYNC,经过这一步,驱动程序中的 fasync函数就会执行。

    大家的鼓励是我继续创作的动力,如果觉得写的不错,欢迎关注,点赞,收藏,转发,谢谢!

    展开全文
  • 爆裂:未来社会的 9 大生存原则

    千次阅读 2018-04-12 10:41:39
    此,向他们表示祝贺。 本书的两位作者是极富远见的思考者。他们敏锐地看到,随着科技革命和通信革命的发生,世界已经进入数字时代,变革快速出现,而人类的思维却总是处于脱节状态。面对这个充满不对称性、复杂性...
  • 开发者和系统管理员笔记本上编译测试通过的容器可以批量地生产环境部署,包括 VMs(虚拟机)、bare metal、OpenStack 集群、云端、数据中心和其他的基础应用平台。容器是完全使用沙箱机制,相互之间不会有任何...
  • 微信十周年升级 8.0 版本,炸弹表情炸群;时隔两个多月之后马云现身,阿里股价暴涨;卫健委发布通知,春节返乡需要核酸证明。微信 8.0「炸」升级网友们提前过年了。如果不小心最近升级了微信,你可能要体验一...
  • 并确认与地图相关的图片资源有无加载,若加载了,将地图调用的代码从项目独立出来,看能否正常显示,若能显示,项目,使用二分法一半一半地删除引用的JavaScript,css代码,看这些JavaScript或css代码是否对...
  • 来源:微信公众号「LJ 说」,id:「LjNotes」。“你居然要从腾讯离职了!?”这是身边朋友得知我要离开的反应,似乎大家都难以理解这样的决定。从行业环境来看,中国互...
  • 用C++程序理解汉字的机内码表示

    万次阅读 2014-04-25 21:56:04
    汉字的编码是很多初学者不容易搞不明白的事情。... 简介一下GB2312-80的概况。 1、区位码 每个汉字及符号都有一个区位码,即每个汉字有一个区号(两位十进制)和一个位号(两位十进制)。一共分了94个区,每
  • 牛逼!Java 从入门到精通,超全汇总版

    万次阅读 多人点赞 2021-05-06 19:40:33
    就这一张,如果你能把图中内容都理解的差不多,那你就可以说是入门 Java 了,但是这里要注意一个概念,这并不等于说你是一个合格的初级 Java 程序员了,因为要想达到初级 Java 程序员的水平,你要会能干活,能...
  • 来源:大数据DT ...每个类别,逐一讨论数据输入的类型、作为黑箱的算法以及输出(为了简便易,即使真实算法不是黑箱也暂且把它当成黑箱)。 因为这是高层次的概述,所以我鼓励你深入研究感兴趣的具体应用.
  • 本篇文章我们来了解一下 MySQL 的高级内容。事务控制和锁定语句我们知道,MyISAM 和 MEMORY 存储引擎支持表级锁定(table-level locking),InnoDB ...
  • 转列:将多个列的数据一列输出 列转行:将某列一行中的数据拆分成多行 Explode炸函数 将hive某列一行中复杂的 array 或 map 结构拆分成多行(只能输入array或map) 语法 explode(col) select explode...
  • 点上方人工智能算法与Python大数据获取更多干货右上方···设为星标★,第一时间获取资源仅做学术分享,如有侵权,联系删除转载于 :学术志整理自观象台头条号、冬日黄花残阳如血知乎考...
  • 外审专家审完论文提出,稿件所有试验结果,已经发表一篇名为《金纳米柱的可控制备及其光学非线性性质》论文。 外审专家表示,后来那篇论文的所有试验结果,已经发表前述论文的文献:“该稿件选用了...
  • 书接上文,继上文实现了《复仇者联盟4:终局之战》... 这里我把200条左右的纯评论数据抽取解析了出来,贴下面,感兴趣的可以拿去: =========================================================================...
  • 你们都用IntelliJ IDEA吗?或许你们需要看一下这篇博文写前面以前一直用的elipce,如今入坑IntelliJ IDEA,没想到啊。深深的爱上了它,强大到无所不能;"工欲善其事必利其器",IntelliJ IDEA作为一个非常好用...
  • js指定tr添加一,删除一

    万次阅读 2016-08-09 14:14:18
     1 此行下插入新  2 function instTR(){  var tab=document.getElementById('tab');  var n=document.getElementById('x').rowIndex+1;  var tr=tab.insertRow(n);  var td=tr.inser
  • 《编码:隐匿计算机软硬件背后的语言》   第一章 电筒密谈 假若你才10岁,你的好朋友与你临街而住,而且你们卧室的窗户面对着面。每天晚上,当父母像平常一样很早催你上床睡觉时,你可能还想与好朋友交流思想...
  • //2018/09/28 当初开始面试时就想着,以后我一定要写一篇面经,现在是来还愿的时候了。 首先,嗯,非常感谢牛客平台,提供了很多信息啊。而且去年11月曾报名左神的课程,...而且自从听了左神讲的各种排序算法,...
  • HIVE介绍 Hive是基于Hadoop的一个...HiveHadoop生态位置如下所示: hive和hadoop的关系: 1)Hive处理的数据存储HDFS 2)Hive分析数据底层的实现是MapReduce 3)执行程序运行Yarn上 Hive的基本操作 ...
  • 原标题:和年薪百万的CFO大佬聊天,我慌了!"我太失败了!”上周,小志给我发来信息。小志毕业就来到一家公司做财务,两年来任劳任怨,说已经有3年的工作经验一点也不过分,数据统计、记账结账、纳税申报、...
  • [Phoenix基础]-- 常见问题解答

    千次阅读 2017-06-08 11:30:50
    常问问题 我想开始 有没有凤凰Hello World? 凤凰城有没有办法批量加载? 如何将Phoenix表映射到现有的HBase表? 有没有任何提示来优化凤凰?... 凤凰可以任意时间戳的表上工作,像HBase API一样...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,100
精华内容 840
关键字:

在图中表示位置是先列后行吗