linux内核编程学习——草稿
第一章
1.1 文件IO
c标准函数与系统函数的区别 FILE文件类型是一个结构体类型,包括文件描述符(inode)、位置指针(f_pos)、缓冲器(buffer)(8192byte)。
c标准文件函数都是带有缓冲区的,系统函数是不带缓冲区的。对于网络编程是不能有缓冲区的。
c标准函数->应用层API->内核层API->驱动函数->设备
写一个hello到文件中:用c标准函数fopen和fwrite将hello写入文件,这之间首先将hello写入C标准缓冲区然后调用应用层API的write将hello写入内核缓冲区然后依据系统的守护进程中定义的时间或者体积量调用内核层函数sys_write在调用驱动层将hello写入文件。
1.2 PCB(进程控制块)概念
PCB是一个task_struct结构体,里面包含了进程的所有信息。
每个PCB(taskstruct)中都有一个filestruct结构体指针,此指针指向的是文件描述符表,即文件的地址。
1.3 open/close
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
int main(int argc,char *argv[])
{
int fd;
if (argc < 2) {
printf("./app filename\n");
exit(1);
}
fd = open(argv[1],O_CREAT,0644);
printf("fd = %d\n", fd);
close(fd);
return 0;
}
open() 主要用到的属性:
O_CREAT O_RDWR O_RDONLY O_WRONLY O_APPEND
fd=open(argv[1], O_CREAT | O_RDWR | O_EXCL, 0644);
1.4 最大打开文件个数
一个进程默认最大打开文件个数1021个文件。
int main(int argc,char *argv[])
{
char name[1024];
int i = 0;
int fd;
while( 1 ) {
sprintf(name, "file%d", ++i);
fd = open(name, O_CREAT, 0777);
if(-1 == fd) exit(1);
printf("%d\n", i);
}
}
cat /proc/sys/fs/file-max 查看当前电脑能承受的最大打开文件个数
ulimit -n 4096 修改默认设置最大打开文件个数为4096个
ulimit -a 查看当前设置的能打开文件的最大个数
1.5 read/write
#include <unistd.h>
ssize_t read(int fd,void *buf, size_t count);
/*ssize_t 有符号整形类型 size_t 无符号整形类型*/
读成功返回读到的字节个数,读完返回0,读失败返回-1
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#define SIZE 8192
int main(int argc, char *argv[])
{
char buf[SIZE];
int fd_src, fd_dest, len;
if(argc < 3){
printf("./mycp src dest\n");
exit(1);
}
fd_src = open(argv[1], O_RDONLY);
fd_dest = open(argv[2], O_CREAT | O_WRONLY | O_TRUNC, 0644);
while( len = read ( fd_src, buf, sizeof(buf)) >0 )
write (fd_dest, buf, len);
close(fd_src);
close(fd_dest);
}
1.6 阻塞与非阻塞
1.6.1 阻塞
一个进程默认打开3个文件描述符
STDIN_FILENO 0 相当于stdin
STDOUT_FILENO 1 相当于stdout
STDERR_FILENO 3 相当于stderr
#include <sys/types.h>
#include
int main(int argc,char *argv[])
{
char buf[1024];
int len;
len = read(STDIN_FILENO, buf, sizeof(buf));//阻塞
if(len<0){
exit(1);
}
write(STDOUT_FILENO, buf, len);
return 0;
}
读磁盘上常规文件一般不会出现阻塞,不管读多少字节,read一定会有限时间内返回,从终端设备或网络设备上读一般会发生阻塞。
当一个进程处于阻塞时,这个进程会被置于SLEEP状态。在linux下用S+表示SLEEP状态。
1.6.2 非阻塞
终端的概念:tty是linux的终端文件,当开启新的窗口时会将tty指向新开的窗口。
open() creat()返回新的文件描述符,如果失败返回-1,同时将errno置相应的错误值
perro()函数根据errno的错误号,打印相应的信息
errno 全局标量 错误原因标志位
strerror()是perro下层的函数(个人理解)
char *strerror(int errnum)
1.7 lseek
lseek()函数类似于fseek()函数,fseek()函数有两个作用:当前读写位置指针和扩展文件。
int fseek(FILE *stream, long offset, int whence)
off_t lseek(int fd, off_t offset, int whence) //fseek的底层函数
扩展文件时,lseek(fd, 0x1000, SEEK_SET),fd是一个空文件描述符,扩展后不会增加,只有在write后才能增加,增加的内容随意。(扩展一个文件大小,一定要有一次写操作)
lseek()可以扩展一个文件,可以得到一个文件的大小。
1.8 fcntl
fcntl()获取一个文件的访问控制属性(FGETFL)和设置一个文件的访问控制属性(FSETFL)
1.9 ioctl
uart_write
uart_read
uart_ioctl
ioctl获取和设置文件的物理特性
fcntl获取和设置文件的访问特性
应用层write调用系统层syswrite调用驱动层uartwrite
第二章
对于ext2文件系统,每个分区组都有特定的格式:
每个block是4096Bytes,每个block占8个磁盘扇区,每个磁盘扇区是512Bytes,每个block也就是32768bit位。对于每个分区将被分为若干个block,第一个block是一个boot block是产商约定的,第二块是超级block记录了整个分区的情况,之后是GDT块描述表,记录了它之后的一些块(指的是描述性的块,不是数据块)的位置,再之后是块位图(block bit map),记录了那些块还是空闲的,之后是inode bit map,记录的各个文件的起始位置,之后是inode table,记录的对应inode节点文件的文件属性和块指针,之后才是数据块。。。一个文件要想存入系统,需要首先根据GDT找到inode bit map申请一个inode节点数,然后对应inodetable写入描述信息,之后根据block bit map看哪些块是空闲的写入inode table的块指针中,之后写入相应的数据,完成存储。
重点说明(1)inode table中的块指针,默认用一个块记录指针,也就是4096Bytes记录,也就是4096/4=1024个指针,一般来说1024个指针只能存储1024*4096(Bytes)/1024(M)/1024(G)=4G不能满足大文件的存储,因此设计1024个指针的最后三个指针为一级,二级,三级指针,分别指针另外的块,这样就被大大的增加了指针的数量。(2)从第二块开始被分为若干组,每个组的大小由block bit map中字节位数大小决定,block bit map的字节位数由block的大小决定,block的大小可以人为设定。
linux内核编程学习——草稿的更多相关文章
- linux内核数据结构学习总结
目录 . 进程相关数据结构 ) struct task_struct ) struct cred ) struct pid_link ) struct pid ) struct signal_stru ...
- Linux内核编程规范与代码风格
source: https://www.kernel.org/doc/html/latest/process/coding-style.html translated by trav, travmym ...
- Linux 系统编程 学习:00-有关概念
Linux 系统编程 学习:00-有关概念 背景 系统编程其实就是利用系统中被支持的调度API进行开发的一个过程. 从这一讲开始,我们来介绍有关Linux 系统编程的学习. 知识 在进行Linux系统 ...
- Linux 系统编程 学习:01-进程的有关概念 与 创建、回收
Linux 系统编程 学习:01-进程的有关概念 与 创建.回收 背景 上一讲介绍了有关系统编程的概念.这一讲,我们针对 进程 开展学习. 概念 进程的身份证(PID) 每一个进程都有一个唯一的身份证 ...
- Linux 系统编程 学习:02-进程间通信1:Unix IPC(1)管道
Linux 系统编程 学习:02-进程间通信1:Unix IPC(1)管道 背景 上一讲我们介绍了创建子进程的方式.我们都知道,创建子进程是为了与父进程协作(或者是为了执行新的程序,参考 Linux ...
- Linux 系统编程 学习:03-进程间通信1:Unix IPC(2)信号
Linux 系统编程 学习:03-进程间通信1:Unix IPC(2)信号 背景 上一讲我们介绍了Unix IPC中的2种管道. 回顾一下上一讲的介绍,IPC的方式通常有: Unix IPC包括:管道 ...
- Linux 系统编程 学习:04-进程间通信2:System V IPC(1)
Linux 系统编程 学习:04-进程间通信2:System V IPC(1) 背景 上一讲 进程间通信:Unix IPC-信号中,我们介绍了Unix IPC中有关信号的概念,以及如何使用. IPC的 ...
- Linux 系统编程 学习:05-进程间通信2:System V IPC(2)
Linux 系统编程 学习:05-进程间通信2:System V IPC(2) 背景 上一讲 进程间通信:System V IPC(1)中,我们介绍了System IPC中有关消息队列.共享内存的概念 ...
- Linux 系统编程 学习:06-基于socket的网络编程1:有关概念
Linux 系统编程 学习:006-基于socket的网络编程1:有关概念 背景 上一讲 进程间通信:System V IPC(2)中,我们介绍了System IPC中关于信号量的概念,以及如何使用. ...
随机推荐
- DataTable 分页
#region DataTable 分页 /// <summary> /// Datatable 分页 /// </summary> /// <param name=&q ...
- CF GYM 100703I Endeavor for perfection
题意:有n个学习领域,每个领域有m个课程,学习第i个领域的第j个课程可以获得sij个技能点,在每个领域中选择一个课程,要求获得的n个技能点的最大值减最小值最小,输出符合要求的策略. 解法:尺取法.将课 ...
- memcached 学习笔记
memcached是高性能的分布式内存缓存服务器.一般的使用目的是,通过缓存数据库查询结果,减少数据库访问次数,以提高动态应用的速度.提高可扩展性. Memcached基于一个存储键/值对的hashm ...
- hive 配置mysql元数据库
在 hive的配置文件hive-site.xml中 <?xml version="1.0"?> <!-- Licensed to the Apache Softw ...
- httpServer V1
package cn.edu.sss.httpServer; import java.io.BufferedReader; import java.io.IOException; import jav ...
- MVC 部署出现错误未能写入输出文件xxxxxxx.
编译器错误消息: CS0016: 未能写入输出文件“c:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files\ro ...
- office在线预览方案
一.服务器先转换为PDF,再转换为SWF,最后通过网页加载Flash预览 微软方:利用Office2007以上版本的一个PDF插件SaveAsPDFandXPS.exe可以导出PDF文件,然后再利用免 ...
- Read Asia Embedded fell
first and foremost, 很久没写了,心痒了,手贱了,于是乎在这一刻心静时,积攒的思绪开始回放了,惊世Copy-on-write之文随之面世了; 臭毛孩子拉的 屎 特臭,小毛孩子前途黯淡 ...
- nyoj 129 树的判定
并查集+欧拉 树的判定 时间限制:1000 ms | 内存限制:65535 KB 难度:4 描述 A tree is a well-known data structure that is e ...
- 转载Expression Tree揭秘
概述 在.NET Framework 3.5中提供了LINQ 支持后,LINQ就以其强大而优雅的编程方式赢得了开发人员的喜爱,而各种LINQ Provider更是满天飞,如LINQ to NHiber ...