Jos*_*ain 3 sockets linux file-descriptor
我在C/linux中有一个套接字服务器.每次我创建一个新套接字时,都会为其分配一个文件描述符.我想将这些FD用作每个客户端的唯一ID.如果保证它们总是按递增顺序分配(我正在运行的Ubuntu就是这种情况)那么我可以将它们用作数组索引.
所以问题是:从linux套接字分配的文件描述符是否始终保持递增顺序?
小智 5
让我们看看它是如何在内部工作的(我正在使用内核4.1.20).在Linux中分配文件描述符的方式是使用__alloc_fd.当您执行打开的系统调用时,将调用do_sys_open.此例程从get_unused_fd_flags获取一个空闲文件描述符:
long do_sys_open(int dfd, const char __user *filename, int flags, umode_t mode)
{
...
fd = get_unused_fd_flags(flags);
if (fd >= 0) {
struct file *f = do_filp_open(dfd, tmp, &op);
Run Code Online (Sandbox Code Playgroud)
get_unused_d_flags调用__alloc_fd设置最小和最大fd:
int get_unused_fd_flags(unsigned flags)
{
return __alloc_fd(current->files, 0, rlimit(RLIMIT_NOFILE), flags);
}
Run Code Online (Sandbox Code Playgroud)
__alloc_fd获取进程的文件描述符表,并将fd作为next_fd获取,该实际上是从上一次运行时设置的:
int __alloc_fd(struct files_struct *files,
unsigned start, unsigned end, unsigned flags)
{
...
fd = files->next_fd;
...
if (start <= files->next_fd)
files->next_fd = fd + 1;
Run Code Online (Sandbox Code Playgroud)
所以你可以看到文件描述符的确是单调增长的......直到某一点.当fd达到最大值时,__ alloc_fd将尝试查找最小的未使用文件描述符:
if (fd < fdt->max_fds)
fd = find_next_zero_bit(fdt->open_fds, fdt->max_fds, fd);
Run Code Online (Sandbox Code Playgroud)
此时,文件描述符将不再单调增长,而是跳转尝试查找空闲文件描述符.在此之后,如果表格已满,它将被展开:
error = expand_files(files, fd);
Run Code Online (Sandbox Code Playgroud)
在这一点上,他们将再次单调地增长.
希望这可以帮助
FD 在套接字的生命周期内保证是唯一的。所以,是的,理论上,您可以使用 FD 作为客户端数组的索引。不过,我至少出于以下几个原因对此提出警告:
正如已经说过的,不能保证FD会被单调分配。Accept() 有权返回一个高编号的 FD,这会使你的数组效率低下。对你的问题的简短回答:不,它们不能保证是单调的。
您的服务器可能最终会出现许多其他打开的 FD - stdin、stdout 和 stderr 仅举三个 - 因此,您的阵列又浪费了空间。
我建议使用其他一些从 FD 映射到客户端的方法。事实上,除非您要与数千个客户打交道,否则搜索客户列表应该没问题 - 这实际上并不是您需要执行大量操作的操作。
| 归档时间: |
|
| 查看次数: |
3307 次 |
| 最近记录: |