熱搜:win11繞過硬件限制安裝 一鍵重裝Win10系統(tǒng) 最干凈的u盤啟動(dòng)盤 真正純凈版的win7系統(tǒng)
時(shí)間:2014-12-26 15:58:35 作者:qipeng 來源:系統(tǒng)之家 1. 掃描二維碼隨時(shí)看資訊 2. 請(qǐng)使用手機(jī)瀏覽器訪問: https://m.xitongzhijia.net/xtjc/20141226/33535.html 手機(jī)查看 評(píng)論 反饋
現(xiàn)在對(duì)前一節(jié)文件I/O(1)的幾個(gè)操作進(jìn)一步說明:
1. 完成write之后,文件中當(dāng)前偏移量即所增加的字節(jié)數(shù)。如果當(dāng)前偏移量大于文件長度,則將i節(jié)點(diǎn)中當(dāng)前文件長度設(shè)為當(dāng)前文件偏移量。
2. 用O_APPEND打開一個(gè)文件,相應(yīng)標(biāo)志會(huì)被設(shè)置到文件狀態(tài)標(biāo)識(shí)中。每次寫時(shí),當(dāng)前偏移量會(huì)被設(shè)置為i節(jié)點(diǎn)中的文件長度
3. lseek定位到文件尾端時(shí),則文件當(dāng)前偏移量會(huì)被設(shè)置為當(dāng)前文件長度。
可能有多個(gè)文件描述符指向同一文件表項(xiàng)。調(diào)用dup和fork時(shí)都能看到這一點(diǎn)。
多個(gè)進(jìn)程讀同一文件能正確工作。但多個(gè)進(jìn)程寫同一文件時(shí),可能產(chǎn)生預(yù)期不到的后果?梢岳迷硬倏v避免這種情況。
原子操作
一般而言,原子操作指的是由多部組成的操作。如果該院自地執(zhí)行,要么執(zhí)行完所以步驟,要么一步也不執(zhí)行。
1. 添加至一個(gè)文件
考慮一個(gè)進(jìn)程,它要講數(shù)據(jù)添加到一個(gè)文件尾端。早期UNIX不支持open,所以可以如下實(shí)現(xiàn):
代碼如下:
if(lseek(fd, 0L, 2)《0)
err_sys(“lseekerror”);
if(write(fd, buf, 100) != 100)
err_sys(“writeerror”);
對(duì)于單個(gè)進(jìn)程,這段程序能正常工作。但多個(gè)進(jìn)程就不一定。結(jié)社進(jìn)程A和B都對(duì)同一文件進(jìn)行添加操作。每個(gè)進(jìn)程都打開該文件,此時(shí)數(shù)據(jù)結(jié)構(gòu)之間關(guān)系如圖2中所示。假定A調(diào)用lseek,將A的當(dāng)前偏移量設(shè)置為1500。進(jìn)程B執(zhí)行l(wèi)seek也將其當(dāng)前偏移量設(shè)為1500。然后B調(diào)用write,將當(dāng)前偏移量增至1600。然后內(nèi)核又進(jìn)行進(jìn)程切換使進(jìn)程A恢復(fù)運(yùn)行,當(dāng)A調(diào)用write時(shí),從其當(dāng)前偏移量1500處將數(shù)據(jù)寫入,將替換B剛寫入到該文件中的數(shù)據(jù)。
問題出在邏輯操作“定位到文件尾端處,然后寫“使用了兩個(gè)分開的函數(shù)調(diào)用。解決辦法是使這兩個(gè)操作成為一個(gè)原子操作。O_APPEND標(biāo)識(shí),使內(nèi)核每次對(duì)文件進(jìn)行寫之前,都將進(jìn)程當(dāng)前偏移量設(shè)置到該文件的尾端處。
2.pread和pwrite函數(shù)
原子性地定位搜索和執(zhí)行I/0。
代碼如下:
#include 《unistd.h》
ssize_t pread(int fd, void *buf, size_tcount, off_t offset);
ssize_t pwrite(int fd, const void *buf,size_t count, off_t offset);
ssize_t pread(int fd, void *buf, size_tcount, off_t offset);
ssize_t pwrite(int fd, const void *buf,size_t count, off_t offset);
dup和dup2函數(shù)
代碼如下:
#include 《unistd.h》
int dup(int oldfd);
int dup2(int oldfd, int newfd);
上面兩個(gè)函數(shù)都可用來復(fù)制一個(gè)現(xiàn)存的文件描述符。
由dup返回的新文件描述符一定是當(dāng)前可用文件描述符中的最小數(shù)值。用dup2則可以用newfd參數(shù)指定新描述符的數(shù)值。如果newfd已經(jīng)打開,則先將其關(guān)閉。如果newfd等于oldfd,則dup2返回newfd而不關(guān)閉它。
假定我們的進(jìn)程執(zhí)行了:
newfd = dup(1);
當(dāng)此函數(shù)執(zhí)行時(shí),假設(shè)下一個(gè)可用的描述符是3。因?yàn)檫@兩個(gè)描述符指向同一個(gè)文件表項(xiàng),所以他們共享文件標(biāo)志以及同一文件偏移量。
sync、fsync和fdatasync
代碼如下:
#include 《unistd.h》
void sync(void);
int fsync(int fd);
int fdatasync(int fd);
當(dāng)將數(shù)據(jù)寫入文件時(shí),內(nèi)核通常將數(shù)據(jù)復(fù)制到一個(gè)緩沖區(qū),直到緩沖區(qū)寫滿,再將緩沖區(qū)排路輸出隊(duì)列,然后等待其到達(dá)隊(duì)首,才進(jìn)行實(shí)際的I/O操作。這種輸出防暑被稱為延遲寫。延遲寫減少了磁盤的讀寫次數(shù),但卻降低了文件內(nèi)容的跟新速度。當(dāng)系統(tǒng)發(fā)生故障時(shí),延遲寫可能造成文件跟新內(nèi)容的丟失。為了保證磁盤上實(shí)際文件系統(tǒng)與緩沖區(qū)高速緩存中內(nèi)容一致性,UNIX系統(tǒng)提供了sync、fsync和fdatasync 三個(gè)函數(shù)。
fcntl函數(shù)
代碼如下:
#include 《unistd.h》
#include 《fcntl.h》
int fcntl(int fd, int cmd, 。。。 /* arg */ );
可以改變已經(jīng)打開文件的性質(zhì)。
復(fù)制一個(gè)現(xiàn)有的描述符(cmd=F_DUPFD)
獲得或設(shè)置文件描述符(cmd=F_GETFD|F_SETFD)
獲得或設(shè)置文件狀態(tài)標(biāo)志(cmd=F_GETFL|F_SETFL)
獲得或設(shè)置異步I/O所有權(quán)(cmd=F_GETOWN|F_SETOWN)
獲得或設(shè)置記錄鎖(cmd=F_GETLK|F_SETLK、F_SETLKW)
可以用fcntl函數(shù)設(shè)置文件狀態(tài),常用設(shè)置套接字描述符為非阻塞O_NONBLOCK
ioctl函數(shù)
#include 《sys/ioctl.h》
int ioctl(int d, int request, 。。。);
提供了一個(gè)用于控制設(shè)備及其描述符行為和配置底層服務(wù)的接口。
/dev/fd
打開文件/dev/fd/n等效于復(fù)制描述符n。
上面就是Linux文件I/O的相關(guān)介紹了,通過這些介紹相信你已經(jīng)對(duì)文件I/O有了進(jìn)一步的了解,如果你還想了解更多的相關(guān)知識(shí)的話,不妨多多關(guān)注本網(wǎng)站吧。
發(fā)表評(píng)論
共0條
評(píng)論就這些咯,讓大家也知道你的獨(dú)特見解
立即評(píng)論以上留言僅代表用戶個(gè)人觀點(diǎn),不代表系統(tǒng)之家立場(chǎng)