branch,tag,version,patch 分支,标签,版本,补丁

版本控制工具中平时使用的较多的是提交commit,更新update……,对于分支,标签,版本,补丁这些概念不是经常用,这篇文章介绍了分支版本,标签的使用场景:

CVS Branch 和 Merge 在 Eclipse 中的使用 http://blog.csdn.net/sanshiqiduer/article/details/2423936

Branch:

我们在version Release_1_0建立一个branch,比如叫做“Release_1_0_Branch”, 这时CVS会同时建立一个regular tag “Root_of_Releas_1_0_Branch”,这个“Root_of_Releas_1_0_Branch” tag的用途是为了以后branch 合并到main trunk时提供一个参考点。

之后开发新版本的人员就基于main trunk工作,而fix bug的人员就基于Release_1_0_Branch工作。
一旦在Release_1_0_Branch上将Release_1_0的bug修复了,我们就可以将Release_1_0_Branch合并到main trunk中来,从而一次性remove the bugs。

Merge:

fix bug之后,这时我们要把 Brank  merge main trunk 了。

1、选择 project -> Right click your project name, choose Replace With > Another Branch or Version from the context menu,
Then select the HEAD to replace with your current version in your workplace。

2、Select the project and choose Team > Merge.

在随后出现的对话框中,你首先选择regular tag ”Root_of_Releas_1_0_Branch”,然后在下一步中选择你的Branch“Release_1_0_Branch”。

3、Synchronize view中的操作

在第二步结束后,Synchronize view中将显示“all the differences between the branch and your workspace version(that is the HEAD version)”,你必须在Synchronize view中通过菜单中提供的“Update, Override and Update, or Mark as Merged”手工决定合并到你工作区的change。

4、在所有期望的changes都被merge到你的工作区后,你就可以“commit”the changes to the repository了。

 

tag作用:
1.指示你正工作在那个branch上。(因为每个branch都有一个tag.
2.如果你不想更新一个大目录树的一部分,你可以利用sticky   tag.
(sticky   tag的定义:If   you   check   out   a   certain   revision   (such   as   1.4)   it   will   become   sticky.  Subsequent   cvs   update   commands   will   not   retrieve   the   latest   revision   until   you   reset   the   tag   with   cvs   update   -A.)

什么情况下用branch:
若release1.0已经发布,现在正在开发2.0.这时发现在1.0中发现严重bug,但2.0的code还没有稳定,你就要从1.0建立一个branch.创建branch的时也要指定一个tag,同时文件的版本号都会改变。

补丁程序(patch)

是一个包含了某一资源的资源库实例和该资源的工作空间实例之间差别的文件。补丁程序可表示出一个单独文件(或完整项目)中的差别。补丁程序允许您共享尚未提交到CVS的更改。有很多原因使得补丁程序非常有用。

●       由于您没有向CVS提交资源的权限,所以您需要将该补丁程序发送给具有资源提交权限的人,然后再由他向CVS提交资源。

●       您需要为所遇到的问题准备一个应急修改或临时工作空间。

●       在将重要的更改提交到CVS之前,您可能想让别人对您的更改进行校验。在这种情况下,您可以将补丁程序发送给校验人以让他们进行测试。

通过使用快捷菜单Team | Create Patch…,我们就可以创建补丁文件。该操作会调用Create Patch向导来指导您完成补丁文件的创建。若要应用某补丁程序,则使用快捷菜单Team | Apply Patch…。该操作会调用Apply Patch向导。Eclipse联机文档Workbench User Guide的Working with patches 一节中有关上述两个操作的描述非常精彩。

补丁生成的是一个文本文件。包含了本地环境与已提交版本的区别,使用apply可以依据已提交版本再次生成本地环境。

Continue reading branch,tag,version,patch 分支,标签,版本,补丁

EAI中的应用集成和过程集成

书上抄网上,网上互相抄,一模一样的话,就是没看懂,还是这个解释的稍微清楚点:

应用层集成
应用层集成主要是指在通过应用接口对应用系统实现集成。应用接口(Application Programming Interface - API)是通用应用系统以及客户自建系统为方便和外部应用系统连接而对外开放的软件接口。目前时常上的一些标准商业软件,例如ERP系统,CRM系统,电子商务系统等,都有非常成熟的API。通过采用API层的应用集成,用户可以不对应用的数据库直接进行操作。

过程集成
过程集成是将不同单位部门、或不同企业的不同业务流程利用应用集成技术集成在一起,实现跨部门、跨系统、跨企业的流程共用。

Continue reading EAI中的应用集成和过程集成

面向对象的原则

1、"开-闭"原则——模块应对扩展开放,而对修改关闭。
2、里氏代换原则——如果调用的是父类的话,那么换成子类也完全可以运行。里氏代换原则是继承复用的一个基础。
3、合成复用原则——要少用继承,多用合成关系来实现。 --这也造成结构复杂,实现成本增加
4、依赖倒转原则——抽象不应该依赖与细节,细节应当依赖与抽象。 要针对接口编程,而不是针对实现编程。
5、接口隔离原则——每一个接口应该是一种角色,不多不少,不干不该干的事,该干的事都要干。
6、单一职责
7、迪米特法则——最少知识原则。不要和陌生人说话。--但这也造成不同模块通信效率低,产生大量传递简介调用的小方法。

 

这不过是对面向对象精髓的阐述:模块化,抽象,信息隐藏,高内聚,低耦合。

Continue reading 面向对象的原则

NoSQL对REST的影响,无状态,扩展性

infoq文章 http://www.infoq.com/news/2011/10/nosql-rest 谈到noSql可能对REST产生的影响。

REST要求状态要么被放入资源状态中,要么保存在客户端上。而这个资源就可以使用NoSql来存储,像Redis。

无状态通信最直接的理由就是可伸缩性—— 如果服务器需要保持客户端状态,那么大量的客户端交互会严重影响服务器的内存可用空间(footprint)。

 

参见:

http://www.infoq.com/cn/articles/rest-introduction  深入浅出REST

http://a-kuei.iteye.com/blog/706836  对REST中无状态(stateless)的理解

Continue reading NoSQL对REST的影响,无状态,扩展性

REST 将替代 SOAP?

infoq上看到这篇文章http://www.infoq.com/articles/rest-soap,其统计数据表明REST(在SOA中)越来越占主导优势。并在文章结尾为mule打了个广告,原来作者是MuleSoft的创始人。文章评论很多,打头的把emule和mule混淆,认为eMule(应该是mule)仍然解决不了根本的集成问题,后面的拿这个开涮!

写这篇文章时我对REST早闻其名,最近也用过,但是自己还觉得没怎么透彻的理解。不过由于早年深受webservice欺骗和xml的虐待,对soap一直深恶痛绝。使用rest基于json格式的服务后,感觉如此之美。

大执概括一下这篇文章:

Web API越来越火从2005的105个到2011的5000以上。

REST风格从2008年开始急剧上身(60%->74%),而SOAP上升缓慢(25%->15%)。

REST的上升要得益于客户端访问的便捷,json格式要比xml格式易懂,易用,简洁。目前大部分api都提供或只提供json格式。

后面就开始说各Api集成问题,然后提出使用mule解决。

Continue reading REST 将替代 SOAP?

冒烟测试 smoke test

没听过这个词的认为说它的人很牛X,了解了后会认为是装X,原来就是这么easy。

冒烟测试的对象是每一个新编译的需要正式测试的软件版本,目的是确认软件基本功能正常,可以进行后续的正式测试工作。冒烟测试的执行者是版本编译人员。

上面一句话很经典,冒烟测试:

  • 费时很短,吸根烟的功夫。
  • 是正式测试前的检验步骤,这个都没通过那就不能进行测试流程。
  • 关注改动,由编译人员或是修改者执行。

Continue reading 冒烟测试 smoke test

三级封锁协议两段锁以及隔离级别

并发控制的主要方法是封锁(Locking)。就是要用正确的方式调度并发操作,使一个用户的事务在执行过程中不受其他事务的干扰,从而避免造成数据的不一致性。
封锁是使事务对它要操作的数据有一定的控制能力。封锁通常具有3个环节:第一个环节是申请加锁,即事务在操作前要对它将使用的数据提出加锁申请;第二个环节是获得锁,即当条件成熟时,系统允许事务对数据进行加锁,从而事务获得数据的控制权;第三个环节是释放锁,即完成操作后事务放弃数据的控制权。
基本的封锁类型有以下两种: 锁是事务实现并发控制隔离级别的实现方法
1.排它锁(Exclusive Locks,简称X锁)
排它锁也称为独占锁或写锁。一旦事务T对数据对象A加上排它锁(X锁),则只允许T读取和修改A,其他任何事务既不能读取和修改A,也不能再对A加任何类型的锁,直到T释放A上的锁为止。
2.共享锁(Share Locks,简称S锁)
共享锁又称读锁。如果事务T对数据对象A加上共享锁(S锁),其他事务只能再对A加S锁,不能加X锁,直到事务T释放A上的S锁为止。
在对数据进行加锁时,另外需要约定并执行一些规则和协议,其中包括何时申请锁,保持锁的时间以及何时释放等,这些规则就称为封锁协议(Locking Protocol){谁定义的?-确实找不出来,也许就是理论基础},其总共分为以下三级:
(1)一级封锁协议。一级封锁协议是事务T在修改数据之前必须先对其加X锁,直到事务结束才释放。 防止丢失更新。
(2)二级封锁协议。二级封锁协议是事务T对要修改数据必须先加X锁,直到事务结束才释放X锁;对要读取的数据必须先加S锁,读完后即可释放S锁。 防止丢失更新和脏读

 T1T2 
 Slock A  
 读A=20
unlcok A 事务还没完成,但是读完了马上释放
  
  Xlock A 
  A = 60 
  Unclock A
事务提交
 
 SlockA  
 A=60
不可重复读
  
 T1事务造成了不可重复读  

(3)三级封锁协议。三级封锁协议是事务T在读取数据之前必须先对其加S锁,在要修改数据之前必须先对其加X锁,直到事务结束后才释放所有锁。 防止丢失更新,脏读,不可重复读

相对于二级锁,Slock的范围加长了,开销自然大了。

执行了封锁协议之后,就可以克服数据库操作中的数据不一致所引起的问题。

参看图4。

Snap2

从图4的情况我们看到事务T1在执行过程中独自占用并加X锁,直到处理完之后再释放锁,T2虽然也需要使用,但是在封锁协议的约束之下,T2所要求的X 锁就被拒绝,因此必须处于等待状态,直到T1释放之后,T2才获得使用的权利,这样就不会发生使用冲突,避免了数据的丢失。这里我们看到,此处实际上是执行了一级封锁协议。

下面我们看图5。

Snap3

通过图5,能够清楚的看到,由于施行了封锁协议,使事务T1使用了共享锁占用A,B两块数据,这样T2需要加上的X锁就无法实现,(如果是S锁,虽然可以加上,但也不能够随便修改数据,只是读取一下数据。)当T1释放锁之后,T2就可以得到并使用锁了,这样读取的数据B仍然还是100,不影响A+B的结果,这就是可重复读取。因此我们看到,其实这里用的就是三级封锁协议

 

参看图6,事务T1在对数据C修改之前,先加上了X锁,修改后写回数据库,这时T2请求在C上添加S锁,因为T1加了X锁,T2只好等待,当T1因为某种原因撤销了修改的数据后,C就恢复了原来的数据100,等T1释放 X锁后T2获得C上的S锁,读到的还是C=100,因此避免了读出“脏”数据。这里使用的其实就是二级封锁协议。

Snap1

 

两阶段封锁协议

对锁机制,保证事务可串行性的最常用协议是两阶段封锁协议。该协议要求每个事务分两个阶段提出加锁和解锁申请:

(1)增长阶段。事务可以获得锁,但不能释放锁。

(2)缩减阶段。事务可以释放锁,但不能获得锁。

一开始,事务处于增长阶段,事务根据需要获得锁。一旦该事务释放了锁,它就进入缩减阶段,不能再发出加锁请求。

两阶段封锁协议实现了事务集的串行化调度,但同时,一个事务的失败可能会引起一连串事务的回滚。为避免这种情况的发生,我们需要进一步加强对两阶段封锁协议的控制,这就是:严格两阶段封锁协议和强两阶段封锁协议。

严格两阶段封锁协议除了要求封锁是两阶段之外,还要求事务持有的所有排它锁必须在事务提交之后方可释放。这个要求保证未提交事务所写的任何数据,在该事务提交之前均以排它锁封锁,防止其他事务读取这些数据。

强两阶段封锁协议,要求事务提交之前不得释放任何锁。使用锁机制的数据库系统,要么使用严格两阶段封锁协议,要么使用强两阶段封锁协议。

两阶段封锁协议并不保证不会发生死锁,数据库系统必须采取其他的措施,预防和解决死锁问题。

 

数据库并发操作存在的异常情况:

1. 更新丢失(Lost update):事务 T1 读取数据 A,然后对 A 进行运算修改,最后写回数据库。如果在 T1 读取和写回数据库之间,有其他事务修改了 A 值,就造成了丢失更新,因为 T1 是在旧的数据上进行的运算。

第一类丢失更新(lost update): 在完全未隔离事务的情况下,两个事物更新同一条数据资源,某一事物异常终止,回滚造成第一个完成的更新也同时丢失。

第二类丢失更新(second lost updates):是不可重复读的特殊情况,如果两个事务都读取同一行,然后两个都进行写操作,并提交,第一个事务所做的改变就会丢失。

说他是第二类更新,又说他其实是不可重复读的特例,实际上在隔离级别上又和不可重复读相同,大部分分类根本不提这个第二类丢失更新。

2. 脏读取(Dirty Reads):一个事务读取了另一个未提交的并行事务写的数据。事务 T1 修改了数据 A,然后事务 T2 读取了数据 A,然后事务 T1 回滚了事务。则T2读的是错误的数据。

3. 不可重复读取(Non-repeatable Reads):一个事务对同一行数据重复读取两次但是却得到了不同结果。例如在两次读取中途有另外一个事务对该行数据进行了修改并提交

4. 幻读(Phantom Reads):也称为幻像(幻影,虚读)。事务在操作过程中进行两次查询,第二次查询结果包含了第一次查询中未出现的数据(这里并不要求两次查询SQL语句相同)这是因为在两次查询过程中有另外一个事务插入数据造成的。

幻读和不可重复读可认为是同类的,但是在控制上有区别。要控制不可重复读只需要控制记录的修改,而要控制幻读则要控制记录的添加和删除。所以,隔离级别可重复读取不能禁止幻读,而串行则可以。

 

事务隔离级别:

为了避免上面出现几种情况在标准SQL规范中定义了4个事务隔离级别,不同隔离级别对事务处理不同 。

1. 未授权读取(Read Uncommitted):也称未提交读。防止更新丢失(这不对应一级锁吗),如果一个事务已经开始写数据则另外一个数据则不允许同时进行写操作但允许其他事务读此行数据。该隔离级别可以通过“排他写锁”实现。事务隔离的最低级别,仅可保证不读取物理损坏的数据。与READ COMMITTED 隔离级相反,它允许读取已经被其它用户修改但尚未提交确定的数据。

2. 授权读取(Read Committed):也称提交读。1之上防止脏读取(这不对应二级锁吗)。这可以通过“瞬间共享读锁”和“排他写锁”实现,读取数据的事务允许其他事务继续访问该行数据,但是未提交写事务将会禁止其他事务访问该行。SQL Server 默认的级别。在此隔离级下,SELECT 命令不会返回尚未提交(Committed) 的数据,也不能返回脏数据。

3. 可重复读取(Repeatable Read):2之上防止不可重复读取(这不对应三级锁吗)。但是有时可能出现幻影数据,这可以通过“共享读锁”和“排他写锁”实现,读取数据事务将会禁止写事务(但允许读事务),写事务则禁止任何其他事务。在此隔离级下,用SELECT 命令读取的数据在整个命令执行过程中不会被更改。此选项会影响系统的效能,非必要情况最好不用此隔离级。

三级封锁协议并不能阻止幻读,修改的不能再被读取,但是新增(删除)的记录数可以统计。

4. 串行(Serializable):也称可串行读(这不对应两段锁吗)。提供严格的事务隔离,它要求事务序列化执行,事务只能一个接着一个地执行,但不能并发执行。如果仅仅通过 “行级锁”是无法实现事务序列化的,必须通过其他机制保证新插入的数据不会被刚执行查询操作事务访问到。事务隔离的最高级别,事务之间完全隔离。如果事务在可串行读隔离级别上运行,则可以保证任何并发重叠事务均是串行的。

 

 LU丢失更新DR脏读NRR非重复读SLU二类丢失更新PR幻像读
未提交读 RUYYYYY
提交读 RCNNYYY
可重复读 RRNNNNY
串行读 SNNNNN

ORACLE的默认事务级别:READ COMMITTED

ORACLE支持的事务隔离级别:

SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
SET TRANSACTION ISOLATION LEVEL READ ONLY;

少数数据库默认的隔离级别为Repeatable Read, 如MySQL InnoDB存储引擎
即使是最低的级别,也不会出现 第一类 丢失 更新问题 .

查看InnoDB系统级别的事务隔离级别:

mysql> SELECT @@global.tx_isolation;
+-----------------------+
| @@global.tx_isolation |
+-----------------------+
| REPEATABLE-READ       |
+-----------------------+
1 row in set (0.00 sec)

查看InnoDB会话级别的事务隔离级别:

mysql> SELECT @@tx_isolation;
+-----------------+
| @@tx_isolation  |
+-----------------+
| REPEATABLE-READ |
+-----------------+
1 row in set (0.00 sec)

修改事务隔离级别:

mysql> set global transaction isolation level read committed;
Query OK, 0 rows affected (0.00 sec)
mysql> set session transaction isolation level read committed;
Query OK, 0 rows affected (0.00 sec)

InnoDB的可重复读隔离级别和其他数据库的可重复读是有区别的,不会造成幻象读(phantom read)。

 

Oracle对隔离级别的支持:

Oracle 明确地支持READ COMMITTED(读已提交)和SERIALIZABLE(可串行化)隔离级别,因为标准中定义了这两种隔离级别。不过,这还不是全部。SQL标准试图 建立多种隔离级别,从而允许在各个级别上完成的查询有不同程度的一致性。REPEATABLE READ(可重复读)也是SQL标准定义的一个隔离级别,可以保证由查询得到读一致的(read-consistent)结果。在SQL标准的定义 中,READ COMMITTED不能提供一致的结果,而READ UNCOMMITTED(读未提交)级别用来得到非阻塞读(non-blocking read)。

不 过,在Oracle中,READ COMMITTED则有得到读一致查询所需的所有属性。在其他数据库中,READ COMMITTED查询可能(而且将会)返回数据库中根本不存在的答案(即实际上任何时间点上都没有这样的结果)。另外,Oracle还秉承了READ UNCOMMITTED的“精神”。(有些数据库)提供脏读的目的是为了支持非阻塞读,也就是说,查询不会被同一个数据的更新所阻塞,也不会因为查询而阻 塞同一数据的更新。不过,Oracle不需要脏读来达到这个目的,而且也不支持脏读。但在其他数据库中必须实现脏读来提供非阻塞读。

        除 了4个已定义的SQL隔离级别外,Oracle还提供了另外一个级别,称为READ ONLY(只读)。READ ONLY事务相对于无法在SQL中完成任何修改的REPEATABLE READ或SERIALIZABLE事务。如果事务使用READ ONLY隔离级别,只能看到事务开始那一刻提交的修改,但是插入、更新和删除不允许采用这种模式(其他会话可以更新数据,但是READ ONLY事务不行)。如果使用这种模式,可以得到REPEATABLE READ和SERIALIZABLE级别的隔离性。
        所以,Oracle对隔离级别的支持如下:
1.SERIALIZABLE:支持
2.READ ONLY:Oracle特有的级别,利用它来实现对REPEATABLE READ的支持
3.READ COMMITTED:支持
4.READ UNCOMMITTED:不明确且不完全地支持

 

参见:

http://seaizon.iteye.com/blog/571139

http://wenku.baidu.com/view/2f89710879563c1ec5da7130.html

http://yjhexy.iteye.com/blog/658706

http://www.cnblogs.com/ityfei/articles/1502153.html

http://heysql.com/mysql/%E5%9F%BA%E7%A1%80%E7%9A%84%EF%BC%9A%E5%B0%81%E9%94%81%E5%8D%8F%E8%AE%AE%EF%BC%8C%E9%94%81%E7%B1%BB%E5%9E%8B%EF%BC%8C%E8%84%8F%E8%AF%BB%E3%80%81%E4%B8%8D%E5%8F%AF%E9%87%8D%E5%A4%8D%E8%AF%BB%E5%92%8C/

Continue reading 三级封锁协议两段锁以及隔离级别

Notepad++ 使用技巧

早就听说过Notepad++大名,最近用了下,觉得挺不错。

可以使用主题配色,看文本舒服多了。我最喜欢Rubyblue。

配合插件NppFTP: notepad++ ftp插件,查看服务端日志方便多了。修改文本文件自然不在话下。我想用这个修改服务器上的php文件岂不很好。

之前格式化个xml还要用专门的xml工具,使用nodepad++的xml tools插件,使用它的pretty print(line break)功能就能很好的格式化。

要格式化json或者javascript,可以使用jsmin插件中的jsformat功能。

常用快捷键:

Ctrl+L 删除行

Ctrl+D复制行

Ctrl+W关闭当前编辑页

Ctrl+Alt+鼠标 纵列选择

Ctrl+M批量修改文件

Continue reading Notepad++ 使用技巧

BCNF 示例

BCNF定义:

定义一:若关系模式R是第一范式,且每个属性都不传递依赖于R的候选键。这种关系模式就是BCNF模式。

定义二:若关系模式R∈1NF,且对于每一个非平凡的函数依赖X→Y,都有X 包含码,则R∈BCNF。

平凡函数依赖

当关系中属性集合Y是属性集合X的子集时(Y?X),存在函数依赖X→Y,即一组属性函数决定它的所有子集,这种函数依赖称为平凡函数依赖。

非平凡函数依赖

当关系中属性集合Y不是属性集合X的子集时,存在函数依赖X→Y,则称这种函数依赖为非平凡函数依赖。

第二个不好记,也不好理解,理解第一个就是了,两个是等同的。

举例 ①:

假设仓库管理关系表为StorehouseManage(仓库ID, 存储物品ID, 管理员ID, 数量),且有一个管理员只在一个仓库工作;一个仓库可以存储多种物品。这个数据库表中存在如下决定关系:

(仓库ID, 存储物品ID) →(管理员ID, 数量)

(管理员ID, 存储物品ID) → (仓库ID, 数量)

所以,(仓库ID, 存储物品ID)和(管理员ID, 存储物品ID)都是StorehouseManage的候选关键字,表中的唯一非关键字段为数量,它是符合第三范式的。但是,由于存在如下决定关系:

(仓库ID) → (管理员ID)

(管理员ID) → (仓库ID)

即存在关键字段决定关键字段的情况,所以其不符合BCNF范式。也就是存在循环传递依赖(仓库ID) → (管理员ID)  → (仓库ID)

 

它会出现如下异常情况:

(1) 删除异常:

当仓库被清空后,所有"存储物品ID"和"数量"信息被删除的同时,"仓库ID"和"管理员ID"信息也被删除了。

(2) 插入异常:

当仓库没有存储任何物品时,无法给仓库分配管理员。

(3) 更新异常:

如果仓库换了管理员,则表中所有行的管理员ID都要修改。

把仓库管理关系表分解为二个关系表:

仓库管理:StorehouseManage(仓库ID, 管理员ID);

仓库:Storehouse(仓库ID, 存储物品ID, 数量)。

这样的数据库表是符合BCNF范式的,消除了删除异常、插入异常和更新异常。

举例②:

CSZ(CITY 城市,ST 街道,ZIP 邮编),其属性组上的函数依赖集是 F={( CITY,ST) →ZIP,ZIP→CITY}。

存在两个候选码:

(CITY, ST)->ZIP

(ST, ZIP)->CITY

(CITY, ST)和(ST, ZIP)是两个候选码,没有非主属性,自然CSZE∈3NF。

但存在传递依赖(CITY, ST)->ZIP->CITY, 所以CSZ∉BCNF。
关系模式CSZ 也存在种删除,插入,更新异常:

若将CSZ 分解为两个关系模式ZC(ZIP, CITY)和SZ(ST,ZIP),就不再有
非平凡的函数依赖的决定因素中不包含码的情况,都是BCNF 的关系模式了。

 

可以看到上面两个例子都是存在循环依赖造成的主属性传递依赖于码,不知道这是必然还是有别的例子属于3NF不属于BCNF但是也不存在循环依赖的情况?

Continue reading BCNF 示例

IO 接口,设备

IO这个词出现太多了太多了,这里整理一下思路。

计算机由控制单元,运算单元,存储单元,输入设备输出设备组成。其中IO指的就是输入输出。

关于IO又有接口,设备,操作的概念: 参见http://book.51cto.com/art/200704/45417.htm

IO接口

IO接口是实现外部设备与主机之间的连接和信息交换的设备,也可称I/O适配器(Adapter)或适配卡。目前有:

① 总线系统

② 直接内存访问(DMA)

③ 通道

④ SCSI(Small Computer System Interface)

⑤ 并行口

⑥ RS-232C接口

⑦ USB(Universal Serial Bus,通用串行总线)接口

⑧ IEEE 1394接口

IO接口的控制方式

(1)程序查询方式
这种方式下,CPU通过I/O指令询问指定外设当前的状态,如果外设准备就绪,则进行数据的输入或输出,否则CPU等待,循环查询。
这种方式的优点是结构简单,只需要少量的硬件电路即可,缺点是由于CPU的速度远远高于外设,因此通常处于等待状态,工作效率很低

(2)中断处理方式
在这种方式下,CPU不再被动等待,而是可以执行其他程序,一旦外设为数据交换准备就绪,可以向CPU提出服务请求,CPU如果响应该请求,便暂时停止当前程序的执行,转去执行与该请求对应的服务程序,完成后,再继续执行原来被中断的程序。
中断处理方式的优点是显而易见的,它不但为CPU省去了查询外设状态和等待外设就绪所花费的时间,提高了CPU的工作效率,还满足了外设的实时要求。但需要为每个I/O设备分配一个中断请求号和相应的中断服务程序,此外还需要一个中断控制器(I/O接口芯片)管理I/O设备提出的中断请求,例如设置中断屏蔽、中断请求优先级等。
此外,中断处理方式的缺点是每传送一个字符都要进行中断,启动中断控制器,还要保留和恢复现场以便能继续原程序的执行,花费的工作量很大,这样如果需要大量数据交换,系统的性能会很低。

(3)DMA(直接存储器存取)传送方式
DMA最明显的一个特点是它不是用软件而是采用一个专门的控制器来控制内存与外设之间的数据交流,无须CPU介入,大大提高CPU的工作效率。
在进行DMA数据传送之前,DMA控制器会向CPU申请总线控制 权,CPU如果允许,则将控制权交出,因此,在数据交换时,总线控制权由DMA控制器掌握,在传输结束后,DMA控制器将总线控制权交还给CPU。

(4) 通道方式

(5) 外围处理机(输入输出处理机)方式

有专门的处理机负责IO,一般用于大型系统

IO设备

键盘,鼠标,硬盘,打印机,扫描仪,网络设备等……

 

说实话,我还是没搞清楚!有时候把接口当成设备,有时又要把它当成控制方式,下面显然是控制方式:

常见I/O接口方式的分类方式有:

①按数据传送格式分类:串行接口和并行接口

②按时序控制方式分类:同步接口和异步接口

③按传送控制方式分类:直接程序传送接口,中断接口,DMA接口.

网络IO

还有网络IO这个说法,对于web方面的来说,性能与网络IO操作有很大关系,参见http://blog.csdn.net/historyasamirror/article/details/5778378

对于一个network IO (这里我们以read举例),它会涉及到两个系统对象,一个是调用这个IO的process (or thread),另一个就是系统内核(kernel)。

当一个read操作发生时,它会经历两个阶段:
1 等待数据准备 (Waiting for the data to be ready)
2 将数据从内核拷贝到进程中 (Copying the data from the kernel to the process)记住这两点很重要,因为这些IO Model的区别就是在两个阶段上各有不同的情况。

阻塞IO:特点就是在IO执行的两个阶段都被block了,调用返回时数据一定是准备好了的。

非阻塞IO:调用马上返回,但是数据可能还没准备好,需要不断的主动询问kernel数据好了没有

多路IO(IO multiplexing):先选择,后获取。选择操作会阻塞知道其中一个有数据。

异步IO:调用马上返回,有数据后会发信号。(和ajax取数据有点像哈)

此文将多路分为同步IO,

这篇文章有另一种分法:http://blog.chinaunix.net/space.php?uid=20357359&do=blog&id=1963658

090830172605

将多路归类为异步阻塞,各有各道理,知道原理就好。不钻牛角尖!

显然非阻塞异步IO性能应该是最好的,Nodejs中的事件驱动非阻塞IO就是AIO。

Continue reading IO 接口,设备

Pagination


Total views.

© 2013 - 2019. All rights reserved.

Powered by Hydejack v6.6.1