1. 程式人生 > >Linux下程式設計------檔案與IO(三) 檔案共享和fcntl函式

Linux下程式設計------檔案與IO(三) 檔案共享和fcntl函式

檔案共享


一個程序打開了兩個檔案

檔案表條目(file-table-entry):

   1.檔案狀態標誌(file-status-flags): 讀/寫/追加/同步/非阻塞等;

   2.當前檔案偏移量

   3.v節點指標

  1. //驗證
  2. int main(int argc, char *argv[])  
  3. {  
  4.     int fd1 = open("test.txt", O_RDONLY);  
  5.     if (fd1 == -1)  
  6.         err_exit("fd1 open O_RDONLY error");  
  7.     int fd2 = open("test.txt", O_RDWR);  
  8.     if (fd2 == -1)  
  9.         err_exit("fd2 open O_RDWR error");  
  10.     //讀取fd1
  11.     char buf[BUFSIZ];  
  12.     if (read(fd1, buf, 10) == -1)  
  13.         err_exit("read fd1 error");  
  14.     cout << "fd1: " << buf << endl;  
  15.     //讀取fd2
  16.     bzero(buf, 10);  
  17.     if (read(fd2, buf, 10) == -1)  
  18.         err_exit("read fd1 error");  
  19.     cout << "fd2: " << buf << endl;  
  20.     lseek(fd1, 0, SEEK_SET);  
  21.     lseek(fd2, 0, SEEK_SET);  
  22.     write(fd2, "Helloworld", 10);  
  23.     bzero(buf, 10);  
  24.     if (read(fd1, buf, 10) == -1)  
  25.         err_exit("read fd1 error"
    );  
  26.     cout << "after fd2 write: " << buf << endl;  
  27. }  
一個程序多次開啟同一個檔案,檔案指標是互不干擾的,因為他們各自維護自己檔案表(資料結構),但是如果修改了檔案的內容,那麼v結點資訊改變,則都會受到影響。


兩個獨立的程序開啟同一個檔案

複製檔案描述符

 

方法有三種:

1.dup

2.dup2 

其中dup2相當於先close在執行dup。

  1. #include <unistd.h>
  2. int dup(int oldfd);  
  3. int dup2(int oldfd, int newfd);  
  1. //示例
  2. int main(int argc, char *argv[])  
  3. {  
  4.     int fd = open("text.txt", O_WRONLY|O_TRUNC);  
  5.     if (fd == -1)  
  6.         err_exit("open O_WRONLY error");  
  7. //    close(1);   //將標準輸出關閉, 則檔案描述符1將空閒
  8. //    int dupfd = dup(fd);
  9.     int dupfd = dup2(fd, 1);  
  10.     cout << "dupfd = " << dupfd << endl;  
  11. }  
  1. /** 示例: 實現檔案拷貝 
  2. 其中execlp會在後面介紹 
  3. **/
  4. int main(int argc, char *argv[])  
  5. {  
  6.     if (argc < 3)  
  7.         err_quit("usage: ./main file-name1 file-name2");  
  8.     close(STDIN_FILENO);  
  9.     open(argv[1], O_RDONLY);  
  10.     close(STDOUT_FILENO);  
  11.     open(argv[2], O_WRONLY|O_CREAT, 0666);  
  12.     execlp("/bin/cat""cat", NULL);  
  13.     err_exit("execlp error");  
  14. }  
3.fcntl
  1. int fcntl(int fd, F_DUPFD, ... /* arg */ );  
  2. //示例見下

fcntl

  1. #include <unistd.h>
  2. #include <fcntl.h>
  3. int fcntl(int fd, int cmd, ... /* arg */ );  

  操縱檔案描述符, 改變已經開啟的檔案的屬性

fcntl常用操作(cmd常用取值)

F_DUPFD (long)

複製檔案描述符

F_GETFD (void)

F_SETFD (long)

檔案描述符標誌

F_GETFL (void)

F_SETFL (long)

檔案狀態標誌

F_GETLK

F_SETLK,F_SETLKW(阻塞)

檔案鎖

  1. //示例: 複製檔案描述符
  2. int main(int argc, char *argv[])  
  3. {  
  4.     int fd = open("text.txt", O_WRONLY|O_TRUNC);  
  5.     if (fd == -1)  
  6.         err_exit("open O_WRONLY error");  
  7.     close(1);   //將標準輸出關閉, 則檔案描述符1將空閒
  8.     // 當cmd使用F_DUPFD時, 第三個引數代表搜尋的起始位置
  9.     int dupfd = fcntl(fd, F_DUPFD, 1);  // 1代表: 從1開始搜尋一個空閒的檔案描述符
  10.     if (dupfd < 0)  
  11.         err_exit("fcntl F_DUPFD error");  
  12.     cout << "dupfd = " << dupfd << endl;  
  13. }  

檔案狀態標誌

F_GETFL (void)

 Get the file access mode and the file status flags; arg is ignored.

F_SETFL (int)

 Set the file status flags to  the  value  specified  by  arg.   File  access  mode(O_RDONLY,  O_WRONLY,  O_RDWR)  and  file  creation  flags (i.e., O_CREAT, O_EXCL, O_NOCTTY, O_TRUNC) in arg are ignored.  On Linux this command can change only  the O_APPEND, O_ASYNC, O_DIRECT, O_NOATIME, and O_NONBLOCK flags.

設定檔案狀態的時候,注意要先使用F_GETFL獲取,否則原來的狀態會丟失。

  1. //示例: 給檔案描述符0設定成非阻塞模式
  2. int main(int argc, char *argv[])  
  3. {  
  4.     int flags = fcntl(0, F_GETFL, 0);  
  5.     if (flags == -1)  
  6.         err_exit("fcntl get error");  
  7.     flags |= O_NONBLOCK;  
  8.     if (fcntl(0, F_SETFL, flags) == -1)  
  9.         err_exit("fcntl set error");  
  10.     char buf[BUFSIZ];  
  11.     if (read(0, buf, sizeof(buf)) == -1)  
  12.         err_exit("read STDIN_FILENO error");  
  13.     cout << "buffer size = " << strlen(buf) << endl;  
  14. 相關推薦

    Linux程式設計------檔案IO 檔案共享fcntl函式

    檔案共享 一個程序打開了兩個檔案 檔案表條目(file-table-entry):    1.檔案狀態標誌(file-status-flags): 讀/寫/追加/同步/

    linux系統程式設計之基礎必備檔案描述符file descriptorinode的相關知識

           每個程序在Linux核心中都有一個task_struct結構體來維護程序相關的 資訊,稱為程序描述符(Process Descriptor),而在作業系統理論中稱為程序控制塊 (PCB,Process Control Block)。task_struct中有一

    Linux程序的管理排程 -- Linux程序ID號

    Linux 核心使用 task_struct 資料結構來關聯所有與程序有關的資料和結構,Linux 核心所有涉及到程序和程式的所有演算法都是圍繞該資料結構建立的,是核心中最重要的資料結構之一。 該資料結構在核心檔案include/linux/sched.h中定義,在目前最新

    嵌入式Linux C程式設計學習之路——初識GCC

           Gcc(GNU C Compiler)是GNU推出的功能強大、效能優越的多平臺編譯器,是GNU的代表作之一。Gcc可以在多種硬體平臺上編譯出可執行程式,其執行效率與一般的編譯器相比平均效率要高20%~30%。       Gcc最基本的用法是∶gcc [opt

    Linux C程式設計--陣列指標

    1.1陣列的基本概念及其定義    在程式設計中,為了方便處理,把具有相同型別的若干變數按有序的形式組織起來。這些按序排列的同類資料元素的集合稱為陣列。(1)對於同一個陣列,其所有元素的資料型別都是相同

    postgresql從入門到菜鳥基本命令視窗函式

    上一篇我們已經在rhel上建立了資料庫,並且建立的一張成績表。之後通過通過客戶端連線上伺服器端。 這一篇將會寫一些關於資料庫的操作,首先是一些基本的操作的操作如選擇資料庫,查看錶等等。 連線至伺服器端後可以通過以下命令檢視資料庫的基本資訊 \l:檢視所有資料庫。 \c:選擇資料庫

    手推SVM-軟間隔損失函式的推導

    軟間隔的提出 對偶問題及其化簡 引數的求解 引數的調優 1.軟間隔的提出 上一篇文章(手推SVM(二)-核方法 )我們用核方法來解決線性不可分問題,但如果即使對映到高維空間中,仍然有部分點不能完美的區分開呢? 如圖,無論核函式怎麼選取,都不

    linux常用命令檔案作業系統磁碟管理

    1.df -h  檢視磁碟容量 2.du -h  檢視目錄容量 3.du -h -d  檢視目錄深度 du -h -d 0 ~  檢視一級目錄資訊 du -h -d 1 ~檢視二級目錄資訊 4.du

    嵌入式Linux學習筆記檔案程式設計

    一、系統呼叫-建立 int creat(const char *filename,mode_t mode) filename:要建立的檔名(包含路徑,預設為當前路徑) mode:建立模式 常見建立模式: S_IRUSR 可讀

    多線程編程之Linux環境的多線程

    del mutex 我們 後退 post linux環境 ini tro create 前面兩篇文章都講述了Linux環境下的多線程編程基礎知識,也附帶了典型實例。本文主要比較一下Linux環境與Windows環境下的多線程編程區別。   看待技術問題要瞄準其本質,不管是W

    spring cloud實戰思考 微服務之間通過fiegn上傳一組文件

    ets inf str ceo iter protected let pan ins 需求場景:   用戶調用微服務1的接口上傳一組圖片和對應的描述信息。微服務1處理後,再將這組圖片上傳給微服務2進行處理。各個微服務能區分開不同的圖片進行不同處理。   上一篇博客已經討

    NOIP複賽複習檔案讀寫數論模板

    檔案讀入讀出 假設題目名為“add”,那麼資料夾名為“add”,c++程式名為“add.cpp”,讀入檔名為“add.in”,輸出檔名為“add.out”。四個的拼寫均不可有誤,包括大小寫差異。千萬不要除錯後就忘記修改檔案讀入讀出了。  #include<cstdio&

    程式設計演算法第九周 標準模板庫STL2

    STL演算法(一) STL演算法分類 不變序列演算法 變值演算法 刪除演算法 變序演算法 排序演算法 有序區間演算法 數值演算法 大多數過載的演算法都是有兩個版本的 用“==”判斷元素是否相等,或

    程式設計演算法第十週 c++新特性c++高階主題3

    強制型別轉換 :static_cast、interpret_cast、const_cast、dynamic_cast 1、static_cast:static_cast 用來進行比較“自然”和低風險的轉

    北京大學MOOC C++程式設計 程式設計演算法週測驗

    1:返回什麼才好呢 程式填空,使其按要求輸出 #include <iostream> using namespace std; class A { public: int val; A(int // 在此處補充你的程式碼 }; int main()

    北京大學MOOC C++程式設計 程式設計演算法第四周測驗

    1:MyString 補足MyString類,使程式輸出指定結果 #include <iostream> #include <string> #include <cstring> using namespace std; class M

    北京大學MOOC C++程式設計 程式設計演算法第七週測驗

    1:簡單的SumArray 描述 填寫模板 PrintArray,使得程式輸出結果是: TomJackMaryJohn 10 不得編寫SumArray函式 #include <iostream> #include <string> using n

    Linux系統程式設計學習常見問題:VMware虛擬機器Ubuntu18.04突然上不了網的問題解決方案

    問題描述:VMware虛擬機器下Ubuntu18.04突然上不了網的問題:如下圖所示:   更改這裡的三種連線方式都是這樣  2.  分析:IP衝突或者配置出了問題,需重新更新設定。 3.  解決: (1)將模式調整為

    Spring Boot學習筆記檔案上傳訪問靜態檔案

    檔案上傳 寫法和Spring MVC沒啥區別看起來 package org.test.Controll; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.we

    非同步程式設計學習之路-多執行緒之間的協作通訊

    本文是非同步程式設計學習之路(三)-多執行緒之間的協作與通訊,若要關注前文,請點選傳送門: 非同步程式設計學習之路(二)-通過Synchronize實現執行緒安全的多執行緒 通過前文,我們學習到如何實現同步的多執行緒,但是在很多情況下,僅僅同步是不夠的,還需要執行緒與執行緒協作(通訊),生產