learn-tlpi
hev-task-system
binder-linux
segedit
the-art-of-command-line
bcc
Qv2ray
macOS-Simple-KVM
darling
bpftrace
linux-insides-zh
sysstat
linux-0.12
ply
fineftp-server
traces
syscall-tabl
Docker-OSX
OSX-KVM
coreutils
lsof

关于 root 和 wheel:在 Linux 中创建管理员账号(root 权限)的正确方式
https://zhuanlan.zhihu.com/p/355710754

Linux文件事件监控之Fanotify [一]
https://zhuanlan.zhihu.com/p/186027813

sendfile(),splice(),tee()函数
https://blog.csdn.net/qq_36553387/article/details/119759192

linux_syscall.md

1
2
3
4
5
6
7
8
9
__NR_name_to_handle_at
#define __NR_ptrace 101
#define __NR_bpf 321
#define __NR_userfaultfd 323
#define __NR_copy_file_range 326
#define __NR_statx 332
#define __NR_io_uring_setup 425
#define __NR_pidfd_getfd 438
#define __NR_landlock_add_rule 445

Bash - get current script directory path
https://dirask.com/posts/Bash-get-current-script-directory-path-1X9E8D

文件锁实现

1
2
3
4
5
6
https://github.com/tox-dev/py-filelock
win32 locking
https://learn.microsoft.com/zh-cn/cpp/c-runtime-library/reference/locking
unix flock
man flock https://linux.die.net/man/2/flock
soft impl -> open O_EXCL

用一分钟了解: fsync这个系统调用!

https://blog.51cto.com/u_15015155/2615475

Arch Linux 已从 SVN 迁移至 GitLab

https://www.oschina.net/news/241933/arch-linux-git-svn-migration-over

负载均衡算法–轮询法(Round Robin)

https://blog.csdn.net/claram/article/details/90265243

常见的负载均衡算法包含:
1、轮询法(Round Robin)
2、加权轮询法(Weight Round Robin)
3、随机法(Random)
4、加权随机法(Weight Random)
5、平滑加权轮询法(Smooth Weight Round Robin)
6、源地址哈希法(Hash)
7、最小连接数法(Least Connections)

fio

https://github.com/axboe/fio

1
2
3
4
5
6
7
8
9
10
# macOS
fio --filename=$HOME/2m-seq-read --direct=1 --rw=read --ioengine=posixaio --bs=2m --iodepth=64 --size=10G --numjobs=1 --runtime=1 --time_base=1 --group_reporting --name=test-seq-read
rm 2m-seq-read

fio --filename=$HOME/seq-write --name=seq-write --size=128M --rw=write

# HDD
fio --name=seq-read --size=128M --rw=write && rm seq-read.0.0
# SSD
fio --name=seq-read --size=128M --rw=write --bs=1m && rm seq-read.0.0

linux中whereis、which、find、location的区别和用法

https://www.cnblogs.com/cjjjj/p/9846374.html

Manjaro HiDPI

1
2
3
4
5
hidpi
窗体管理器
Matcha-sea -> Matcha-sea-hdpi
外观->设置->窗口缩放
2x

xrandr

1
xrandr --output Virtual1 --mode 3840x2160

彻底学会使用epoll(一)——ET模式实现分析

https://zhuanlan.zhihu.com/p/410285273

abstract namespace unix socket

https://cloud.tencent.com/developer/article/1839208
http://linux.die.net/man/7/unix

unix socket 有3种:

基于文件的
socketpair 创建的,匿名的
abstract namespace 的,Linux特有

Linux 下, AF_UNIX socket 支持一种特殊的 abstract namespace unix socket 。

相比 普通的基于文件系统的 unix socket,abstract namespace unix socket :

没有磁盘文件
进程挂了以后自动删除,无残留文件
无需担心与 文件系统上的文件冲突,不需要关心文件系统上的绝对路径是否存在的问题

C/C++ Linux 异步IO(AIO)

https://zhuanlan.zhihu.com/p/555604045?utm_id=0

BSD异步IO -> SIGIO/O_ASYNC
POSIX异步IO(AIO) -> aio_read

O_NOATIME标志的设计旨在为索引和备份程序服务。该标志的使用能够显著减少磁盘的活动量。

文件 I/O 的两种竞争状态

以独占方式创建一个文件

当同时指定 O_EXCL 与 O_CREAT 作为 open()的标志位时,如果要打开 的文件已然存在,则 open()将返回一个错误。
这提供了一种机制,保证进程是打开文件的创建者。

向文件尾部追加数据

多个进程同时向同一个文件(例如,全局日 志文件)尾部添加数据。
要规避这一问题,需要将文件偏移量的移动与数据写操作纳入同一原子操作。
在打开文 件时加入 O_APPEND 标志就可以保证这一点。

pread/pwrite

当调用 pread()或 pwrite()时,多个线程可同时对同一文件描述符执行 I/O 操作,且不会因其他线程修 改文件偏移量而受到影响。如果还试图使用 lseek()和 read()(或 write())来代替 pread()(或 pwrite()),那么将引发竞争状态,这类似于 5.1 节讨论 O_APPEND 标志时的描述(当多个进 程的文件描述符指向相同的打开文件句柄时,使用 pread()和 pwrite()系统调用同样能够避免进 程间出现竞争状态)。

如果需要反复执行 lseek(),并伴之以文件 I/O,那么 pread()和 pwrite()系统调用在某些 情况下是具有性能优势的。这是因为执行单个 pread()(或 pwrite())系统调用的成本要低于 执行 lseek()和 read()(或 write())两个系统调用。然而,较之于执行 I/O 实际所需的时间, 系统调用的开销就有些相形见绌了。

Linux 2.6.30 版本新增了两个系统调用:preadv()、pwritev(),将分散输入/集中输出和于指
定文件偏移量处的 I/O 二者集于一身。它们并非标准的系统调用,但获得了现代 BSD 的支持。

ReadFile -> overlapped
https://github.com/aleitner/windows_pread

_FILE_OFFSET_BITS 宏

显然,使用宏_FILE_OFFSET_BITS 要比采用过渡型的 LFS API 更为简单,但这也要求应 用程序的代码编写必须规范(例如,声明用于放置文件偏移量的变量,应正确地使用 off_t, 而不能使用“原生”的 C 语言整型)。

glibc 提供的 malloc 调试工具的部分功能

MALLOC_TRACE -> mtrace/muntrace
MALLOC_CHECK_ -> mcheck/mprobe
众多 UNIX 实现提供各种版本的 mallopt()和 mallinfo()。
然而,这些函数所提供的接口却 随实现而不同,因而也无法移植。

由于 realloc()可能会移动内存块,任何指向该内存块内部的指针在调用 realloc()之后都可 能不再可用。

alloca

在信号处理程序中调用 longjmp()(6.8 节)或 siglongjmp()(21.2.1 节)以执行非局部跳 转时,alloca()的作用尤其突出。此时,在“起跳”函数和“落地”函数之间的函数中,如果 使用了 malloc()来分配内存,要想避免内存泄漏就极其困难,甚至是不可能的。与之相反, alloca()完全可以避免这一问题,因为堆栈是由这些调用展开的,所以已分配的内存会被自动 释放

passwd

只要访问密码信息的程序采用的是本章稍后描述的函数(getpwnam()、 getpwuid()等),那么无论是使用 NIS 还是 LDAP,对应用程序来说都是透明的。

读取密码的程序应立即加密密码,并尽快将密码的明 文从内存中抹去。只有这样,才能基本杜绝如下事件的发生:恶意之徒借程序崩溃之机,读 取内核转储文件以获取密码。

可重入

可重入(reentrancy) vs. 线程安全(thread-safety)
https://zhuanlan.zhihu.com/p/352218464
一文理解可重入函数
https://zhuanlan.zhihu.com/p/280711576

1
2
3
4
满足下列条件的函数多数是不可重入的:
函数体内使用了静态(static)/全局(global)的数据结构;
函数体内调用了 malloc() 或者 free() 函数;
函数体内调用了标准 I/O 函数;

device

与其他类型的文件一样,设备文件总会出现在文件系统中,通常位于/dev 目录下。超级
用户可使用 mknod 命令创建设备文件,特权级程序(CAP_MKNOD)执行 mknod()系统调用 亦可完成相同任务。

FUSE

Linux 2.6.14中,添加了FUSE(用户空间文件系统)工具。采用这一机制,可为内核 添加挂钩(hook),以便以用户空间程序来完整实现文件系统,而无需对内核进行修补或重 新编译。详细信息请见 http://fuse.sourceforge.net/。

VFS

VFS 的抽象层建模精确仿照传统的 UNIX 文件系统模型。当然,还有一些文件系统,尤其 是非 UNIX 文件系统,并不支持所有的 VFS 操作(。比如,微软的 VFAT 就不支持使用 symlink() 创建的符号链接概念。)对于这种情况,底层文件系统会将错误代码传回 VFS 层,表明不支持 相应操作,而 VFS 随之会将错误代码传递给应用程序。

tmpfs

由于不涉及磁盘访问,虚拟文件系统的文件操作速度极快。
该文件系统不但使用 RAM,而且在 RAM 耗尽的情况下,还会利用交换空间。
(虽然此处描述的 tmpfs 文件系统为 Linux 所专有, 但大多数 UNIX 实现都提供某种形式的基于内存的文件系统。)
除了用于用户应用程序以外,tmpfs 文件系统还有以下两个特殊用途。

  • 由内核内部挂载的隐形 tmpfs 文件系统,用于实现 System V 共享内存(第 48 章)和 共享匿名内存映射(第 49 章)。
  • 挂载于/dev/shm的tmpfs文件系统,为glibc用以实现POSIX共享内存和POSIX信号量。

在 macOS 系统上创建、挂载 Ramdisk(aka: RamFS、tmpfs)
https://www.cnblogs.com/emitial/p/ramfs-on-mac.html

stat

虽然大多数 UNIX 系统都不会记录文件的创建时间,但最新的 BSD 系统会使用名为 st_birthtime 的 stat 字段来记录这一时间。[also for macOS]

可利用系统调用 chown()和 chmod()来更改文件的所有权及权限。系统调用 umask() 则用来设置权限的位掩码,当进程新建文件时,会按位掩码来关闭相应权限位。

扩展属性(EA)

EA 可用于实现访问列表(第 17 章)和文件能力(第 39 章)。但就设计而论,其能力绝 不仅限于此。例如,还可利用 EA 去记录文件的版本号、与文件的 MIME 类型/字符集有关的 信息,或是指向图符的指针。
SUSv3 并未对 EA 加以规范。但少数其他 UNIX 实现却提供了类似的特性,其中知名的 有现代 BSD(详见 extattr(2))系列和 Solaris 9 及其后续版本(详见 fsattr(5))。
EA 需要有底层文件系统来提供支撑,Btrfs、ext2、ext3、ext4、JFS、Reiserfs 以及 XFS 等文件系统都支持 EA。

此外,基于上述事实,还可以玩点小技巧:先创 建并打开一个临时文件,随即取消对文件的链接(unlink),然后在程序中继续使用该文件。(这 正是 5.12 节所述 tmpfile()函数的所作所为。)

remove

如果 pathname 是一文件,那么 remove()去调用 unlink();
如果 pathname 为一目录,那么 remove()去调用 rmdir()。
remove()属于 C 语言标准库函数,广为 UNIX 和非 UNIX 系统所支持。
大多数非 UNIX 系统并不支持硬链接,所以将移除文件的函数命名为 unlink()也不合情理。

readdir/scandir

readdir()返回时并未对文件名进行排序,而是按照文件在目录中出现的天然次序
使用scandir(3)函数可以获得经过排序处理的文件列表,且排列规则可由程序员定义
readdir_r可重入。这是因为 readdir_r()对文件条目的返回利用的是由调用者分配的 entry 参数,而 readdir()则 是将信息置于静态分配的结构并返回其指针。

nftw

nftw()函数允许程序对整个目录子树进行递归遍历,并为子树中的每个文件执行某些操作
(即,调用由程序员定义的函数)。

openat

当调用 open()打开位于当前工作目录之外的文件时,可能会发生某些竞态条件。而使 用 openat()就能够避免这一问题。在调用 open()的同时,如果 pathname 目录前缀的某 些部分发生了改变,就可能导致竞争。要想避免这类竞态,可以针对目标目录打开一个文件描述符,然后将该描述符传递给 openat()。

chroot

有些场合需 要改变一个进程的根目录,而特权级(CAP_SYS_CHROOT)进程通过 chroot()系统调用能够 做到这一点。
一些 BSD 衍生系统提供的 jail()系统调用解决了包括上述问题在内的不少问题,其所创 建的监禁区即使针对特权级进程也是安全的。

SIGTERM

发送 SIGKILL 信号可以杀掉某个进程,从而绕开了 SIGTERM 信号的处理器程序。因此,总是应该首先尝试使用 SIGTERM 信号来终止进程,而把 SIGKILL 信 号作为最后手段,去对付那些不响应 SIGTERM 信号的失控进程。

signal/sigaction

使用 signal(),将无法在不改变信号处置的同时,还能获取到当前的信号处置。要想做 到这一点,必须使用 sigaction()。

strsignal

尽管 SUSv3 并未将 psignal()、strsignal()和 sys_siglist 纳入标准,但还是有许多 UNIX 实现 支持它们。(SUSv4 中加入了对 psignal()和 strsignal()的规范。)

标准的异步信号安全函数

异步信号安全的函数是指当从信号处理器函数调用时,可以保证其实现是安全的。如 果某一函数是可重入的,又或者信号处理器函数无法将其中断时,就称该函数是异步信号安全的。

sigsetjmp/siglongjmp

鉴于两大 UNIX 流派之间的差异,POSIX.1-1990 选择不对 setjmp()和 longjmp()的信号掩 码处理进行规范,而是定义了一对新函数:sigsetjmp()和 siglongjmp(),针对执行非本地跳转 时的信号掩码进行显式控制。

SA_RESTART

即使采用了类似 NO_EINTR()这样的宏,让信号处理器来中断系统调用还是颇为不便,因 为只要有意重启阻塞的调用,就需要为每个阻塞的系统调用添加代码。反之,可以调用指定 了 SA_RESTART 标志的 sigaction()来创建信号处理器函数,从而令内核代表进程自动重启系 统调用,还无需处理系统调用可能返回的 EINTR 错误。
不幸的是,并非所有的系统调用都可以通过指定 SA_RESTART 来达到自动重启的目的。 究其原因,有部分历史因素。

zombie

在设计长生命周期的父进程(例如:会创建众多子进程的网络服务器和 Shell)时,这些 语义具有重要意义。换句话说,在此类应用中,父进程应执行 wait()方法,以确保系统总是能够 清理那些死去的子进程,避免使其成为长寿僵尸。如 26.3.1 节所述,父进程在处理 SIGCHLD 信 号时,对 wait()的调用既可同步,也可异步。

异步取消

如果设定线程为可异步取消时(取消性类型为 PTHREAD_CANCEL_ASYNCHRONOUS),可 以在任何时点将其取消(亦即,执行任何机器指令时),取消动作不会拖延到下一个取消点才执行。
作为一般性原则,可异步取消的线程不应该分配任何资源,也不能获取互斥量或锁。这 导致大量库函数无法使用,其中就包括 Pthreads 函数的大部分。(SUSv3 中有 3 处例外 pthread_cancel()、pthread_setcancelstate()以及 pthread_setcanceltype(),规范明确要求将它们实 现为“异步取消安全(async-cancel-safe)”,亦即,实现必须确保在可异步取消的线程中可以 安全调用它们。)
换言之,异步取消功能鲜有应用场景,其中之一就是:取消在执行计算密集型循环的线程。

1
Thread::enableAsynchronousCancel

https://github.com/Qalculate/libqalculate/blob/master/libqalculate/util.cc#L1070

假唤醒

如果一个信号处理函数中断了对 pthread_cond_wait()的调用,则该调用要么自 动重新开始(Linux 就是如此),要么返回 0,表示遭遇了假唤醒(如 30.2.3 节所述, 此时,设计良好的应用程序会重新检查相应的判断条件并重新发起调用)。

nohup、setsid 与 disown 的不同之处

https://baijiahao.baidu.com/s?id=1759038604359417311
nohup(1)命令可以用来使一个命令对 SIGHUP 信号免疫——即执行命令时将 SIGHUP 信号 的处理设置为 SIG_IGN。bash 内置的命令 disown 提供了类似的功能,它从 shell 的任务列表中 删除一个任务,这样在 shell 终止时就不会向该任务发送 SIGHUP 信号了。

静态库

要强制使用库的 静态版本则可以完成下列之一。
在 gcc 命令行中指定静态库的路径名(包括.a 扩展)。
在 gcc 命令行中指定-static 选项。
使用–Wl,–Bstatic 和–Wl,–Bdynamic gcc 选项来显式地指定链接器选择共享库还是静态
库。在 gcc 命令行中可以使用-l 选项来混合这些选项。链接器会按照选项被指定时的 顺序来处理这些选项。

IPC持久性

进程持久性
管道、FIFO 以及 socket 是进程持久的 IPC 工具
内核持久性
具备内核持久性的工具包括 System V IPC 和 POSIX IPC
文件系统持久性
唯一一种具备文件系统持久性的IPC对象 是基于内存映射文件的共享内存

popen

这种便捷性所牺牲的是效率,因为至少 需要创建两个额外的进程:一种用于 shell,一个或多个用于 shell 执行的命令。与 system()一样,在特权进程中永远都不应该使用 popen()

System V 消息队列

之所以得出其他 IPC 机制通常要优于 System V 消息队列的结论是因为几个因素,其中最 主要的一个是引用消息队列不会用到文件描述符。这意味着在消息队列上无法使用另一种 I/O模型,特别是同时监控消息队列和文件描述符以查看是否可进行 I/O 将变得复杂。此外,消息 队列无连接(即不进行引用计数)这个事实使得应用程序难以知道何时能够安全地删除一个 队列。

System V 信号量

不管怎样,与消息队列所面临的情况不同,替代 System V 信号量的方案不多,其结果是 在很多情况下都必须要用到它们。信号量的一个替代方案是记录锁,在第 55 章中将会对此予 以介绍。此外,从内核 2.6 以及之后的版本开始,Linux 支持使用 POSIX 信号量来进行进程同步。第 53 章将会介绍 POSIX 信号量。

POSIX IPC

POSIX IPC 接口与传统的 UNIX 文件模型更加一致。IPC 对象是通过名字来标识的,并使 用 open、close 以及 unlink 等操作方式与相应的文件相关的系统调用类似的调用来管理。

shutdown

在套接字上调用 close()会将双向通信通道的两端都关闭。有时候,只关闭连接的一端也 是有用处的,这样数据只能在一个方向上通过套接字传输。系统调用 shutdown()提供了这种 功能。

select/poll

select()和 poll()糟糕的性能延展性源自这些 API 的局限性:通常,程序重复调用这些系统 调用所检查的文件描述符集合都是相同的,可是内核并不会在每次调用成功后就记录下它们。
我们接下来要讨论的信号驱动 I/O 以及 epoll 都可以使内核记录下进程中感兴趣的文件描 述符,通过这种机制消除了 select()和 poll()的性能延展问题。这种解决方案可根据发生的 I/O 事件来延展,而与被检查的文件描述符个数无关。结果就是,当需要检查大量的文件描述符 时,信号驱动 I/O 和 epoll 能提供更好的性能表现。