您的位置:首页 > 房产 > 家装 > 口碑好的家装前十强_揭阳网站开发定制_电商具体是做什么的_数据分析师培训

口碑好的家装前十强_揭阳网站开发定制_电商具体是做什么的_数据分析师培训

2025/1/11 18:44:57 来源:https://blog.csdn.net/m0_75253775/article/details/144063545  浏览:    关键词:口碑好的家装前十强_揭阳网站开发定制_电商具体是做什么的_数据分析师培训
口碑好的家装前十强_揭阳网站开发定制_电商具体是做什么的_数据分析师培训

函数分类

库函数

        系统提供的,不能直接访问内核的,如printf,fopen等

系统调用

        系统提供的,可以直接访问内核的,如open,close等

自定义函数

        自己编写的


注意:

        man命令查看帮助手册

        章节1        查命令

        章节2        系统调用

        章节3        库函数

系统编程概述

操作系统的职责

        操作系统用来管理所有的资源,并将不同的设备和不同的程序关联起来
 

什么是linux系统编程

        在有操作系统的环境下编程,并使用操作系统提供的系统调用及各种库,对系统资源进行访问

        学会了C语言再知道一些使用系统调用的方法,就可以进行linux系统编程了

什么是系统调用

系统调用是操作系统提供给用户程序的一组特殊的函数接口

类UNIX系统的软件层次

                        ​​​​​​​        

内核功能的通俗解释

  • 进程管理
    • 进程就好比是工厂里的一条条生产线。内核就是工厂的管理员,它决定什么时候开启一条新的生产线(创建进程),哪条生产线先工作、工作多久(进程调度),什么时候关掉生产线(终止进程)。比如说,你一边听歌一边写文档,这就相当于两条生产线同时开工,内核会安排它们合理地使用 CPU 这个 “动力源”。
  • 内存管理
    • 内存就像是一个大仓库,内核就是仓库管理员。它要把这个仓库划分好,给每个软件(进程)分配好地方来存放自己的东西(数据),而且还要保证不同软件的东西不会混在一起。就像把仓库隔成一个个小房间,每个软件有自己的房间,不会互相干扰。
  • 设备驱动管理
    • 硬件设备就像是不同的工具,内核里的设备驱动就像是这些工具的使用说明书。当你插入一个新的工具(比如 U 盘),内核就会找到对应的说明书(驱动程序),然后学会怎么用这个工具,让你能通过电脑来使用 U 盘里的东西。
  • 文件系统管理
    • 计算机里的文件和文件夹就像是图书馆里的书和书架。内核就是图书馆管理员,它决定了书怎么摆放(文件存储格式)、谁能看哪些书(访问权限),以及书架怎么排列(目录结构)。当你想找一本书(打开一个文件),内核就会帮你找到它。

 用户态和内核态

        CPU指令是可以操作硬件的,要是因为指令操作的不规范,造成的错误是会影响整个计算机操作系统的,就像你在写一个程序,但是因为你对硬件的操作不熟悉导致出现了问题,那么你的影响范围将会是整个计算机系统,操作系统内核,以及其他所有正在运行的程序,都会因为操作失误收到不可挽回的错误

        而对于 硬件的操作 是非常复杂的,参数众多,出问题的几率相当大,必须及其谨
慎的进行操作,这对于个人开发者来说是个艰巨的任务,同时个人开发者在这方面也是
不被信任的。所以 操作系统内核 直接屏蔽了个人开发者对于硬件操作的可能 .
        这方面 系统内核 对 硬件操作 进行了封装处理,对外提供标准函数库,操作更简
单、更安全。比如 我们要打开一个文件, C 标准函数库中对应的是 fopen() ,其内部封
装的是内核中的系统函数 open()
        因为这个需求,硬件设备商直接提供了硬件级别的支持,做法就是对CPU指令设置了权限,不同级别的权限可以使用的CPU指令是有限制的,以Inter CPU为例,Inter 把CPU指令操作的权限划为4级:
        ring 0
        ring 1
        ring 2
        ring 3
        其中ring 0权限最高,可以使用所有CPU指令,ring 3权限最低,仅能使用常规CPU指令,这个级别的权限不能使用访问硬件资源的指令,比如IO读写,网卡访问,申请内存都不行,都没有权限
        
        linux系统内核采用了:ring 0 和ring 3 这两个权限
        ring 0:内核态,完全在操作系统内核中运行,由专门的内核线程在CPU中执行其任务
        ring 3:用户态,在应用程序中运行,由用户线程在CPU中执行其任务

        linux系统中所有对硬件资源的操作都必须在内核态状态下执行,比如IO的读写,网络的操作

 区别

1,用户态的代码必须由用户线程去执行,内核态的代码必须由内核线程去执行


2,用户态,内核态 或者说 用户线程,内核线程 可以使用的资源是不同的,尤其体现在内存资源上,linux内核对每一个进程都会分配4G虚拟内存空间地址

        用户态:        -->只能操作0~3G的内存地址

        内核态:        -->0~4G的内存地址都可以操作,尤其是对3~4G的高位地址必须由内核态去操作,因为所有进程的3~4G的高位地址使用的都是同一块,专门留给系统内核使用的1G物理地址

3,所有对硬件资源,系统内核数据的访问都必须由内核态去执行

如何切换内核态

通过软件中断

软件中断与硬件中断

软件中断

        软件中断是由软件程序触发的中断,如系统调用,软中断,异常等,软件中断不是由硬件设备触发的,而是由软件程序主动发起的,一般用于系统调用,进程切换,异常处理等事务,软件中断需要在程序中进行调用,其响应速度和实时性相对较差,但是具有灵活性和可控性高的特点

        如程序中出现的内存溢出,数据下标越界等


硬件中断

        硬件中断是由硬件设备触发的中断,如时钟中断,串口接收中断,外部中断等,当硬件设备有数据或事件需要处理时,会向CPU发送一个中断请求,CPU在收到中断请求后,会立即暂停当前正在执行的任务,进入中断处理程序中处理中断请求,硬件中断具有实时性强,可靠性高,处理速度快等特点      

 系统调用与库函数的关系

        ​​​​​​​        ​​​​​​​                        

文件描述符

文件描述符是一个非负整数,表示已打开的文件

每一个进程都会创建一张文件描述符表,记录的是当前进程打开的所有文件描述符

每一个进程默认打开三个文件描述符

        0(标准输入设备)

        1(标准输出设备printf)

        2(标准错误输入设备perror)

新打开的文件描述符为最小可用的文件描述符

扩展

ulimit是一个计算机命令,用于shell启动进程所占用的资源,可修改系统资源限制,使用ulimit命令用于临时修改资源限制,如果需要永久修改需要将设置写入配置文件/etc/security/limits.conf


ulimit -a 查看open files 打开的文件最大数


ulimit -n 最大数     设置open files打开文件最大数

文件磁盘权限

        ​​​​​​​        

第一位说的是文件或文件夹

2~4位说明所有者权限

5~7位说明同组用户权限

8~10位说明其他用户权限


r        4

w        2

x        1


只读        4

只写        2

只执行        1

可读可写        6

可读可执行        5

可读可写可执行        7

系统调用之文件操作

open:打开文件

所需头文件

        #include <sys/types>

        #include <sys/stat.h>

        #include <fcntl.h>

函数:

        int open(const char *pathname,int flags);

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

参数:

        pathname:打开的文件地址

        flags:代码操作文件的权限

                必选项

                        O_RDONLY 以只读的方式打开

                        O_WRONLY 以只写方式打开

                        O_RDWR 以可读可写的方式打开

                可选项

                        O_CREAT 文件不存在则创建,使用此选项时需要使用mode说明文件的权限

                        O_EXCL 如果同时指定了O_CREAT,且文件已经存在,则打开,如果文件不存在则新建

        mode:文件在磁盘中的权限

                格式:

                        0ddd

                        d的取值:4(可读),2(可写),1(可执行)

                        第一个d:所有者权限

                        第二个d:同组用户权限

                        第三个d:其他用户权限

                        如果需要可读可写就是6,可读可执行就是5等

                        如:

                        0666:所有者可读可写,同组用户可读可写,其他用户可读可写

                        0765:所有者可读可写可执行,同组用户可读可写,其他用户可读可执行

返回值:

        成功:得到最小可用的文件描述符

        失败:-1

注意:

        操作已有文件使用两参

        新建文件使用三参                   

 close:关闭文件

所需头文件

        #include<unistd.h>

函数

        int close(int fd);

参数

        关闭的文件描述符

返回值

        成功:0

        失败:-1,并设置errno

write:写入

所需头文件

        #include<unistd.h>

函数

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

参数

        fd:写入的文件描述符

        buf:写入的内容首地址

        count:写入的长度,单位字节

返回值

        成功:返回写入的内容的长度,单位字节

        失败:-1

read:读取

所需头文件:

        #include<unistd.h>

函数:

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

参数:

        fd:文件描述符

        buf:内存首地址

        count:读取的字节个数

返回值:

        成功:实际读取到的字节个数

        失败:-1

fcntl函数

作用:针对已经存在的文件描述符设置阻塞状态

语法:

        所需头文件

        #include <unistd.h>

        #include <fcntl.h>

函数:

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

功能:

        改变已打开文件性质,fcntl针对描述符提供控制

参数:

        fd:操作的文件描述符

        cmd:操作模式

        arg:针对cmd的值,fcntl能够接受第三个参数 int arg

返回值:

        成功:返回某个其他值

        失败:-1


fcntl函数有5种功能:

        1)复制一个现有的描述符(cmd=F_DUPFD)

        2)获得/设置文件描述符标记(cmd=F_GEDFD 或 F_SETFD)

        3)获得/设置文件状态标记(cmd=F_GETOWN 或 F_SETFL)

        4)获得/设置异步I/O所有权(CMD=F_GETOWN 或 F_SETOWN)

        5)获得/设置记录锁(cmd=FGETLK,F_SETLK 或F_SETLKW)

stat函数

作用:

        获取文件状态信息

所需头文件:

        #include <sys/types.h>

        #include <sys/stat>

        #incldue <unistd.h>

函数:

        int stat(const char *path,struct stat *buf);

        int lstat(const char *pathname,struct stat *buf);

参数:

        参1:文件地址

        参2:保存文件信息的结构体

返回值:

        0:成功

        -1:失败

注意:

        当文件是一个符号链接时

        lstat返回的是该符号链接本身的信息

        stat返回的是该链接指向的文件的信息

struct stat {
        dev_t st_dev; //文件的设备编号
        ino_t st_ino; //节点
        mode_t st_mode; //文件的类型和存取的权限
        nlink_t st_nlink; //连到该文件的硬连接数目 , 刚建立的文件值为 1
        uid_t st_uid; //用户 ID
        gid_t st_gid; //组 ID
        dev_t st_rdev; //(设备类型 ) 若此文件为设备文件,则为其设备编号
        off_t st_size; //文件字节数 ( 文件大小 )
        blksize_t st_blksize; //块大小 ( 文件系统的 I/O 缓冲区大小 )
        blkcnt_t st_blocks; //块数
        time_t st_atime; //最后一次访问时间
        time_t st_mtime; //最后一次修改时间
        time_t st_ctime; //最后一次改变时间 ( 指属性 )
};

st_mode的值

文件夹操作

opendir

作用:打开目录opendir

所属头文件:

        #include<sys/types.h>

        #include<dirent.h>

函数:

        DIR *opendir(const char *name);

参数:

        name:目录名

返回值:

        成功:返回指向该目录结构体指针(DIR *)

        失败:NULL

DIR:中文名称句柄,其实就是目录的结构体指针

closedir

作用:关闭目录closedir

所需头文件

        #include<sys/types.h>

        #include<dirent.h>

函数:

        int closedir(DIR *dirp);

参数:

        dirp:opendir 返回的指针

返回值:

        成功:0

        失败:-1

readdir

作用:读取目录readdir

所需头文件

        #include <dirent.h>

函数:

        dirp:opendir的返回值

返回值:

        成功:目录结构体指针

        失败:NULL

注意:一次读取一个文件

相关结构体:

        struct dirent

        {
                ino_t d_ino; // 此目录进入点的 inode
                off_t d_off; // 目录文件开头至此目录进入点的位移
                signed short int d_reclen; // d_name 的长度, 不包含 NULL 字符
                unsigned char d_type; // d_type 所指的文件类型
                char d_name[256]; // 文件名
        };
        d_type说明 :
                DT_BLK这是一个块设备。( 块设备如 : 磁盘 )
                DT_CHR这是一个字符设备。( 字符设备如 : 键盘 , 打印机 )
                DT_DIR这是一个目录。
                DT_FIFO这是一个命名管道(FIFO )。
                DT_LNK这是一个符号链接。
                DT_REG这是一个常规文件。
                DT_SOCK这是一个UNIX 域套接字。
                DT_UNKNOWN文件类型未知。

        

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com