asp做网站的缺点,做平面设计都在那个网站找免费素材?,centos wordpress环境,做网站下载那个数据库好在进程描述学习中#xff0c;扯到了max_fds#xff0c;接着就联想到了日常运维中常见的ulimit参数、sysctl内核参数#xff0c;原来以为max_fds与这些个关联性比较强#xff0c;但经过一早上折腾以后#xff0c;发现其实还是有一些差距的。但是在学习过程中#xff0c;却…在进程描述学习中扯到了max_fds接着就联想到了日常运维中常见的ulimit参数、sysctl内核参数原来以为max_fds与这些个关联性比较强但经过一早上折腾以后发现其实还是有一些差距的。但是在学习过程中却是东拉西扯折腾出了很多其他东西。
现在尝试把这些东西都统一消化一下。
文件描述符File Descriptor
fd 是 File descriptor 的缩写中文名叫做文件描述符。文件描述符是一个非负整数本质上是一个索引值。
fd是索引值fd是索引值fd是索引值
重要的事情说三遍。
什么时候需要fd
当打开一个文件时内核向进程返回一个文件描述符 open 系统调用得到 后续 read、write 这个文件时则只需要用这个文件描述符来标识该文件将其作为参数传入 read、write 。
如同task_struct内的struct files_struct *files struct task_struct {// .../* Open file information: */struct files_struct *files;// ...} 此处的files 是一个指针指向一个为 struct files_struct 的结构体。这个结构体就是用来管理该进程打开的所有文件的管理结构。
struct task_struct 是进程的抽象封装标识一个进程。当创建一个进程其实也就是 new 一个 struct task_struct 出来
上面代码通过进程结构体引出了 struct files_struct 这个结构体。这个结构体管理某进程打开的所有文件的管理结构核心代码如下
struct files_struct {
....struct fdtable __rcu *fdt;struct fdtable fdtab; //动态数组
....struct file __rcu * fd_array[NR_OPEN_DEFAULT]; //静态数组
....
};
files_struct 结构体是用来管理所有打开的文件的。通过数组进行管理所有打开的文件结构都在数组里。struct files_struct内有两个数组一个静态数组一个动态数组。
由于大部分进程只会打开少量的文件所以静态数组就够了这样就不用另外分配内存。如果超过了静态数组的阈值那么就动态扩展使用动态数组。
静态数组
#define NR_OPEN_DEFAULT BITS_PER_LONG
这是一个静态数组随着 files_struct 结构体分配出来的在 64 位系统上静态数组大小为 64
定义代码如下BITS_PER_LONG在64位系统上为64
#define NR_OPEN_DEFAULT BITS_PER_LONG
动态数组
struct fdtable
这个是数组管理结构封装用来管理 fd 的结构体代码如下
struct fdtable {unsigned int max_fds;struct file __rcu **fd; /* current fd array */unsigned long *close_on_exec;unsigned long *open_fds;unsigned long *full_fds_bits;struct rcu_head rcu;
};
fdtable.fd 这个字段是一个二级指针指向 fdtable.fd 是一个指针字段指向的内存地址还是存储指针的元素指针类型为 struct file * 。换句话说fdtable.fd 指向一个数组数组元素为指针指针类型为 struct file *。其中 max_fds 指明数组边界。
file_struct 本质上是用来管理所有打开的文件的内部的核心是由一个静态数组和动态数组管理结构实现。而文件描述符fd 就是这个数组的索引也就是数组的槽位编号已。 通过非负数 fd 就能拿到对应的 struct file 结构体的地址。 日常运维与fd擦边的参数
1. file-max /proc/sys/fs/file-max 这个文件决定了系统级别所有进程可以打开的文件描述符的数量限制尝试分配超过file-max值的文件描述符将通过printk报告查找包含VFS: file-max limit reached的信息。
rootlinux-kernel:/# sysctl -a | grep -i file-max fs.file-max 65535
修改方式 echo fs.file-max 65535000 /etc/sysctl.conf sysctl -p 2. file-nr
这个是一个状态指示的文件一共三个值第一个代表全局已经分配的文件描述符数量第二个代表自由的文件描述符待重新分配的第三个代表总的文件描述符的数量。
Linux 2.6 版本始终将空闲文件句柄数量报告为0 —— 这不是错误而是表示已分配的文件句柄数量恰好等于已使用的文件句柄数量。 rootlinux-kernel:/# cat /proc/sys/fs/file-nr 1248 0 9223372036854775807 3. nr_open
表示一个进程可以分配的最大文件句柄数量。默认值是1024*10241048576对大多数机器来说应该足够了。实际限制取决于RLIMIT_NOFILE资源限制。
unsigned int sysctl_nr_open __read_mostly 1024*1024;
unsigned int sysctl_nr_open_min BITS_PER_LONG;
4. RLIMIT_NOFILE
RLIMIT_NOFILE是一个用于限制单个进程可以打开的文件描述符数量的资源限制。它定义了当前进程能够同时打开的最大文件描述符数量。这个限制是针对每个进程的而不是系统整体的。通过调整这个限制可以控制每个进程能够同时处理的文件数量从而对系统的资源利用进行管理和优化。
可以通过ulimit -n 配置重启后失效) 或者配置/etc/security/limits.conf永久生效。openEuler默认为1024
其中nofile为number of open file 为打开文件数量针对单个进程和用户。
# /etc/security/limits.conf //将可打开数量设置为65535
* soft nofile 65535
* hard nofile 65535
对应limit默认值配置源码如下用户空间的NR_OPEN配置为1024.
另外可以通过程序接口 setrlimit()、getrlimit() 进行设置
int do_prlimit(struct task_struct *tsk, unsigned int resource,struct rlimit *new_rlim, struct rlimit *old_rlim)
{struct rlimit *rlim;int retval 0;...if (new_rlim) {if (new_rlim-rlim_cur new_rlim-rlim_max)return -EINVAL;if (resource RLIMIT_NOFILE new_rlim-rlim_max sysctl_nr_open)return -EPERM;}...
}
在/proc/sys/fs下三个参数的加载源码
static struct ctl_table fs_table[] {...{.procname file-nr,.data files_stat,.maxlen sizeof(files_stat),.mode 0444,.proc_handler proc_nr_files,},{.procname file-max,.data files_stat.max_files,.maxlen sizeof(files_stat.max_files),.mode 0644,.proc_handler proc_doulongvec_minmax,.extra1 zero_ul,.extra2 long_max,},{.procname nr_open,.data sysctl_nr_open,.maxlen sizeof(unsigned int),.mode 0644,.proc_handler proc_dointvec_minmax,.extra1 sysctl_nr_open_min,.extra2 sysctl_nr_open_max,}...
nr_open、file-max与RLIMIT_NOFILE的对比
范围
nr_open单个进程的文件描述符最大值。file-max系统范围内所有进程的文件描述符总数。RLIMIT_NOFILE每个进程的文件描述符软限制和硬限制。
层级
nr_open 和 RLIMIT_NOFILE 作用于进程级别控制单个进程可以打开的文件数量。file-max 作用于系统级别控制整个系统可以打开的文件数量。
限制机制
nr_open 提供了一个系统范围内的进程级硬限制。RLIMIT_NOFILE 可以通过用户或管理员动态调整灵活性较高。file-max 确保系统不会超出总的文件描述符资源避免资源枯竭。
关联性
在 Linux 系统中NR_OPEN 是一个内核中定义的常量它表示整个系统可以同时打开的文件描述符的最大数量。一旦这个常量在内核中设置为某个值比如1024那么系统级别的文件描述符总数就会受到这个限制。
用户进程可以通过 RLIMIT_NOFILE 这个资源限制来控制其自身可以打开的文件描述符数量。这个限制是针对每个进程的与 NR_OPEN 不同它影响的是单个进程的能力而不是整个系统。
如果 NR_OPEN 被设置为 1024这意味着整个系统在任何时刻都不会超过 1024 个打开的文件描述符。但是每个单独的进程可以通过 RLIMIT_NOFILE 设置自己的最大文件描述符数量。默认情况下如果不显式设置RLIMIT_NOFILE 的值通常会比较大远超过 NR_OPEN 的设置允许进程在其自身的限制内操作。
因此即使 NR_OPEN 设置为 1024用户进程仍然可以通过设置适当的 RLIMIT_NOFILE 来打开更多的文件描述符只要它们不超过其自身的限制。这种设置允许操作系统在系统级别保持资源的控制同时让每个进程有足够的灵活性来管理自己的资源使用。
在设置和检查文件描述符时内核会结合这几个参数来确保资源使用在合理范围内。例如当一个进程请求打开新的文件描述符时内核会检查 RLIMIT_NOFILE 和 nr_open同时在全局范围内检查是否超过 file-max。
通过这些参数的组合Linux 内核能够灵活而有效地管理文件描述符资源确保系统稳定和高效运行。