Unix进程能打开的最大文件数

  1. ulimit -n可以设置和查询当前进程能打开的最大文件数:
# ulimit -n 65536
# ulimit -n
65536
  1. 有些Unix系统还保留OPEN_MAX定义,但其实已经没用了。比如Linux系统就完全移除了OPEN_MAX

  2. 在程序中使用sysconf(_SC_OPEN_MAX)getrlimit来获得进程能打开的最大文件数。

参考:
Advanced Programming in the UNIX Environment: Week 02, Segment 1 – File Descriptors

查看Unix/Linux文件的inode

Unix/Linux系统上可以使用stat命令查看文件的inode信息。NetBSD系统:

# stat -f %i foo
1400196

Linux系统:

# stat -c %i foo
277428

也可以使用ls命令:

# ls -i foo
1400196 foo

df命令可以显示整个文件系统的inode使用情况,仍以Linux为例:

# df -i
Filesystem     Inodes  IUsed  IFree IUse% Mounted on
devtmpfs        55113    371  54742    1% /dev
tmpfs           61625      1  61624    1% /dev/shm
tmpfs           61625    371  61254    1% /run
/dev/sda1      524288 116074 408214   23% /
cgroup          61625     13  61612    1% /sys/fs/cgroup
tmpfs           61625      3  61622    1% /tmp

要注意inode的数量是预先分配好的。我曾经经历过的一个短信网关项目最初的设计的就是每条短信都存到一个文件里,结果很快就把inode用光了:-)。

uptime和vmstat在显示系统负载的区别

uptime可以用来检查Linux系统的负载状况:

$ uptime
 22:53:34 up 169 days,  6:47, 19 users,  load average: 1.99, 2.00, 2.03

load average后面的3个值分别是系统在过去1515分钟负载的平均值(这里的负载包含3种进程:当前正在被CPU执行的,一切条件就绪等待CPU调度的,和等待I/O操作结果的)。

vmstat也可以用来检查Linux系统的负载状况:

$ vmstat 1
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 2  0      0 32312576 1716732 74998032    0    0     0     8    0    0  2  0 98  0  0
 2  0      0 32312264 1716732 74998032    0    0     0     0 3059  139  5  0 95  0  0
 ......

其中r这一栏表示当前正在被CPU执行的,和一切条件就绪等待CPU调度的进程。由于其不包含等待I/O操作结果的进程,所以vmstatuptime更准确地表示系统是否“饱和”:如果r的值大于CPU数量(这里的CPU指一个“逻辑CPU”,即需要考虑物理CPU有多个core,每个core支持hyper-thread的情况),那么系统就处于饱和状态。

对于其它的Unix系统,需要查阅文档确认是否同Linux一致。

查看Unix/Linux进程内存分布

Unix平台,如果要查看某个进程的内存分布,可以使用gdb附着在该进程,再使用“info proc mappings”命令:

$ sudo gdb -p 1
......
(gdb) info proc mappings
process 1
Mapped address spaces:

          Start Addr           End Addr       Size     Offset objfile
            0x400000           0x401000     0x1000        0x0 /usr/bin/runit
            0x401000           0x480000    0x7f000     0x1000 /usr/bin/runit
            0x480000           0x4aa000    0x2a000    0x80000 /usr/bin/runit
            0x4ab000           0x4ae000     0x3000    0xaa000 /usr/bin/runit
            0x4ae000           0x4b0000     0x2000        0x0
            0x62d000           0x650000    0x23000        0x0 [heap]
      0x7ffe5e3f3000     0x7ffe5e414000    0x21000        0x0 [stack]
      0x7ffe5e4a4000     0x7ffe5e4a7000     0x3000        0x0 [vvar]
      0x7ffe5e4a7000     0x7ffe5e4a8000     0x1000        0x0 [vdso]

另外在Linux系统上,也可以使用pmap命令:

$ sudo pmap -x 1
1:   runit
Address           Kbytes     RSS   Dirty Mode  Mapping
0000000000400000       4       4       0 r---- runit
0000000000401000     508     440       0 r-x-- runit
0000000000480000     168     124       0 r---- runit
00000000004ab000      12      12      12 rw--- runit
00000000004ae000       8       8       8 rw---   [ anon ]
000000000062d000     140       8       8 rw---   [ anon ]
00007ffe5e3f3000     132      12      12 rw---   [ stack ]
00007ffe5e4a4000      12       0       0 r----   [ anon ]
00007ffe5e4a7000       4       4       0 r-x--   [ anon ]
---------------- ------- ------- -------
total kB             988     612      40

通过查看进程的内存分布,可以了解哪些地址是有效的,可写的;这对于调试有一定帮助。

Tmux简明手册

screen类似,tmux也用来管理多个终端回话。常用的就是下面几个命令:

(1)创建新会话:

# tmux

创建时指定会话的名字(2是会话名字),多用于复用之前已经退出会话的名字:

# tmux new -s 2  

(2)离开(detach)会话:先输入Ctrl + b,然后输入d
(3)列出当前管理的所有会话(冒号前面的是会话名字):

# tmux ls
0: 1 windows (created Wed Jul  3 15:08:44 2019) [88x29]
1: 1 windows (created Wed Jul  3 16:29:19 2019) [120x39]

(4)附着(attach)某个会话(2是会话名字):

# tmux a -t 2

(5)杀死某个会话(2是会话名字):

# tmux kill-session -t 2

参考资料:
A Gentle Introduction to tmux
tmux cheatsheet