当前位置:首页>Linux>Linux内核随处可见“面向对象”,但就是不用C++来写

Linux内核随处可见“面向对象”,但就是不用C++来写

  • 2026-09-18 21:34:25
Linux内核随处可见“面向对象”,但就是不用C++来写

Linux内核随处可见面向对象思想,但就是不用 C++ 来写,这里面是不是有什么说法?

这个问题,其实从 Linux 之父林纳斯本人的口中就能找到答案,他曾经多次公开吐槽过 C++ 是糟糕的语言。

首先,我们来看下内核有哪些面向对象思想?

/* * NOTE: * read, write, poll, fsync, readv, writev, unlocked_ioctl and compat_ioctl * can be called without the big kernel lock held in all filesystems. */struct file_operations {    struct module *owner;    loff_t (*llseek) (struct file *, loff_t, int);    ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);    ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);    ssize_t (*aio_read) (struct kiocb *, const struct iovec *, unsigned long, loff_t);    ssize_t (*aio_write) (struct kiocb *, const struct iovec *, unsigned long, loff_t);    int (*readdir) (struct file *, void *, filldir_t);    unsignedint(*poll)(struct file *, struct poll_table_struct *);    int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long);    long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);    long (*compat_ioctl) (struct file *, unsigned int, unsigned long);    int (*mmap) (struct file *, struct vm_area_struct *);    int (*open) (struct inode *, struct file *);    int (*flush) (struct file *, fl_owner_t id);     int (*release) (struct inode *, struct file *);    int (*fsync) (struct file *, struct dentry *, int datasync);    int (*aio_fsync) (struct kiocb *, int datasync);    int (*fasync) (int, struct file *, int);    int (*lock) (struct file *, int, struct file_lock *);    ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int);    unsignedlong(*get_unmapped_area)(struct file *, unsignedlong, unsignedlong, unsignedlong, unsignedlong);    int (*check_flags)(int);    int (*flock) (struct file *, int, struct file_lock *);    ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int);    ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, size_t, unsigned int);    int (*setlease)(struct file *, long, struct file_lock **); };

比如最典型的 struct file_operations 结构体,这是Linux 虚拟文件系统中用于操作文件的“对象”。结构体里面几乎都是指针,更像是C++中的“虚函数表“,定义了open、read、write、release等一系列操作。具体的文件系统会提供自己的实现,并将这些函数指针赋值给这个结构体。

内核没有 C++ 的“继承”语法,但通过将父结构体作为子结构体的成员,实现了类似继承的效果。

/* * The pci_dev structure is used to describe PCI devices. */struct pci_dev {    struct list_head bus_list;  /* node in per-bus list */    struct pci_bus  *bus;       /* bus this device is on */    struct pci_bus  *subordinate;   /* bus this device bridges to */    void        *sysdata;   /* hook for sys-specific extension */    struct proc_dir_entry *procent; /* device entry in /proc/bus/pci */    struct pci_slot *slot;      /* Physical slot this device is in */    // ....#ifdef CONFIG_PCIEASPM    struct pcie_link_state  *link_state;    /* ASPM link state. */#endif    pci_channel_state_t error_state;    /* current connectivity state */    struct  device  dev;        /* Generic device interface */    int     cfg_size;   /* Size of configuration space */    /*     * Instead of touching interrupt line and base address registers     * directly, use the values stored here. They might be different!     */    unsigned int    irq;    struct resource resource[DEVICE_COUNT_RESOURCE]; /* I/O and memory regions + expansion ROMs */    // ....};
 最典型的就是 struct device 和 struct pci_device 结构体,pci_device 里面包含了 device 结构体。

面向对象最核心的思想,应该就是多态,在内核里面,也有很多多态的案例。比如文件系统中的struct file_operations。对于一个struct file,无论它代表什么样的文件,内核都通过 file->f_op->read() 来调用其读操作。f_op这个函数指针表指向了不同文件系统各自实现的read函数,从而实现了“同一个接口,多种行为”的多态性。

说完了面向对象特性,再来看看为什么内核不直接用 C++ 来写。

第一点,异常处理,这也是林纳斯最反感的一点。C++的异常处理机制在内核这种底层、资源敏感的环境中会带来巨大的不确定性和不可预测性。内核需要精确控制每一处错误路径,而异常处理隐藏了控制流,使得代码行为难以预测,对内核的稳定性是致命的

第二点,隐藏的内存分配。比如构造函数,会在开发者不知情的情况下进行内存分配。在内核中,内存是极其宝贵的资源,任何“隐形”的操作都可能成为性能瓶颈或导致不可预知的失败。

第三点,性能与可预测性。C++的诸多高级特性(如虚函数、模板、RTTI等)会引入额外的运行时开销,这些开销在内核这种对性能要求苛刻的场景下是不可接受的。使用C,代码的行为几乎完全透明,开发者可以精确地知道每一行代码会生成什么样的机器指令。

第四点,C++还是太复杂了。在一个拥有数千万行代码、由全球数千名开发者共同维护的项目中,这种复杂性会成为沟通和理解的巨大障碍。

大家觉得,还有哪些原因导致内核不用C++来写,欢迎在评论区交流。

实战延伸___

以上只是 Linux 工程中的一个小技巧,如果你也想真正写出工程级代码,我整理了几个完整项目,这个暑期可以一对一带着做,从0到可运行项目,适合做简历提升。

品牌宣传 | 企业培训 | 技术推广 | 职业提升
请在公众号后台回复 合作

最新文章

随机文章