01.系统调用

1.操作系统的概念

多线程多任务

操作系统(英语:Operating System,缩写:OS)是一种内置的程序,用来协作计算机的各种硬件,以与用户进行交互。常见有Windows,macOS 和开源的 Linux。

分类:操作系统可以分为桌面操作系统,手机操作系统,服务器操作系统,嵌入式操作系统(RT_THREAD)等。

嵌入式操作系统:基本上都是实时操作系统,体积较小,方便移植,主要是为了实现多任务,提高MCU的工作效率。

问题:

MCU和SOC的区别??

操作系统是人与计算机之间的接口,也是计算机的灵魂

系统--大型应用软件,帮助我们使用人员更好的操作使用底层的资源,作为用户不需要了解底层的工作原理,即可快速的上手使用产品

为什么选择Linux操作系统??

目前我们学习系统编程最好的方式就是通过linux操作系统,主要是因为开源,可裁剪

2.系统调用

系统调用主要是侧重于操作系统内部的工作实现机制,我们需要学习的都是基于linux操作系统内部的函数调用实现。

系统调用以及后续的系统编程的学习,都是去学习linux操作系统的工作原理

linux操作系统中的分层:

kernel--linux的内核,最核心的部分

Ubuntu--操作系统,包含kernel 系统调用(system calls)shell app

centos--操作系统,适合用于服务器端的开发

redhat--红帽系统

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

系统调用按照功能逻辑大致可分为:

进程控制、进程间通信、线程的使用、文件系统控制、系统控制、内存管理、网络管理、 socket 控制、用户管理。(每一个不同的颜色都表示一个完整的知识体系)

系统调用的返回值:

通常,用一个负的返回值来表明错误,返回一个 0 值表明成功。错误信息存放在全局

变量 errno 中,用户可用 perror 函数打印出错信息。

可移植系统接口(POSIX):

POSIX线程

(英语:POSIX Threads,常被缩写为Pthreads)是POSIX的线程标准,定义了创建和操纵线程的一套API。

3.系统调用 I/O 函数

重点学习的函数:open、 close、 write 、 read、 ioctl

系统调用中操作 I/O 的函数,都是针对文件描述符的

通过文件描述符可以直接对相应的文件进行操作。

文件描述符

在整个工程中是唯一的,用于标识不同的文件

内核(kernel)利用文件描述符(file descriptor)来访问文件。文件描述符是非负整数。打开现存文件或新建文件时,内核会返回一个文件描述符。读写文件也需要使用文件描述符来指定待读写的文件。

POSIX 定义了 STDIN_FILENO、STDOUT_FILENO 和 STDERR_FILENO 来代替 0、1、2。这三个符号常量的定义位于头文件 unistd.h。

STDIN_FILENO--标准输入 0 scanf

STDOUT_FILENO --标准输出 1 printf

STDERR_FILENO --标准错误 2 error

目前0--2的文件描述符已经被占用了,我们自己定义的文件,内核返回的描述符都是从3开始

IO相关的函数定义

#include <sys/types.h>
#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: open 函数的行为标志。
mode:文件权限(可读、可写、可执行)的设置。
返回值:
成功返回打开的文件描述符。
失败返回-1,可以利用 perror 去查看原因。 

在我们之前学习C语言的时候会使用到文件操作中的fopen函数

FILE *fopen(const char *filename, const char *mode)

fopen函数和open函数之间的联系???

我们是在应用层中调用了fopen函数,最终起作用的是在系统调用中的open函数,通过open函数连接到内核,进一步操作底层的硬件资源部分

close函数:

关闭一个文件
#include <unistd.h>
int close(int fd);
参数:
fd 是调用 open 打开文件返回的文件描述符。
返回值:
成功返回 0。
失败返回-1,可以利用 perror 去查看原因。

write函数

把指定数目的数据写到文件
#include <unistd.h>
ssize_t write(int fd, const void *addr,size_t count);
参数:
fd:文件描述符。
addr:数据首地址。
count:写入数据的字节个数。
返回值:
成功返回实际写入数据的字节个数。
失败返回-1,可以利用 perror 去查看原因。

read函数

把指定数目的数据读到内存
#include <unistd.h>
ssize_t read(int fd, void *addr, size_t count);
参数:
fd:文件描述符。
addr:内存首地址。
count:读取的字节个数。
返回值:
成功返回实际读取到的字节个数。
失败返回-1,可以利用 perror 去查看原因。

remove函数:

删除文件
#include <stdio.h>
int remove(const char *pathname);
参数:
pathname :文件的路名+文件名。
返回值:
成功返回 0。
失败返回-1,可以利用 perror 去查看原因。

4.系统调用与库函数

库函数访问文件的时候根据需要,设置不同类型的缓冲区,从而减少了直接调用 IO系统调用的次数,提高了访问效率。

CP命令的实现:

cp [options] source dest 或 cp [选项] 源文件 目标文件

#include <stdio.h>
#include <sys/types.h>  //open
#include <sys/stat.h>  //open
#include <fcntl.h>     //open 
#include <unistd.h> //read  write  close
#include <errno.h>  //perror


//主函数传参
//argc--代表传入的参数个数
//argv--传入的参数  ./a.out  往代码中传入了一个参数  a.out
//./a.out 5 3
//argv[1]---源
//argv[2]---目的
int main(int argc, char *argv[])
{
    int fd_read=0;
    int fd_write=0;
    char buf[256]={0};
    int ret=0;//返回值
    //cp指令---将一个文件中的内容复制到另外一个文件中
    //int open(const char *pathname, int flags);
    fd_read=open(argv[1],O_RDONLY);
    if(fd_read<0)
    {
        //perror("fd_read:");   //标准出错 --当你的代码出错的时候,系统会将错误信息返回  
        write(2, "fd_read:", 9);
    }
    printf("fd_read=%d\n",fd_read);

    //复制的位置
    //int open(const char *pathname, int flags, mode_t mode);
     fd_write=open(argv[2],O_WRONLY|O_CREAT|O_TRUNC,0777);
     if(fd_write<0)
    {
        perror("fd_write:");   //标准出错 --当你的代码出错的时候,系统会将错误信息返回    
    }
    printf("fd_write=%d\n",fd_write);

    ret=read(fd_read,buf,256);
    if(ret==-1)
    {
        perror("read:");        
    }
    printf("读取到的数据个数为:%d\n",ret);
    
    ret=write(fd_write,buf,ret);
    ret=0;
    if(ret==-1)
    {
        perror("write:");        
    }

    close(fd_read);
    close(fd_write);

    return 0;
}

  • 19
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值