Linux驱动如何向应用层提供sysfs操作接口

在 Linux 中,用户态操作驱动设备主要有以下 5 种方式,每种方式适用于不同的场景,各有其特点和用途:

  1. 字符设备(Char Device)接口

这是最常用的设备交互方式,适用于流式数据传输复杂命令交互的设备(如串口、LED、传感器、显卡等)。

核心特点:

  • 通过 /dev 目录下的设备节点(如 /dev/ttyS0/dev/led0)操作;
  • 驱动需实现 file_operations 结构体(open/read/write/ioctl 等);
  • 支持阻塞 / 非阻塞读写、ioctl 命令控制、mmap 内存映射等复杂操作。

示例(用户态代码):

复制代码
// 打开设备
int fd = open("/dev/led0", O_RDWR);
if (fd < 0) { /* 错误处理 */ }

// 写入数据(如控制 LED 亮度)
write(fd, "255", 3);

// 发送命令(如通过 ioctl 设置模式)
ioctl(fd, LED_SET_MODE, MODE_BLINK);

// 关闭设备
close(fd);

适用场景:

需要复杂交互(如命令控制、批量数据传输、异步操作)的设备。

  1. sysfs 接口

基于虚拟文件系统的属性暴露机制 ,适用于简单的属性读写(如设备状态查询、参数配置)。

核心特点:

  • 通过 /sys 目录下的属性文件(如 /sys/class/leds/led0/brightness)操作;
  • 驱动只需定义 show/store 回调函数(无需完整 file_operations);
  • 接口标准化,操作简单(通过 cat/echo 即可交互)。

示例(用户态操作):

复制代码
# 读取亮度
cat /sys/class/leds/led0/brightness

# 设置亮度
echo 255 > /sys/class/leds/led0/brightness

适用场景:

简单的属性配置(如开关、亮度、模式切换),无需复杂命令交互的设备。

  1. procfs 接口

基于 /proc 虚拟文件系统,主要用于内核 / 驱动的状态信息查询(如进程状态、内存使用、驱动调试信息)。

核心特点:

  • 通过 /proc 目录下的文件(如 /proc/cpuinfo/proc/driver/mydriver)操作;
  • 驱动需注册 proc_ops 结构体(类似 file_operations);
  • 更偏向 "信息展示",而非设备控制(现代驱动中逐渐被 sysfs 替代)。

示例(用户态操作):

复制代码
# 查看驱动调试信息
cat /proc/driver/mydriver/debug_info

适用场景:

内核 / 驱动的调试信息输出、系统状态查询(如 /proc/net 网络信息)。

  1. 设备文件系统(devfs)

早期 Linux 用于管理设备节点的文件系统,现已被 udev + devtmpfs 替代,但概念上仍需了解。

核心特点:

  • 自动创建 /dev 节点,无需手动 mknod
  • 现代系统中,udev 会根据设备的 subsystemdevtype 等属性动态生成 /dev 节点,并支持规则自定义(如 /etc/udev/rules.d/)。

示例(udev 规则自定义节点名称):

复制代码
# /etc/udev/rules.d/70-led.rules
SUBSYSTEM=="leds", ATTR{name}=="user-led", SYMLINK+="myled"
# 生成 /dev/myled 符号链接,指向实际 LED 设备节点

适用场景:

设备节点的动态管理和命名规则自定义。

5. Netlink 套接字

基于内核与用户态的异步通信机制 ,适用于事件通知高频数据交互(如热插拔事件、网络配置、实时监控)。

核心特点:

  • 类似 socket 接口,支持双向通信和多播;
  • 驱动需注册 netlink_kernel_cfg 结构体,用户态通过 socket API 操作;
  • 效率高于 ioctl,适合传递结构化数据和异步事件。

示例(用户态代码框架):

复制代码
// 创建 netlink 套接字
int sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_MYDRIVER);
// 绑定地址、发送/接收数据...

适用场景:

设备事件通知(如热插拔、状态变化)、内核与用户态的高频数据交换。

总结:选择原则

交互需求 推荐方式 典型设备 / 场景
复杂命令 / 流式数据 字符设备(/dev 串口、显卡、传感器数据采集
简单属性读写 sysfs(/sys LED 亮度、温度传感器数值
调试信息 / 系统状态 procfs(/proc 内核版本、驱动调试日志
设备节点动态管理 udev + devtmpfs 自动生成 / 命名 /dev 节点
异步事件 / 高频通信 Netlink 套接字 热插拔事件、实时监控数据

实际开发中,常结合多种方式(如字符设备 + sysfs:/dev 用于数据传输,/sys 用于参数配置)。

本文我们主要讲解sysfs接口。。。。。。。。。。。。。。。

主要目录文件

Linux 内核中 sysfs 的实现涉及多个核心目录和文件,这些文件分布在内核源码的不同路径下,共同构成了 sysfs 虚拟文件系统的框架、属性管理和与其他子系统的交互逻辑。以下是核心的实现目录和文件及其作用:

一、sysfs 核心实现目录

sysfs 的核心代码集中在 fs/sysfs/ 目录下,该目录包含了 sysfs 文件系统的底层实现(如 inode 管理、文件操作、目录结构维护等)。

二、核心文件及功能说明

  1. fs/sysfs/file.c
  • 作用 :实现 sysfs 中文件的核心操作逻辑,是 sysfs 与 VFS(虚拟文件系统)对接的关键。
  • 核心内容
    • 定义 sysfsfile_operations 结构体(sysfs_file_operations),包含 open/read/write/llseek 等通用文件操作;
    • 实现用户空间与内核空间的数据交互(如 sysfs_read/sysfs_write 函数,负责将用户读写转发给属性的 show/store 回调);
    • 管理文件的打开 / 关闭状态,处理并发访问。
  1. fs/sysfs/dir.c
  • 作用 :管理 sysfs 的目录结构,负责目录的创建、删除和层级关系维护。
  • 核心内容
    • 定义 sysfs_dirent 结构体(sysfs 中目录和文件的统一表示,包含名称、类型、父节点指针等);
    • 实现目录创建(sysfs_create_dir)、删除(sysfs_remove_dir)、重命名等操作;
    • 维护 sysfs 的目录树结构,确保节点间的层级关系正确。
  1. fs/sysfs/sysfs.h
  • 作用sysfs 内部的头文件,定义核心数据结构和内部函数声明。
  • 核心内容
    • 声明 struct sysfs_direntstruct sysfs_ops 等核心结构体;
    • 定义 sysfs 内部使用的宏和辅助函数(如 sysfs_get/sysfs_put 用于引用计数管理)。
  1. fs/sysfs/attr.c
  • 作用 :处理 sysfs 属性(attribute)的注册与管理,是驱动与 sysfs 交互的桥梁。
  • 核心内容
    • 实现属性文件的创建(sysfs_create_file)、删除(sysfs_remove_file);
    • 处理属性组(attribute group)的批量注册(sysfs_create_group);
    • 关联属性的 show/store 回调函数与 sysfs 的文件操作。
  1. fs/sysfs/mount.c
  • 作用 :负责 sysfs 文件系统的挂载初始化,是 sysfs 作为虚拟文件系统的入口。
  • 核心内容
    • 定义 sysfsfile_system_type 结构体(sysfs_fs_type),向 VFS 注册 sysfs
    • 实现 sysfs 的挂载函数(sysfs_mount),初始化根目录和超级块(super block)。

三、与其他子系统的交互文件

sysfs 并非独立存在,而是与内核其他子系统(如设备模型、总线、驱动)深度集成,这些子系统通过特定文件定义自己的 sysfs 属性:

  1. 设备模型相关(include/linux/device.h
  • 定义 struct device_attribute(设备属性结构体)和 DEVICE_ATTR 宏,用于设备在 sysfs 中暴露属性;
  • 提供 device_create_file/device_remove_file 等函数,简化设备属性的注册。
  1. 总线与驱动相关(include/linux/device.hinclude/linux/module.h
  • 总线(如 platform 总线)和驱动通过 struct bus_attributestruct driver_attribute 定义自己的 sysfs 属性;
  • 例如,/sys/bus/platform/drivers/ 下的驱动属性文件,由 driver_create_file 函数创建。
  1. 类设备相关(include/linux/device.h
  • 类(struct class)通过 struct class_attribute 定义类级别的 sysfs 属性(如 /sys/class/leds/ 目录下的共性属性);
  • 提供 class_create_file 等函数,用于类属性的注册。

四、用户态可见的 sysfs 目录结构

虽然不属于内核实现文件,但了解用户态可见的 sysfs 目录结构有助于理解其实现逻辑。sysfs 挂载在 /sys 目录下,核心子目录包括:

  • /sys/devices/:所有设备的底层表示,按硬件拓扑结构组织;
  • /sys/class/:按设备功能分类的目录(如 ledsttynet),是用户访问的主要入口;
  • /sys/bus/:按总线类型分类(如 platformusb),包含总线上的设备和驱动;
  • /sys/drivers/:系统中所有驱动的信息;
  • /sys/dev/:设备号与设备的映射关系。

总结

sysfs 的实现以 fs/sysfs/ 目录为核心,其中 file.cdir.cattr.c 分别负责文件操作、目录管理和属性注册,mount.c 负责与 VFS 对接。同时,内核其他子系统(设备模型、总线、驱动)通过定义属性结构体和注册函数,将自身信息暴露到 sysfs 中,最终形成用户态可见的 /sys 目录结构。这些文件共同实现了 sysfs 作为 "内核对象属性暴露机制" 的核心功能。

如何生成sysfs接口

在 Linux 驱动中,向用户空间提供 sysfs 操作接口的核心是定义 "属性(attribute)" 并注册到内核 ,通过内核提供的标准化接口将属性文件暴露在 /sys 目录下。以下是具体实现步骤和示例:

一、核心概念:sysfs 属性(attribute)

sysfs 接口的基本单位是 "属性文件"(如 /sys/class/leds/led0/brightness),每个属性文件对应一个 struct attribute 或其派生结构体(如设备属性 struct device_attribute),包含:

  • 属性名称(如 "brightness");
  • 访问权限(如 0644 表示用户可读、root 可写);
  • 读写回调函数(用户读写文件时触发,实现具体逻辑)。

二、驱动实现 sysfs 接口的步骤

  1. 包含必要头文件

    #include <linux/sysfs.h> // sysfs 核心定义
    #include <linux/kobject.h> // kobject 相关(sysfs 依赖的对象模型)
    #include <linux/device.h> // 设备属性相关(如 struct device_attribute)

  2. 定义属性读写回调函数

回调函数是 sysfs 接口的核心,负责处理用户空间的读写请求:

  • 读函数(show :用户执行 cat 时调用,将内核数据返回给用户;
  • 写函数(store :用户执行 echo 时调用,处理用户传入的数据。

示例(以 LED 亮度控制为例)

复制代码
// 读回调:返回当前亮度
static ssize_t brightness_show(struct device *dev, 
                              struct device_attribute *attr, 
                              char *buf) {
    struct my_led_dev *led_dev = dev_get_drvdata(dev);  // 获取私有数据
    // 将亮度值写入 buf,返回字符串长度(内核会自动将 buf 复制到用户空间)
    return sprintf(buf, "%d\n", led_dev->brightness);
}

// 写回调:设置亮度(并控制硬件)
static ssize_t brightness_store(struct device *dev, 
                               struct device_attribute *attr, 
                               const char *buf, 
                               size_t count) {
    struct my_led_dev *led_dev = dev_get_drvdata(dev);
    unsigned int brightness;
    int ret;

    // 将用户传入的字符串(如 "255")转换为整数
    ret = kstrtouint(buf, 10, &brightness);
    if (ret < 0)
        return ret;

    // 校验亮度范围(0~255)
    if (brightness > 255)
        return -EINVAL;

    // 更新私有数据
    led_dev->brightness = brightness;
    // 控制硬件(如通过 GPIO 点亮/熄灭 LED)
    gpiod_set_value(led_dev->gpiod, brightness ? 1 : 0);

    return count;  // 返回处理的字节数
}
  1. 定义属性结构体

通过内核提供的宏(如 DEVICE_ATTR)将属性名称、权限和回调函数绑定:

复制代码
// 定义名为 "brightness" 的设备属性,权限 0644(可读可写)
static DEVICE_ATTR(brightness, 0644, brightness_show, brightness_store);
  • DEVICE_ATTR 是设备类属性的宏,展开后生成 struct device_attribute 结构体;
  • 格式:DEVICE_ATTR(属性名, 权限, 读函数, 写函数)
  • 权限规则同文件系统(如 0644 表示 rw-r--r--)。
  1. 注册属性到 sysfs

将定义的属性添加到内核的 sysfs 目录中,通常在驱动的 probe 函数中完成:

  • device_create_file(dev, &dev_attr_brightness):在设备的 sysfs 目录(如 /sys/devices/platform/.../)下创建 brightness 文件;
  • 若要创建多个属性,可多次调用 device_create_file,或使用 device_create_files 批量注册。
  1. 注销属性(可选)

驱动卸载时,需清理 sysfs 属性(通常在 remove 函数中):

复制代码
static int my_led_remove(struct platform_device *pdev) {
    struct device *dev = &pdev->dev;
    // 注销属性文件
    device_remove_file(dev, &dev_attr_brightness);
    return 0;
}

三、sysfs 目录的组织方式

sysfs 接口的路径由驱动注册时的 "对象类型" 决定,常见场景:

  1. 设备相关属性 :注册到设备的 sysfs 目录(/sys/devices/.../,由内核自动生成);

  2. 类设备属性 :若驱动使用 class_create 创建了类(如 LED 子系统的 leds 类),属性会出现在 /sys/class/<类名>/<设备名>/ 下(更易访问);

    复制代码
    // 示例:创建类并关联设备,属性会出现在 /sys/class/my_led_class/led0/ 下
    struct class *my_led_class = class_create(THIS_MODULE, "my_led_class");
    device_create(my_led_class, NULL, devno, NULL, "led0");  // 生成 /sys/class/my_led_class/led0/
  3. 总线 / 驱动属性 :注册到总线或驱动的目录(如 /sys/bus/platform/drivers/my_led/)。

四、用户空间操作示例

属性注册成功后,用户可通过标准文件操作接口访问:

复制代码
# 查看当前亮度
cat /sys/class/my_led_class/led0/brightness

# 设置亮度为 255(点亮)
echo 255 > /sys/class/my_led_class/led0/brightness

# 设置亮度为 0(熄灭)
echo 0 > /sys/class/my_led_class/led0/brightness

五、高级用法:属性组(attribute group)

若驱动需要暴露多个属性(如 brightnesstriggerdelay_on),可将其组织为 "属性组" 批量注册,简化代码:

复制代码
// 定义多个属性
static DEVICE_ATTR(brightness, 0644, brightness_show, brightness_store);
static DEVICE_ATTR(trigger, 0644, trigger_show, trigger_store);

// 定义属性组
static struct attribute *my_led_attrs[] = {
    &dev_attr_brightness.attr,
    &dev_attr_trigger.attr,
    NULL  // 数组结尾必须为 NULL
};
ATTRIBUTE_GROUPS(my_led);  // 生成属性组结构体

// 注册属性组(在 probe 中)
ret = device_add_groups(dev, my_led_groups);

总结

Linux 驱动向用户提供 sysfs 接口的核心流程是:

  1. 实现属性的 show(读)和 store(写)回调函数;
  2. DEVICE_ATTR 等宏定义属性结构体;
  3. 通过 device_create_file 或属性组将属性注册到 sysfs;
  4. 用户空间通过 /sys 目录下的属性文件与驱动交互。

这种方式无需手动实现 file_operations,内核会自动处理文件系统交互细节,是驱动向用户空间暴露简单控制接口的首选方式。

主要应用场景

sysfs 确实更适合实现简单的属性读写操作,但通过合理设计,也能支持一定程度的复杂交互。不过受限于其 "属性文件" 的设计理念,它在复杂操作场景下存在明显局限性。

一、sysfs 的设计定位:聚焦 "属性暴露"

sysfs 诞生的核心目标是将内核对象(如设备、驱动、总线)的属性以文件形式暴露给用户空间,方便用户查询和配置这些属性(如设备状态、硬件参数、驱动配置等)。

其设计理念决定了它天然适合:

  • 简单的键值对式属性 (如 brightness = 255temperature = 35);
  • 单次读写即可完成的操作(如开关设备、修改参数);
  • 无需复杂状态交互的场景(如查询设备版本、查看资源占用)。

二、sysfs 能支持的 "非简单" 操作(有限)

通过一些技巧,sysfs 可以实现略复杂的交互,但本质上仍是基于 "文件读写" 的扩展:

1. 多值属性(结构化数据)

可以在一个属性文件中读写结构化数据 (如逗号分隔的多个参数),在 show/store 函数中解析。

例如,一个控制 LED 闪烁的属性 blink_params

复制代码
// 写回调:解析 "on_ms,off_ms" 格式的参数
static ssize_t blink_params_store(...) {
    unsigned int on_ms, off_ms;
    // 从 buf 中解析两个数值(如 "500,300")
    if (sscanf(buf, "%u,%u", &on_ms, &off_ms) != 2)
        return -EINVAL;
    // 配置硬件闪烁参数
    set_led_blink(on_ms, off_ms);
    return count;
}
// 读回调:返回当前闪烁参数
static ssize_t blink_params_show(...) {
    return sprintf(buf, "%u,%u\n", led_dev->on_ms, led_dev->off_ms);
}
DEVICE_ATTR(blink_params, 0644, blink_params_show, blink_params_store);

用户操作:

复制代码
echo "500,300" > /sys/class/leds/led0/blink_params  # 设置亮500ms,灭300ms

2. 触发式操作(无数据交互)

通过 "空文件" 触发操作(写入任意内容即执行动作,无需传递参数)。

例如,一个重启设备的属性 reset

复制代码
static ssize_t reset_store(...) {
    // 忽略写入内容,直接执行重启逻辑
    device_reset(dev);
    return count;
}
// 只读为空,只需要写回调
DEVICE_ATTR(reset, 0200, NULL, reset_store);  # 权限 0200 表示仅 root 可写

用户操作:

复制代码
echo 1 > /sys/class/mydevice/reset  # 触发设备重启(写入任意内容均可)

3. 批量属性(属性组)

通过属性组(attribute group)将多个相关属性组织在一起,形成 "逻辑上的复杂接口"。

例如,一个传感器设备可能有 temperaturehumiditypressure 三个属性,用户可分别读写,组合起来实现环境监测。

三、sysfs 的局限性(不适合复杂操作)

尽管能做一些扩展,sysfs 仍有难以突破的限制,使其不适合复杂交互:

1. 没有 "命令" 概念,仅支持 "属性读写"

sysfs 本质是 "文件",只能通过 read/write 操作,无法像 ioctl 那样传递 "命令 + 参数"(如 IOCTL_SET_MODE(MODE_FAST))。复杂操作需要拆解为多个属性,或在 store 中解析字符串命令(如 echo "set_mode fast" > control),可读性和效率都很差。

2. 不支持双向流交互

无法像字符设备那样通过 read/write 实现 "持续数据流"(如串口收发数据)。sysfs 的 read 通常是 "一次性返回当前状态",而非 "阻塞等待新数据"。

3. 缺乏并发控制和事务性

  • 多个属性的读写无法保证原子性(如同时修改 on_msoff_ms 可能导致中间状态异常);
  • 内核对 sysfs 的并发访问控制有限,复杂场景下需驱动自行实现锁机制,容易出错。

4. 性能限制

sysfs 每次读写都会涉及用户态 / 内核态切换,且文件操作本身有开销,不适合高频交互(如每秒数千次的参数修改)。

四、复杂操作该用什么?

如果需要复杂交互,应选择更适合的用户空间接口:

交互类型 推荐接口 典型场景
命令 + 参数(如配置模式) 字符设备(ioctl 摄像头参数配置、网络设备控制
持续数据流(如收发数据) 字符设备 / 块设备(read/write 串口通信、磁盘读写、音频流
高频数据交互 共享内存(mmap)+ 字符设备 显卡驱动、高性能传感器数据采集
异步事件通知 netlinkuevent 热插拔事件、设备状态变化通知

总结

sysfs 的核心定位是 **"属性暴露与简单配置"**,最适合实现键值对式的属性读写。虽然通过技巧能支持一定的复杂操作(如结构化数据、触发式动作),但受限于其 "文件属性" 的设计理念,在命令交互、流数据、并发控制等场景下存在天然缺陷。

驱动开发中应遵循 "简单属性用 sysfs,复杂交互用字符设备 / 其他接口" 的原则,避免过度使用 sysfs 实现不适合的功能。

sysfs和设备节点

sysfs也是基于file_operations,难道不会同时生成设备节点文件吗?

sysfs 虽然基于 file_operations,但它不会生成 /dev 目录下的设备节点文件 ,这与它的设计定位和内核实现方式密切相关。核心原因是:sysfs 是一种 "虚拟文件系统",其文件是内核动态创建的 "属性节点",而非传统意义上的 "设备节点"

1. 先明确两个概念的区别

  • /dev 下的设备节点 :通常是字符设备、块设备等 "可操作设备" 的入口,由 mknod 或内核 device_create() 生成,关联具体的设备驱动(通过主 / 次设备号绑定 file_operations),用于复杂的设备交互(如 read/write/ioctl)。
  • sysfs 下的属性文件 :是内核对象(设备、驱动、总线等)的 "属性描述",由内核在 sysfs 文件系统中动态创建,仅用于暴露属性(如状态、参数),不关联主 / 次设备号。

2. sysfs 基于 file_operations,但为何不生成 /dev 节点?

(1)file_operations 的作用不同

sysfs 的 file_operations内核为 sysfs 虚拟文件系统实现的通用模板 (定义在 fs/sysfs/file.c 中),其核心作用是:

  • 处理用户对 sysfs 属性文件的 read/write 操作;
  • 将操作转发给驱动定义的 show/store 回调函数(属性读写逻辑)。

/dev 设备节点的 file_operations驱动为特定设备实现的硬件操作逻辑 (如串口的 read/write、显卡的 ioctl),直接关联硬件控制。

两者虽然都使用 file_operations 结构体,但前者是 "通用属性转发器",后者是 "设备硬件操作器",定位完全不同。

(2)sysfs 属于独立的虚拟文件系统

Linux 内核支持多种文件系统(如 ext4、proc、sysfs、tmpfs),每种文件系统有自己的目录结构和创建规则:

  • /dev 目录通常挂载的是 devtmpfstmpfs 文件系统,专门用于存放设备节点;
  • /sys 目录挂载的是 sysfs 文件系统,专门用于存放内核对象的属性文件。

sysfs 的属性文件仅存在于 /sys 目录下,与 /dev 属于不同的文件系统,因此不会在 /dev 下生成节点。

(3)sysfs 依赖 kobject 模型,而非设备号

sysfs 的文件创建不依赖 "主 / 次设备号",而是基于内核的 kobject 模型:

  • 每个 sysfs 属性文件都关联一个 kobject(内核对象的抽象,如 struct devicestruct driver);
  • 通过 sysfs_create_file(kobj, &attr) 等函数创建文件,文件路径由 kobject 的层级关系决定(如 /sys/class/leds/led0/brightness)。

/dev 设备节点的创建必须依赖主 / 次设备号(通过 device_create()mknod),用于内核识别 "哪个设备对应哪个驱动"。

3. 举例:LED 子系统的 sysfs 与设备节点对比

以 LED 驱动为例:

  • sysfs 属性文件/sys/class/leds/led0/brightnessdevice_create_file() 创建,关联 struct devicekobject 派生),使用 sysfs 通用 file_operations,仅用于读写亮度属性;
  • 若生成 /dev 节点 :需额外调用 alloc_chrdev_region() 分配设备号,cdev_init() 绑定驱动自定义的 file_operationsdevice_create()/dev 下生成节点(如 /dev/led0),这与 sysfs 是两套独立的机制。

总结

sysfs 虽然依赖 file_operations,但它与 /dev 设备节点的本质区别在于:

  • 定位不同 :sysfs 是 "属性暴露系统",/dev 节点是 "设备操作入口";
  • 实现机制不同 :sysfs 基于 kobject 和独立的虚拟文件系统,/dev 节点基于设备号和字符 / 块设备框架;
  • 用途不同 :sysfs 适合简单属性读写,/dev 节点适合复杂设备交互。

因此,sysfs 不会生成 /dev 下的设备节点,两者是 Linux 内核中并行存在的两种用户空间接口机制。

相关推荐
zz_nj1 小时前
工作的环境
linux·运维·服务器
极客先躯1 小时前
如何自动提取Git指定时间段的修改文件?Win/Linux双平台解决方案
linux·git·elasticsearch
suijishengchengde2 小时前
****LINUX时间同步配置*****
linux·运维
qiuqyue2 小时前
基于虹软Linux Pro SDK的多路RTSP流并发接入、解码与帧级处理实践
linux·运维·网络
切糕师学AI3 小时前
Linux 操作系统简介
linux
南烟斋..3 小时前
GDB调试核心指南
linux·服务器
爱跑马的程序员3 小时前
Linux 如何查看文件夹的大小(du、df、ls、find)
linux·运维·ubuntu
oMcLin6 小时前
如何在 Ubuntu 22.04 LTS 上部署并优化 Magento 电商平台,提升高并发请求的响应速度与稳定性?
linux·运维·ubuntu
Qinti_mm6 小时前
Linux io_uring:高性能异步I/O革命
linux·i/o·io_uring
优雅的38度6 小时前
linux环境下,使用docker安装apache kafka (docker-compose)
linux·架构