【系统调用】常用系统调用函数(一)

系统调用概念

操作系统的职责

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

什么是Linux系统编程

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

系统编程主要就是为了让用户能够更好和更方便的操作硬件设备,并且对硬件设备也起到保护作用。我们所写的程序,本质就是对硬件设备的操作,所以操作系统提供接口可以对硬件进行操作。

系统调用概述:
【系统调用】常用系统调用函数(一)_第1张图片
本质都是要对硬件设备进行操作,但是Linux操作系统在硬件之上设置了内核,也就是只有内核才可以直接操作硬件设备,如果想操作内核,需要调用内核的系统调用,如果要操作内核中的系统调用,有三种方式:

第一种:shell,用户通过shell命令,由shell解释器操作内核的系统调用。
第二种:库函数,用户通过应用层库函数的接口,比如fread对内核的系统调用进行操作。
第三种:应用层系统调用,它可以直接对内核的系统调用进行操作。
系统调用时操作系统提供给用户程序的一组“特殊”的函数接口。

Linux的不同版本提供了两三百个系统调用。

用户程序可以通过这组接口获得操作系统(内核)提供的服务。
【系统调用】常用系统调用函数(一)_第2张图片
系统调用按照功能逻辑大致可分为:

    进程控制、进程间通信、文件系统控制、系统控制、内存管理、网络管理、socket控制、用户管理。

系统调用的返回值:

    通常,用一个非负的返回值来表明错误,返回一个0值表明成功。

    错误信息存放在全局变量errno中,用户可用perror函数打印出错信息。

系统调用遵循的规范:

    在Linux中,应用程序编程接口(API)遵循POSIX标准。

系统调用I/O函数

文件描述符:

    文件描述符是非负整数。打开现存文件或新建文件时,系统(内核)会返回一个文件描述符。文件描述符用来指定已打凯的文件。

    在系统调用(文件IO)中,文件描述符对文件起到标识作用,如果要操作文件,就是对文件描述符的操作。

当一个程序运行或一个进程开启时,系统会自动创建三个文件描述符。

#define STDIN_FILENO 0 //标准输入的文件描述符
#define STDOUT_FILENO 1 //标准输出的文件描述符
#define STDERR_FILENO 2 //标准错误的文件描述符
如果自己打开文件,会返回文件描述符,而文件描述符一般按照从小到大依次创建的顺序。

1. 常用系统调用函数

1.1 open函数

#include

#include

#include

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

        mode:这个参数,只有在文件不存在时有效,指新建文件时指定文件的权限。

返回值:

        成功:文件描述符

        失败:-1
        

flags详细说明

必选项:
【系统调用】常用系统调用函数(一)_第3张图片
可选项:

【系统调用】常用系统调用函数(一)_第4张图片
mode补充说明:

  1. 文件最终权限:mode & ~umask

  2. shell进程的umask掩码可以用umask命令查看

umask:查看掩码(补码)

umask mode:设置掩码,mode为八进制数

umask -S:查看各组用户的默认操作权限

文件I/O和标准I/O权限对比:
【系统调用】常用系统调用函数(一)_第5张图片

代码示例:

#include 
#include 
#include 
 
int main() {
    int fd = open("example.txt", O_RDONLY);
    if (fd == -1) {
        perror("Failed to open the file");
        exit(1);
    }
 
    // 在这里可以继续处理打开的文件
 
    close(fd); // 关闭文件
 
    return 0;
}

1.2 perror、error函数

perror函数:

#include 

void perror(const char *s);

#include 

功能:

        perror函数根据当前的错误代码,将与该错误代码对应的错误消息打印到标准错误流(stderr)中。

参数:

   s是一个字符串,可用于自定义错误消息前缀。

返回值:

        无

error函数:

#include 

void error(int status, int errnum, const char *format, ...);

功能:

        error函数将错误消息打印到标准错误流,并以给定的格式输出。它与perror函数相似,但提供了更多的灵活性,可以根据需要自定义错误消息的格式。

参数:

         status:表示错误的严重程度,通常为非零值表示致命错误。

   errnum:表示具体的错误代码,可以使用errno变量作为参数传递。

   format:一个格式化字符串,类似于printf函数的格式。

   ...:可选的附加参数,用于填充格式化字符串中的占位符。

返回值:无

代码示例:

#include 
#include 
#include 
 
int main() {
    FILE* file = fopen("nonexistent.txt", "r");
    if (file == NULL) {
        perror("Failed to open the file");
        exit(1);
    }
 
    // 在这里可以继续处理打开的文件
 
    fclose(file); // 关闭文件
 
    return 0;
}

1.3 close函数

#include int close(int fd);

功能:

        关闭已打开的文件

参数:

        fd : 文件描述符,open()的返回值

返回值:

        成功:0

        失败: -1, 并设置errno

代码示例:

#include 
#include 
#include 
#include 
 
int main() {
    int fd = open("example.txt", O_RDONLY);
    if (fd == -1) {
        perror("Failed to open the file");
        exit(1);
    }
 
    // 在这里可以继续处理打开的文件
 
    if (close(fd) == -1) {
        perror("Failed to close the file");
        exit(1);
    }
 
    return 0;
}

1.4 write函数

#include

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

功能:

        把指定数目的数据写到文件(fd)。

参数:

        fd:文件描述符

        buf:数据首地址

        count:写入数据的长度(字节)

返回值:

        成功:实际写入数据的字节个数

        失败:-1

代码示例:

#include 
#include 
#include 
#include 
 
int main() {
    int fd = open("example.txt", O_WRONLY | O_CREAT, 0644);
    if (fd == -1) {
        perror("Failed to open the file");
        exit(1);
    }
 
    const char* data = "Hello, World!";
    ssize_t bytes_written = write(fd, data, strlen(data));
    if (bytes_written == -1) {
        perror("Failed to write to the file");
        exit(1);
    }
 
    // 在这里可以继续处理打开的文件
 
    if (close(fd) == -1) {
        perror("Failed to close the file");
        exit(1);
    }
 
    return 0;
}

你可能感兴趣的:(性能测试小白,服务器,linux)