博客專欄

EEPW首頁 > 博客 > 嵌入式Linux:文件共享

嵌入式Linux:文件共享

發(fā)布人:美男子玩編程 時(shí)間:2024-03-22 來源:工程師 發(fā)布文章

在Linux中,文件共享是指多個(gè)進(jìn)程可以同時(shí)訪問和操作同一個(gè)文件。

文件共享在多進(jìn)程或多線程編程環(huán)境中具有重要意義,特別是在以下方面:

  1. 多線程操作大文件: 文件共享可用于實(shí)現(xiàn)多個(gè)線程同時(shí)操作同一個(gè)大文件的場景。通過創(chuàng)建多個(gè)不同的文件描述符,各線程可以并行地讀取或?qū)懭胛募瑥亩鴾p少文件讀寫時(shí)間,提升整體效率。

  2. 提高并發(fā)性: 文件共享提供了一種機(jī)制,使得多個(gè)進(jìn)程或線程能夠并發(fā)地訪問同一個(gè)文件。這對于需要頻繁訪問文件的應(yīng)用程序而言,能夠充分利用系統(tǒng)資源,提高并發(fā)性和響應(yīng)速度。

  3. 文件描述符復(fù)制: 通過多次調(diào)用open函數(shù)或使用dup()、dup2()函數(shù),可以制造出多個(gè)不同的文件描述符,這些描述符指向同一個(gè)文件。這為多個(gè)并發(fā)操作提供了獨(dú)立的文件訪問通道,確保彼此之間不會干擾。

  4. 協(xié)同操作: 文件共享還涉及文件鎖定等機(jī)制,確保在并發(fā)訪問時(shí)對文件的操作是協(xié)同進(jìn)行的。這有助于避免數(shù)據(jù)不一致性和沖突,提高程序的穩(wěn)定性。

下面分享常見的三種文件共享方式。

1、同一個(gè)進(jìn)程中多次調(diào)用 open 函數(shù)打開同一個(gè)文件

在同一個(gè)進(jìn)程中多次調(diào)用 open 函數(shù)打開同一個(gè)文件會得到多個(gè)不同的文件描述符(File Descriptor,簡稱FD)。每次調(diào)用 open 都會返回一個(gè)新的文件描述符,這些描述符可以獨(dú)立地用于對文件的讀取、寫入等操作。

各數(shù)據(jù)結(jié)構(gòu)之間的關(guān)系如下圖所示:


圖片

下面是一個(gè)簡單的例子,演示了在同一個(gè)進(jìn)程中多次調(diào)用 open 打開同一個(gè)文件:

#include#include#include
int main(void) {    // 打開同一個(gè)文件,獲取文件描述符    int fd1 = open("example.txt", O_RDONLY);    int fd2 = open("example.txt", O_RDONLY);
    if (fd1 == -1 || fd2 == -1) {        perror("Error opening file");        return 1;    }
    // 讀取文件內(nèi)容    char buffer1[100];    char buffer2[100];
    ssize_t bytesRead1 = read(fd1, buffer1, sizeof(buffer1));    ssize_t bytesRead2 = read(fd2, buffer2, sizeof(buffer2));
    // 輸出讀取的內(nèi)容    printf("Content read from fd1: %.*sn", (int)bytesRead1, buffer1);    printf("Content read from fd2: %.*sn", (int)bytesRead2, buffer2);
    // 關(guān)閉文件描述符    close(fd1);    close(fd2);
    return 0;}


在這個(gè)例子中,程序打開同一個(gè)文件 "example.txt" 兩次,分別獲得了兩個(gè)文件描述符 fd1 和 fd2。這兩個(gè)文件描述符可以獨(dú)立地進(jìn)行文件讀取操作。需要注意的是,這種情況下讀取的文件內(nèi)容是一樣的,因?yàn)樗鼈冎赶蛲粋€(gè)文件的同一位置。

2、不同進(jìn)程中分別使用 open 函數(shù)打開同一個(gè)文件

在Linux系統(tǒng)中,不同進(jìn)程可以使用open函數(shù)打開同一個(gè)文件。當(dāng)多個(gè)進(jìn)程打開同一個(gè)文件時(shí),每個(gè)進(jìn)程會得到一個(gè)文件描述符(file descriptor),這個(gè)文件描述符是一個(gè)唯一的整數(shù),用于標(biāo)識該文件在該進(jìn)程中的打開實(shí)例。

各數(shù)據(jù)結(jié)構(gòu)之間的關(guān)系如下圖所示:

圖片


以下是一個(gè)簡單的例子,演示了兩個(gè)不同的進(jìn)程分別使用open函數(shù)打開同一個(gè)文件:

#include#include#include#include
int main() {    // 文件路徑    const char *file_path = "example.txt";
    // 在第一個(gè)進(jìn)程中打開文件    int fd1 = open(file_path, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);    if (fd1 == -1) {        perror("Error opening file in process 1");        exit(EXIT_FAILURE);    }
    // 寫入內(nèi)容到文件    const char *content1 = "Hello from process 1n";    write(fd1, content1, strlen(content1));
    // 關(guān)閉文件描述符    close(fd1);
    // 在第二個(gè)進(jìn)程中打開文件    int fd2 = open(file_path, O_WRONLY | O_APPEND);    if (fd2 == -1) {        perror("Error opening file in process 2");        exit(EXIT_FAILURE);    }
    // 寫入內(nèi)容到文件    const char *content2 = "Hello from process 2n";    write(fd2, content2, strlen(content2));
    // 關(guān)閉文件描述符    close(fd2);
    return 0;}

在這個(gè)例子中,兩個(gè)進(jìn)程分別使用open函數(shù)打開同一個(gè)文件 example.txt。第一個(gè)進(jìn)程以寫入模式打開文件,寫入一些內(nèi)容,然后關(guān)閉文件。第二個(gè)進(jìn)程以追加模式打開文件,寫入一些內(nèi)容,然后關(guān)閉文件。由于文件描述符是每個(gè)進(jìn)程私有的,它們可以獨(dú)立地訪問和操作同一個(gè)文件,不會相互干擾。

3、同一個(gè)進(jìn)程中通過 dup(dup2)函數(shù)對文件描述符進(jìn)行復(fù)制

在同一個(gè)進(jìn)程中,可以使用dup函數(shù)或dup2函數(shù)來復(fù)制文件描述符。這樣,進(jìn)程內(nèi)的兩個(gè)文件描述符將指向同一個(gè)打開的文件,允許對同一文件進(jìn)行獨(dú)立的讀寫操作。

各數(shù)據(jù)結(jié)構(gòu)之間的關(guān)系如下圖所示:

下面是一個(gè)簡單的例子:

#include#include#include#include
int main() {    // 文件路徑    const char *file_path = "example.txt";
    // 打開文件    int fd1 = open(file_path, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);    if (fd1 == -1) {        perror("Error opening file");        exit(EXIT_FAILURE);    }
    // 寫入內(nèi)容到文件    const char *content = "Hello from processn";    write(fd1, content, strlen(content));
    // 復(fù)制文件描述符    int fd2 = dup(fd1);    if (fd2 == -1) {        perror("Error duplicating file descriptor");        close(fd1);        exit(EXIT_FAILURE);    }
    // 使用原始文件描述符寫入內(nèi)容    const char *content1 = "Original file descriptorn";    write(fd1, content1, strlen(content1));
    // 使用復(fù)制的文件描述符寫入內(nèi)容    const char *content2 = "Duplicated file descriptorn";    write(fd2, content2, strlen(content2));
    // 關(guān)閉文件描述符    close(fd1);    close(fd2);
    return 0;}

在這個(gè)例子中,程序先打開一個(gè)文件,然后使用dup函數(shù)復(fù)制文件描述符。這樣,fd1和fd2都指向同一個(gè)文件。接著,程序使用原始文件描述符 fd1 寫入一些內(nèi)容,再使用復(fù)制的文件描述符 fd2 寫入另一些內(nèi)容。由于它們指向同一個(gè)文件,兩次寫入的內(nèi)容都會出現(xiàn)在文件中。

需要注意的是,dup函數(shù)會返回一個(gè)新的文件描述符,該描述符是當(dāng)前可用文件描述符中的最小數(shù)值。而dup2函數(shù)則允許指定新的文件描述符的值,如果指定的文件描述符已經(jīng)被占用,dup2會先關(guān)閉該描述符,然后將其重定向到指定的文件。

*博客內(nèi)容為網(wǎng)友個(gè)人發(fā)布,僅代表博主個(gè)人觀點(diǎn),如有侵權(quán)請聯(lián)系工作人員刪除。



關(guān)鍵詞: 嵌入式 Linux 文件共享

相關(guān)推薦

技術(shù)專區(qū)

關(guān)閉