自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Linux命令之write調(diào)用的原子性

運(yùn)維 系統(tǒng)運(yùn)維
linuxman手冊(cè)頁中關(guān)于write調(diào)用的說明很不詳細(xì),并未說明寫操作是否是原子的,所以我們有必要查找SingleUNIXSpecification(SUS)對(duì)write調(diào)用的說明,在SUS中對(duì)此調(diào)用的說明還是比較詳細(xì)的。在繼續(xù)討論之前我們需要清楚內(nèi)核在寫文件之前會(huì)對(duì)該文件加鎖,不管是否成功完成寫操作,在返回之前都會(huì)解鎖。

linux命令是對(duì)Linux系統(tǒng)進(jìn)行管理的命令。本文介紹的關(guān)于linux命令中write調(diào)用的原子性的詳細(xì)描述,具體內(nèi)容如下所述。

UNIX環(huán)境高級(jí)編程中關(guān)于原子操作的介紹,其中有一種情形是在文件尾端添加數(shù)據(jù)。

文中說,如果多個(gè)進(jìn)程都需要將數(shù)據(jù)添加到某一文件,那么為了保證定位和寫數(shù)據(jù)這兩步是一個(gè)原子操作,需要在打開文件時(shí)設(shè)置O_APPEND標(biāo)志,看到這里我們就會(huì)想,雖然保證了定位和寫數(shù)據(jù)是一個(gè)原子操作,但是是否能夠保證多個(gè)進(jìn)程或線程寫入的數(shù)據(jù)不會(huì)交錯(cuò)呢,比如A進(jìn)程調(diào)用write(filedes1,"AAA",3),B進(jìn)程調(diào)用write(filedes2,"BBBB",4)(其中filedes1和filedes2指向同一個(gè)文件),但是***文件中的數(shù)據(jù)是否有可能是AABBBAB,如果這個(gè)文件是一個(gè)管道或socket呢。

linuxman手冊(cè)頁中關(guān)于write調(diào)用的說明很不詳細(xì),并未說明寫操作是否是原子的,所以我們有必要查找SingleUNIXSpecification(SUS)對(duì)write調(diào)用的說明,在SUS中對(duì)此調(diào)用的說明還是比較詳細(xì)的。在繼續(xù)討論之前我們需要清楚內(nèi)核在寫文件之前會(huì)對(duì)該文件加鎖,不管是否成功完成寫操作,在返回之前都會(huì)解鎖。

下面我們就以三種常見的文件根據(jù)SUS標(biāo)準(zhǔn)來討論上面提出的這個(gè)問題:

1.普通文件

SUS中也沒有說明在寫普通文件時(shí)是否會(huì)保證是原子操作,但是它說明了write調(diào)用可能并不能完全把我們需要寫入的數(shù)據(jù)寫到文件中去,那么什么情況下可能少寫數(shù)據(jù)呢?

SUS說明了兩種情況:磁盤已滿或則要寫入的文件的大小超過了當(dāng)前進(jìn)程的文件大小限制。其實(shí)至少還有一種情況,那就是內(nèi)核中的高速緩存不夠用的時(shí)候,比如linux內(nèi)核在發(fā)現(xiàn)高速緩存不夠用的時(shí)候就只寫入實(shí)際能夠容下的數(shù)據(jù)然后返回。正是由于存在上述***一種情況,所以說按照APUE那種方法在linux下面寫文件并不能保證我們的數(shù)據(jù)不會(huì)交錯(cuò)(不過我們可以根據(jù)write的返回值得知是否有發(fā)生交錯(cuò)的可能)。

其它的unix內(nèi)核可能會(huì)在實(shí)現(xiàn)上不同于linux內(nèi)核,他們可能在寫之前就判斷一下緩沖區(qū)是否足夠容納所有數(shù)據(jù),如果是這種情況,寫操作應(yīng)該就是原子的;也可能寫了一部分?jǐn)?shù)據(jù)后才發(fā)現(xiàn)緩沖區(qū)不夠用并讓當(dāng)前進(jìn)程進(jìn)入睡眠狀態(tài),此時(shí)內(nèi)核如果解鎖,那么在當(dāng)前進(jìn)程睡眠期間其它進(jìn)程可能寫了數(shù)據(jù),如果不解鎖,那么就是原子操作,其他進(jìn)程不可能在這個(gè)時(shí)候?qū)懭霐?shù)據(jù)。由上面的分析可知,正是由于SUS標(biāo)準(zhǔn)不太完整的標(biāo)準(zhǔn),我們不能確定一定可以按APUE的方法來同時(shí)向同一個(gè)普通文件寫數(shù)據(jù)。

如果我們非要在同一個(gè)文件中記錄多個(gè)進(jìn)程產(chǎn)生的數(shù)據(jù),我們***采用unix日志系統(tǒng)采用的方法,用一個(gè)專用進(jìn)程處理文件IO,其它進(jìn)程把需要寫的數(shù)據(jù)發(fā)送給這個(gè)專用進(jìn)程,這樣應(yīng)該比多個(gè)進(jìn)程同時(shí)寫一個(gè)文件可靠和高效。

2.管道

SUS對(duì)管道的寫操作說得更多也更明確,我們只需遵照其標(biāo)準(zhǔn)就可以了。對(duì)于write(pipefd,buf,nbyte),其要點(diǎn)如下:

如果nbyte<=PIPE_BUF,不管O_NONBLOCK是否設(shè)置,其寫操作都是原子的,就是說多個(gè)進(jìn)程都在此條件下同時(shí)寫同一個(gè)管道不會(huì)引起數(shù)據(jù)交錯(cuò)。

如果nbyte>PIPE_BUF,是不能保證寫操作是原子的,寫入的數(shù)據(jù)可能與其他進(jìn)程寫入的數(shù)據(jù)交錯(cuò)。

3.socket

SUS中對(duì)于寫socket并沒有說很多,我們無法從標(biāo)準(zhǔn)中得知write是否保證寫操作的原子性。我看了一下linux2.6.14內(nèi)核關(guān)于tcp數(shù)據(jù)的寫操作,發(fā)現(xiàn)它不是原子的,也從網(wǎng)上查到了這部分代碼的作者(們)對(duì)這個(gè)問題的看法,他(們)認(rèn)為對(duì)一個(gè)可能***阻塞的操作保證原子性是錯(cuò)誤的。我們也只能姑且這么認(rèn)為了。

補(bǔ)充:

對(duì)于用UNIX日志系統(tǒng)服務(wù)器的方法,連接端必須每個(gè)線程connect一次logsvr,這樣才能保證發(fā)過來的日志數(shù)據(jù)不互相錯(cuò)亂,保證原子性;此時(shí)logsvr只要用reactor方法來處理每個(gè)線程的連接就好,把這些fd放到隊(duì)列里輪流處理,寫文件,也保證了寫文件的原子性。

實(shí)際上日志服務(wù)器一般都是用UDP來完成的。

總結(jié):

希望本文介紹的Linux命令中write調(diào)用的原子性的內(nèi)容能夠?qū)ψx者有所幫助,更多有關(guān)linux系統(tǒng)的知識(shí)還有待于讀者去探索和學(xué)習(xí)。

【編輯推薦】

  1. Linux內(nèi)核級(jí)虛擬環(huán)境簡介
  2. Linux二十年歷程:昨天與今天
  3. Linux命令行configure參數(shù)介紹
  4. Linux系統(tǒng)中如何進(jìn)行網(wǎng)絡(luò)校時(shí)?
  5. linux服務(wù)器中的三個(gè)內(nèi)核文件簡介
責(zé)任編輯:韓亞珊 來源: 建站學(xué)
相關(guān)推薦

2023-01-05 12:30:32

Redis

2021-07-03 17:44:34

并發(fā)高并發(fā)原子性

2021-06-03 14:00:35

PolarDB

2021-06-02 16:30:33

PolarDB原子性數(shù)據(jù)庫

2010-03-18 17:00:57

Linux命令

2012-05-23 12:49:58

Java自增操作原子性

2021-11-24 09:55:56

Linuxnohup命令

2021-09-07 12:27:34

Linuxchmod命令

2012-05-10 08:46:05

Linuxsort命令

2012-05-11 10:07:55

Linuxfind

2012-05-10 08:37:54

Linuxxargs

2021-05-16 17:14:30

線程安全性

2021-01-12 07:39:48

線程線程安全

2009-07-31 16:14:27

linux cd命令Linux基本命令

2021-09-22 12:56:19

編程技能Golang

2019-02-27 09:28:15

Redis服務(wù)器事務(wù)

2024-03-18 11:24:54

2010-03-18 16:38:39

Linux命令

2009-10-22 10:59:29

linux磁盤命令

2009-10-22 11:36:31

linux磁盤管理
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)