在Unix系统中会大量使用“同步化”(synchronized),“异步化”(nonsynchronized),“同步”(synchronous),以及“异步”(asynchronous)等令人混淆的术语。
现结合Unix中读取和写入操作来分别介绍这四种术语的具体含义:
同步(synchronous)写操作:调用进程会等到所要写入的数据(至少)被存入内核的缓冲区后(用户进程的写操作一般都是数据从用户缓冲区复制到内核缓冲区,然后由内核缓冲区刷新的磁盘文件中),系统调用才会返回。
异步(asynchronous)写操作:调用进程会在用户缓冲区中还有数据也就是数据离开用户空间之前先返回,它不会等待真正的写任务完成后再返回,实际上该系统调用就是只是将对应的写操作排入请求队列中等待稍后处理,稍后的处理由系统来调度的,再与调用进程是没有关系的,进程只要一返回,之后的写入操作就和调用进程无关。所以在这种情况下,必须要有一种机制来判断排入队列的操作是否真的完成了以及实际完成的结果。
相比较于同步操作,同步化(synchronized)操作有较多的限制,但是更为安全,同步化写入操作会将最终要写入的数据刷新到磁盘的文件中,以确保磁盘上的数据与相应的内核缓冲区里面的数据始终是同步的。
而同步化读取操作总是会返回数据的最新副本,而且假设它来自磁盘。
总之,“同步”与“异步”等术语用于指出I/O操作在返回之前是否需要等待某个事件(例如数据的存储),而“同步化”与“异步化”等术语用于指定必须要发生何种事件(例如将数据写入到磁盘)。
在一般情况下(也就是默认情况下),Unix的写入操作是同步的进行,但是异步化,而读取操作则是同步的进行且同步化,而对于写入操作而言,上述提到的四种组合都是可以搭配的,现来讨论下这四种方式与写入操作的搭配组合:
同步的同步化:写入操作会等到数据被刷新到磁盘后才返回,如果在打开文件时指定了O_SYNC标志,便会表现这种行为。
同步的异步化:写入操作会等到数据被存入到内核缓冲区后才返回,这也是通常的行为模式。
异步的同步化:写入操作只在写入请求被排入队列后就返回。等到该写入操作执行时,数据会保证写入到磁盘中。
异步的异步化:写入操作只在写入请求被排入队列后就返回,等到该写入操作执行时,数据会保证至少存入到内核缓冲区。
对于读操作重要的一点是:读操作始终都是同步化的,保证读取操作总是会返回磁盘上的最新的数据副本,读取旧数据毫无意义,但是读取操作可以是同步的也可以是异步的。
同步的同步化:读取操作会在最新的数据被存入到应用程序的用户缓冲区后返回,这也是读取操作的通常行为模式。
异步的同步化:读取操作会在读取请求被排入到队列后返回,但是当读取操作实际被执行时会返回最新的数据。