日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

linux PCB数组,Linux中的系统IO函数

發布時間:2025/4/5 linux 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 linux PCB数组,Linux中的系统IO函数 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、整體大綱

二、 系統IO函數

1. 一些概念

文件描述符

PCB

C庫函的IO緩沖區

1)?文件描述符

int 類型

一個進程最多可打開多少文件

2)?pcb

進程控制塊

在其中有一個文件描述符表 -- 數組[1024]

C庫IO函數工作流程:

pcb和文件描述符:

2. 虛擬地址空間

虛擬地址空間就是程序啟動起來之后從硬盤上會有一塊虛擬內存分配出來。

cpu 為什么要使用虛擬地址空間與物理地址空間映射?解決了什么樣的問題?

1)方便編譯器和操作系統安排程序的地址分布。

程序可以使用一系列相鄰的虛擬地址來訪問物理內存中不相鄰的大內存緩沖區。通過虛擬地址空間與物理地址空間映射解決不連續的緩沖區的問題。

2)方便進程之間隔離

不同進程使用的虛擬地址彼此隔離。一個進程中的代碼無法更改正在由另一進程使用的物理內存。

3)方便OS使用你那可憐的內存。

程序可以使用一系列虛擬地址來訪問大于可用物理內存的內存緩沖區。當物理內存的供應量變小時,

內存管理器會將物理內存頁(通常大小為 4 KB)保存到磁盤文件。數據或代碼頁會根據需要在物理內存與磁盤之間移動。

虛擬地址空間的布局如下:

0-3G是用戶空間? ? ? ? 3-4G是內核空間

用戶區? ? ? ? ? ? ? ? ? ? ? ? 內核區

代碼段

已經初始化的全局變量

未被初始化的全局變量

堆 -- 從下往上

共享庫

棧 - 從上往下

環境變量

內核區

3. C庫函數與系統函數的關系

FD:文件描述符 FP_POS:文件指針 BUFFER:緩沖區

write對0-3G的用戶空間進行操作 sys_write()對3-4G的內核空間進行操作

4. IO函數介紹

1)open

查看 man 2 open

頭文件:

#include #include#include

函數原型:

int open(const char *pathname, intflags);int open(const char *pathname, int flags, mode_t mode);

參數說明

pathname 文件名

flags

必選項:

O_RDONLY 只讀

O_WRONLY 只寫

O_RDWR 讀寫

可選項:

O_APPEND 追加

O_CREAT 創建文件

O_EXCL和O_CREATE一起使用,如果文件存在則報錯

O_NONBLOCK 非阻塞

Mode 權限位,最終(mode&~umask)

返回值:

成功:返回最小的可用文件描述符

失敗:返回-1,并且設置errno

open函數中的errno:

1 #include

2 #include

3 #include

4 #include

5 #include

6

7 int main(int argc, char *argv[])8 {9 if (argc != 2)10 {11 printf("./a.out filename\n")12 return -1

13 }14 int fd = open(argv[1], O_CREAT|O_TRUNC|O_WRONLY, 0666);15 close(fd);16

17 return 0;18 }

使用open實現一個touch功能

1 #include

2 #include

3 #include

4 #include

5 #include

6 #include

7

8 int main(int argc, char *argv[])9 {10 int num = 3;11 char filename[128] = {0};12 while(1)13 {14 sprintf(filename, "temp_%04d", num++);15 if (open(filename, O_RDONLY|O_CREAT, 0666) < 0)16 {17 perror("open err:");18 break;19 }20 }21 printf("num == %d\n", num);22

23 return 0;24 }

一個進程打開的最大文件數(1024)

2)close

作用:關閉文件描述符

頭文件:

#include

函數原型:

int close(int fd);

參數說明:

fd文件描述符

返回值:

成功:返回0

失敗:返回-1,并且設置errno

3)read讀

頭文件

#include

函數原型

ssize_t read(int fd, void *buf, size_t count);

參數說明

fd 文件描述符

buf緩沖區

count緩沖區大小

返回值

失敗:返回-1,設置errno

成功:返回讀到的字節數

0代表讀到文件末尾

非阻塞的情況下read返回-1,但是此時需要判斷error的值。

4)write寫

頭文件

#include

函數原型

ssize_t write(int fd, const void *buf, size_t count);

參數說明:

fd文件描述符

buf緩沖區

count緩沖區大小

返回值

失敗:返回-1,設置errno

成功:返回寫入的字節數

0代表未寫入

1 #include

2 #include

3 #include

4 #include

5 #include

6

7 int main(int argc, char *argv[])8 {9 if (argc != 2)10 {11 printf("./a.out filename\n")12 return -1

13 }14 int fd = open(argv[1], O_RDONLY);15 char buf[256] = {0};16 int ret = 0;17 while ((ret = read(fd, buf, ziseof(buf))) != 0)18 {19 if (ret == -1)20 {21 perror("read err:");22 return -1;23 }24 else

25 {26 write(STDOUT_FILENO, buf, ret);27 }28 }29

30 close(fd);31

32 return 0;33 }

實現一個cat功能

需求:給一個文件中寫入內容,寫完之后打開該文件再讀取寫入的內容?

1 #include

2 #include

3 #include

4 #include

5 #include

6

7 int main(int argc, char *argv[])8 {9 if (argc != 2)10 {11 printf("./a.out filename\n");12 return -1;13 }14 int fd = open(argv[1], O_RDWR|O_CREAT, 0666);15

16 char data[12] = "hello world";17 write(fd, data, sizeof(data));18

19 char buf[256] = {0};20 int ret = 0;21 while ((ret = read(fd, buf, sizeof(buf))) != 0)22 {23 if (ret == -1)24 {25 perror("read err:");26 return -1;27 }28 else

29 {30 write(STDOUT_FILENO, buf, ret); //STDIN_FILENO, STDERR_FILENO

31 }32 }33

34 close(fd);35

36 return 0;37 }

bug版本

結果:內容寫入到文件中,但是并未按預期輸出到屏幕上。

原因:是由于write完成之后,fd到了文件末尾,因此read時到了文件末尾,無法讀取文件數據

解決方法:寫完之后將文件指針設置到文件開頭,使用請看下文要介紹的lseek函數。

5)lseek寫

頭文件

#include #include

函數原型

off_t lseek(int fd, off_t offset, int whence);

參數說明

fd文件描述符

offset偏移量

whence:

SEEK_SET 文件開始位置

SEEK_CUR 文件當前位置

SEEK_END 文件結尾

返回值

失敗:返回-1,設置errno

成功:返回當前位置到文件開頭的長度

lseek作用

移動文件讀寫位置

計算文件大小

拓展文件

示例:

a.?移動文件讀寫位置

1 #include

2 #include

3 #include

4 #include

5 #include

6

7 int main(int argc, char *argv[])8 {9 if (argc != 2)10 {11 printf("./a.out filename\n");12 return -1;13 }14 int fd = open(argv[1], O_RDWR|O_CREAT, 0666);15

16 char data[12] = "hello world";17 write(fd, data, sizeof(data));18 //文件讀寫位置此時在末尾19 //需要移動讀寫位置

20 lseek(fd, 0, SEEK_SET); //將fd移動到文件頭

21

22 char buf[256] = {0};23 int ret = 0;24 while ((ret = read(fd, buf, sizeof(buf))) != 0)25 {26 if (ret == -1)27 {28 perror("read err:");29 return -1;30 }31 else

32 {33 write(STDOUT_FILENO, buf, ret); //STDIN_FILENO, STDERR_FILENO

34 }35 }36

37 close(fd);38

39 return 0;40 }

修改上例的bug(寫入文件內容并讀取文件內容打印到屏幕)

b.?計算文件大小

1 #include

2 #include

3 #include

4 #include

5 #include

6

7 int main(int argc, char *argv[])8 {9 if (argc != 2)10 {11 printf("./a.out filename\n");12 return -1;13 }14 int fd = open(argv[1], O_RDONLY);15

16 int ret = lseek(fd, 0, SEEK_END); //將fd移動到文件頭

17 printf("file size is %d\n", ret); //注意實際讀到的文件大小為ret-1

18

19 close(fd);20

21 return 0;22 }

計算文件大小(輸出文件字節數)

c.?拓展文件

1 #include

2 #include

3 #include

4 #include

5 #include

6

7 int main(int argc, char *argv[])8 {9 if (argc != 2)10 {11 printf("./a.out filename\n");12 return -1;13 }14 int fd = open(argv[1], O_WRONLY|O_CREAT, 0666);15 //拓展文件

16 int ret = lseek(fd, 1024, SEEK_END); //將fd移動到文件頭17 //需要至少寫一次,否則不能保存

18 write(fd, "a", 1);19 printf("file size is %d\n", ret);20

21 close(fd);22

23 return 0;24 }

拓展文件

阻塞的概念:

read函數在讀設備或者讀管道,或者讀網絡的時候。

輸入輸出設備對應的/dev/tty。

6)fcntl

頭文件

#include #include

函數原型

int fcntl(int fd, int cmd, ... /*arg*/ );

參數說明:

fd文件描述符

cmd 命令

返回值

不同的cmd返回值不同

1 #include

2 #include

3 #include

4 #include

5 #include

6

7 int main(int argc, char *argv[])8 {9 //O_NONBLOCK設置為非阻塞

10 int fd = open("/dev/tty", O_RDWR);11 //fcntl()函數,設置非阻塞

12 int flags =fcntl(fd, F_GETFL);13 flags |=O_NONBLOCK;14 fcntl(fd, F_SETFL, flags);15

16 char buf[256] = {0};17 int ret = 0;18 while(1)19 {20 //如果沒有設置O_NONBLOCK

21 ret = read(fd, buf, sizeof(buf));22 if (ret < 0)23 {24 perror("read err:");25 printf("ret is %d\n", ret);26 }27

28 if(ret)29 {30 printf("buf is %s\n", buf);31 }32 printf("haha\n");33 sleep(1);34 }35 close(fd);36

37 return 0;38 }

使用fcntl函數實現讀非阻塞

《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀

總結

以上是生活随笔為你收集整理的linux PCB数组,Linux中的系统IO函数的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。