Linux 中 write 系統呼叫具有原子性嗎?比如兩個程序同時 write 同乙個檔案會不會出現資料交錯的情況?標準裡面有規定嗎?

時間 2021-06-03 08:13:09

1樓:木匠劈柴

兩個程序/執行緒同時write同乙個檔案要分兩種情況,一是「檔案「被共享, 二是不被共享。

首先澄清一下概念,這裡的「檔案」指的是Linux 核心 in memory 檔案表(file table)裡的乙個檔案物件,即 file description。

第一種情況,會在dup或者fork時發生。這時有多個 fd 同時指向「檔案」,兩個程序/執行緒同時呼叫write,即使不同的fd,可「檔案」還是同乙個,write操作的兩個步驟(1. lseek 找寫入檔案位置;2.

vfs_write 寫入內容;)會被 file description 裡的 struct mutex f_pos_lock 加鎖保護,保證其原子性,不會出現檔案內容的overlap。

第二種情況,乙個檔案被open多次,file table 裡有對應的多個檔案物件,有單獨的檔案 position 和 f_pos_lock,此時同時write,會出現內容overlap的情況。

2樓:楊晨

取決於你的linux 版本號。

根據write的man page:write(2) - Linux manual page

Among the APIs subsequently listed arewrite() and writev(2). And

among the effects that should be atomic across threads (and

processes) are updates of the file offset. However, on Linux before

version 3.14, this was not the case:if two processes that share an

open file description (see open(2)) perform a write() (or writev(2))

at the same time, then the I/O operations were not atomic with

respect updating the file offset, with the result that the blocks of

data output by the two processes might (incorrectly) overlap. This

problem was fixed in Linux 3.14.

3樓:

先擺上結論:Linux3.14開始操作普通檔案,read(), write()都是原子的

以下摘錄自man

man 2 write

According to POSIX.1-2008/SUSv4 Section XSI 2.9.

7 ("Thread Interactions with Regular File

Operations"):

All of the following functions shall be atomic with respect to each other in the effects

specified in POSIX.1-2008 when they operate on regular files or symbolic links: ...

Among the APIs subsequently listed are write() and writev(2). And among the effects that should be atomic across threads (and processes) are updates of the file offset. However, on Linux before version 3.

14, this was not the case: if two processes that share an open file

description (see open(2)) perform a write() (or writev(2)) at the same time, then the I/O

operations were not atomic with respect updating the file offset, with the result that the

blocks of data output by the two processes might (incorrectly) overlap. This problem was

fixed in Linux 3.14.

4樓:唐浩然

寫檔案預設是先寫到作業系統cache的(由使用者空間你修改的資料先同步到cache),在cache中,相同的檔案指向同乙個vfs inode,即多個程序開啟的同乙個檔案,最終這個檔案在記憶體cache中被指向了同乙個vfs inode,你的修改~儲存並沒有直接寫回到磁碟。

cache中的資料,由作業系統按一定的演算法寫回到磁碟(比如髒頁的比例達到某個值)。

5樓:馬眾

write 操作是否原子操作得看你開啟裝置的驅動程式是否是互斥的。磁碟之類常用的write一般都不是原子操作的。看誰先flush。

6樓:

你說的兩個程序同時write乙個檔案和原子性操作該沒有關係.

每個程序開啟之後都會有乙個自己的buffer.

程序A write "A" 到檔案F

程序B write "B" 到檔案F

假設他們都沒有flush的話. 那A是看不到B的, B也看不到A. 他們都是在自己的檔案描述符表裡.

如果A flush了, 或者系統自動flush之後, 那F的內容就是A

同理, B也是一樣. 如果都flush了. 那已最後的為準.

linux中c庫函式和系統呼叫的區別是什麼呢?

徐聖 簡單的說c庫函式是為了方便使用者程式設計以及使用OS,對系統呼叫的封裝和擴充套件。封裝體現在使用系統功能介面更友好,更方便。直接調系統呼叫API,你會發現引數較多,各種返回異常需要自己處理。C庫一定程度上幫你做了這個工作。擴充套件體現在系統呼叫沒有的功能,c庫幫你擴充了。比如string庫很多...

linux下的read函式 write函式是屬於直接I O,為什麼函式原型的第二項就是要將資料放到輸入緩衝區內呢?

題主是各種概念混淆了。第一,write read原型 include ssize t write int filedes void buf size t nbytes 返回 若成功則返回寫入的位元組數,若出錯則返回 1 filedes 檔案描述符 buf 待寫入資料快取區 nbytes 要寫入的位元...

linux在系統呼叫進入核心時,為什麼要將引數從使用者空間拷貝到核心空間?不能直接訪問,或是使用memcpy嗎?非要使用copy from user才行嗎?

小呀小阿彭 在使用系統呼叫的時候要進行從特權級3到0的轉換在該轉換過程中 CPU會將事先放在tss中的 ss0 和esp0 賦予ss和esp暫存器這樣就造成了棧的變化通俗點說就是換了乙個棧而進行函式呼叫的時候pushl 指令是將引數從右到左依次壓入棧的此時的棧中的值在新棧中就沒有了因此就有了複製引數...