Linux kernel 介绍
D-Bus
D-Bus
最初由 freedesktop.org
为 Linux
而开发的 进程之间通信IPC
和 远程控制RPC
,用一个统一的协议取代当时的 进程通信
。
D-Bus
也被设计成允许系统级进程(例如打印机、硬件驱动程序服务)和普通进程之间的通信。
D-Bus
采用二进制消息传递,所以非常快
、开销小
,特别适合同一台主机通信
kworker
kworker(Linux Kernel Worker)
是内核 3.x
引入的工作线程占位符
进程,它实际上执行内核的大部分工作,如中断、计时器、I/O等,CPU 中 system时间
大部分由此产生。在系统中,一般会出现多个 kworker
进程,kworker
进程有时会占用大量的 io
或 cpu
,格式:
kworker/%u:%d%s
说明:
u(unbound)
表示没有绑定特定的CPU,如 kworker/u256:2-events_power_efficient
进程
0 进程是 Scheduler
1 进程是 init/systemd
(user thread的父进程)
2 进程是 [kthreadd]
(kernel thread的父进程)
$ ps -eaf
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 Jun17 ? 00:00:18 /sbin/init splash
root 2 0 0 Jun17 ? 00:00:00 [kthreadd]
...
$ ls -lhart /sbin/init
lrwxrwxrwx 1 root root 20 Jan 10 12:56 /sbin/init -> /lib/systemd/systemd
init
进程是 Linux 运行的第一个进程,是其它所有进程的父进程
,主要作用:初始化系统和等待清理子进程(孤儿进程)
kernel 文件
vmlinux
:一个非压缩的,静态链接的,可执行的,且不能 bootable 的 Linux kernel 文件。是用来生成 vmlinuz 的中间步骤。路径:/sys/kernel/btf/vmlinux
vmlinuz
:一个压缩的,能 bootable 的 Linux kernel 文件。vmlinuz
是 Linux kernel 文件的历史名字,它实际上就是 zImage
或 bzImage
$ file /boot/vmlinuz-5.13.0-27-generic
/boot/vmlinuz-5.13.0-27-generic: Linux kernel x86 boot executable bzImage, version 5.13.0-27-generic (buildd@lgw01-amd64-045) #29~20.04.1-Ubuntu SMP Fri Jan 14 00:32:30 UTC 2022, RO-rootFS, swap_dev 0x9, Normal VGAs
zImage
:仅适用于 640k 内存的 Linux kernel 文件
bzImage
:Big zImage,适用于更大内存的 Linux kernel 文件。实际的内核启动文件
Kernel 启动过程
BIOS -> 引导扇区 boot.img -> diskboot.img -> 建立分段分页 -> 选择OS:kernel.img -> 启动内核
设备号
$ ls -lt /dev/
total 0 # major minor
crw-rw-rw- 1 root tty 5, 2 Jan 27 23:45 ptmx
brw-rw---- 1 root disk 7, 14 Jan 27 23:09 loop14
crw-rw-rw- 1 root tty 5, 0 Jan 27 22:53 tty
crw--w---- 1 root tty 5, 1 Jan 27 22:37 console
crw--w---- 1 xiexianbin tty 4, 2 Jan 27 22:37 tty2
crw-rw----+ 1 root kvm 10, 232 Jan 27 20:59 kvm
...
设备号的组成:
- major : 设备所使用的驱动,可以在
/proc/devices
中查看到,如下:
- minor : 具体的设备
$ cat /proc/devices
Character devices:
1 mem
4 /dev/vc/0
4 tty
4 ttyS
5 /dev/tty
...
Block devices:
7 loop
8 sd
...
CPU 的作用
实际上,在 Linux 中,CPU 在任何时刻都在做以下三件事中的一件:
- 在用户空间中,在进程中执行用户代码
- 在内核空间中,在进程上下文中,代表一个特定的进程执行
- 在内核空间中,在中断上下文中,不与进程关联,处理一个中断
信号量
- kernel 中
信号量(struct semaphore)
对临界区代码访问是原子的,用于解决不同进程对通信资源访问的同步问题
- 信号量涉及进程调度,会存在比较大的开销
原子变量(struct atomic_t)
适用于针对 int 变量进行同步的场景
端口
ip_local_port_range
:Linux 临时端口范围,用于定义网络连接可用作其源(本地)端口的最小和最大端口的限制,同时适用于TCP和UDP连接
$ cat /proc/sys/net/ipv4/ip_local_port_range
32768 60999
临时修改:
sudo sysctl -w net.ipv4.ip_local_port_range="1024 64000"
永久性修改:
在文件 /etc/sysctl.conf 添加如下内容:
net.ipv4.ip_local_port_range = 1024 65535
ip_local_reserved_ports
: 预留端口避免被其他程序占用
锁
悲观锁
总是假设最坏的情况,每次访问数据的时候都认为别的程序会修改,因此访问数据前先加锁。程序只有拿到锁时才能访问数据,否则一直处于等待状态。
适用场景:并发冲突概率高的场景,如传统关系型数据库的各种锁:表锁、行锁、读锁、写锁等。
缺点:
乐观锁
适用场景:并发量比较大的业务场景
缺点:
eBPF
eBPF 是内核的一个可编程虚拟机,广泛应用于网络报文的过滤、重定向、性能统计等,应用场景广泛。
特点: