當(dāng)多個(gè)進(jìn)程同時(shí)訪問(wèn)一個(gè)文件的時(shí)候卓鹿,普通的write/read在執(zhí)行的時(shí)候灰羽,無(wú)法保證操作的原子性亥宿,可能會(huì)導(dǎo)致文件被污染搀缠,達(dá)不到預(yù)期的結(jié)果奇瘦。
任何一個(gè)需要多個(gè)函數(shù)調(diào)用的操作都不可能是原子操作荣刑,因?yàn)樵趦蓚€(gè)函數(shù)調(diào)用間伺帘,內(nèi)核可能會(huì)將進(jìn)程掛起執(zhí)行另外的進(jìn)程卒密。
如果想要避免這種情況的話庇谆,則需要使用pread/pwrite函數(shù)
ssize_t pread(int fd 岳掐,void *buffer ,size_t size饭耳,off_t offset)
返回真正讀取到的字節(jié)數(shù)串述,offset是指的從文件開(kāi)始位置起的offset個(gè)字節(jié)數(shù)開(kāi)始讀。其余的參數(shù)與read無(wú)異哥攘。
PS:
pread是無(wú)法中斷的原子操作剖煌,無(wú)法中斷它的定位和讀取操作
pread讀取過(guò)后的文件偏移量不會(huì)發(fā)生改變
同理pwrite也是一樣的
而在文件創(chuàng)建的時(shí)候也是一樣的,當(dāng)需要做文件創(chuàng)建同步的時(shí)候逝淹,我們需要在O_CREATE的時(shí)候耕姊,加上O_EXCL標(biāo)志位,當(dāng)已經(jīng)創(chuàng)建過(guò)的話栅葡,會(huì)返回fd茉兰,否則返回錯(cuò)誤
dup與dup2函數(shù)
int dup( int filedes):
傳入一個(gè)文件描述符,返回當(dāng)前可用的最小文件描述符欣簇。
int dup2(int filedes规脸,int filedes2):
傳入文件描述符坯约,以及新的文件描述符,如果新的文件描述符所指向的文件已經(jīng)打開(kāi)莫鸭,則會(huì)強(qiáng)行將其關(guān)閉后闹丐,將該文件描述符指向到已存在的文件描述符。
如果filedes和filedes2指向同一個(gè)文件被因,則不做任何處理卿拴,直接返回filedes2,不會(huì)關(guān)閉文件
新返回回來(lái)的filedes2會(huì)共享filedes的文件狀態(tài)標(biāo)識(shí)梨与,文件偏移量等等信息堕花。因?yàn)樗鼈兊奈募羔槙?huì)指向文件表的同一個(gè)位置。只是fd不一樣而已粥鞋。