1. 程式人生 > >【轉】Linux系統編程---dup和dup2詳解

【轉】Linux系統編程---dup和dup2詳解

系統 強調 操作 attach bsp ads 正常的 註意 tdi

正常的文件描述符:

在linux下,通過open打開以文件後,會返回一個文件描述符,文件描述符會指向一個文件表,文件表中的節點指針會指向節點表。看下圖:

技術分享

打開文件的內核數據結構

dup和dup2兩個函數都可以用來復制打開的文件描述符,復制成功後和復制源共享同一個文件表。看下圖:

技術分享

執行dup後的內核數據結構

(1)dup函數

fd1=dup(fd);

fd1和fd共享一個文件表(對fd進行什麽操作,fd1也會有相應的操作,fd和fd1是同步的)。

具體解釋:

#inclue<stdio.h>

#include<sys/types.h>

#include<unistd.h>

#include<fcntl.h>

#include<stdlib.h>

int main()

{

char buf[6]={0};

char buf1[6]={0};

int fd = open("file",O_RDWR|O_CREAT,0644);

if(fd < 0)

printf("open error");

printf("fd:%d\n",fd);

//輸出fd=3;

write(fd,"hello,world",12);

lseek(fd,0,SEEK_SET); //將文件偏移量置為0,就是從第一個字符開始讀(h開始)

read(fd,buf,5);

printf("fd:%s",buf);//輸出hello

int fd1 = dup(fd);

read(fd1,buf1,5); //之前做的是對fd的讀寫操作,並沒有對fd1做任何操作。但在這對fd1進行了讀,如果輸出數據。說明fd和fd1是同步的(fd做了什麽相當於fd1也做了什麽)

printf("fd1:%s\n",buf1); //輸出,worl

//既然輸出的是fd中的內容,說明fd和fd1共用一個文件表,讀到的是,worl,而不是hello(我們在上面將偏移量從第一個字符開始,輸出hello之後,fd的偏移量距離開始有5個字符當我們再次讀fd的時候,它是從第6個字符開始讀的,很明顯,第6個是逗號,往後讀5個,就是,worl),說明偏移量是一致的。(其實不用寫偏移量,因為共用文件表就意味著文件偏移量也共用)

printf("fd1:%d\n",fd1);//輸出fd1 = 4

//fd=3不等於fd1說明不共用同一個文件描述符。這也是dup和dup2的區別。

close(fd);

close(fd1);

return 0;

}

(2)dup2函數

fd2 = dup2(fd,fd1);

fd2用的fd1(第二個參數)的描述符,用的fd(第一個參數)的文件(和fd共享一個文件表,當然也共享文件偏移量)

強調第幾個參數是因為如果你寫成fd2=dup2(fd1,fd);那麽fd2 =fd,和fd1共享同一個文件表。

#inclue<stdio.h>

#include<sys/types.h>

#include<unistd.h>

#include<fcntl.h>

#include<stdlib.h>

int main()

{

int fd = open("file",O_RDWR|O_CREAT,0644);

if(fd < 0)

printf("open error");

printf("fd:%d\n",fd);

//輸出fd=3;

int fd1 =open("text",,O_RDWR|O_CREAT,0644);

if(fd1 < 0)

printf("open error");

printf("fd1:%d\n",fd1);

//輸出fd1=4;

int fd2 = dup2(fd,fd1);

printf("fd2:%d\n",fd2);

//輸出fd2=4;

//fd1 =fd2=4;說明fd2使用了fd1的文件描述符。

char buf[12]="hello,world";

write(fd,buf,12); //我們對fd進行了寫,並沒有對fd2進行寫

read(fd2,buf,12);//但是我們對fd2讀的時候,如果沒有寫,怎麽可能讀出來呢

printf("fd2:%s\n",buf);//事實是讀出來了

//輸出fd2:hello,world //說明fd和fd2共用一個文件表。

lseek(fd,5,SEEK_SET);//距離開始偏移5位,說明下次讀的時候是從第6個開始,註意我們是對fd進行偏移,沒有對fd2偏移

read(fd2,buf,5); //但是如果讀fd2結果是從第6個字符開始的

buf[5]=0; //如果不寫這句,輸出的buf是按照12個字符輸出的。因為定義buf的時候數組中可以放12個字符。

printf("fd2:%s\n",buf);//輸出fd2:,worl //說明fd2和fd共享文件偏移量。

close(fd);

close(fd2);

return 0;

}

dup和dup2的區別

dup:fd1= dup(fd);目標描述符使用了fd的文件表

dup2:fd2 = dup2(fd1,fd)目標描述符使用了fd1的描述符,使用了fd的文件表

【轉】Linux系統編程---dup和dup2詳解