精华内容
下载资源
问答
  • Linux select 文件描述符1024限制

    千次阅读 2016-11-15 14:25:07
    最后怀疑是文件描述符超过了1024。但是想到Apache也是采用select的io模型。所以还是很不理解。 查看了Linux的内核源码linux-2.6.32。 static __inline__ void __FD_SET(unsigned long fd, __kernel_fd_set *fdsetp...

    最近系统出现宕机的情况,分析core文件,所有的线程都在select处。

    最后怀疑是文件描述符超过了1024。但是想到Apache也是采用select的io模型。所以还是很不理解。

    查看了Linux的内核源码linux-2.6.32。

    static __inline__ void __FD_SET(unsigned long fd, __kernel_fd_set *fdsetp)
    {
        unsigned long _tmp = fd / __NFDBITS;
        unsigned long _rem = fd % __NFDBITS;
        fdsetp->fds_bits[_tmp] |= (1UL<<_rem);
    }

    #define __NFDBITS    (8 * sizeof(unsigned long))

    typedef struct {
        unsigned long fds_bits [__FDSET_LONGS];
    } __kernel_fd_set;

    #define __FDSET_LONGS   (__FD_SETSIZE/__NFDBITS)

    #define __FD_SETSIZE    1024

    起关键作用的就是红字部分。

    展开全文
  • 最近系统出现宕机的情况,分析core文件,所有的线程都在select...最后怀疑是文件描述符超过了1024。但是想到Apache也是采用select的io模型。所以还是很不理解。 查看了Linux的内核源码linux-2.6.32。 static __inli

              转载地址: http://blog.csdn.net/sxtobj/article/details/53170782


    最近系统出现宕机的情况,分析core文件,所有的线程都在select处。

    最后怀疑是文件描述符超过了1024。但是想到Apache也是采用select的io模型。所以还是很不理解。

    查看了Linux的内核源码linux-2.6.32。

    static __inline__ void __FD_SET(unsigned long fd, __kernel_fd_set *fdsetp)
    {
        unsigned long _tmp = fd / __NFDBITS;
        unsigned long _rem = fd % __NFDBITS;
        fdsetp->fds_bits[_tmp] |= (1UL<<_rem);
    }

    #define __NFDBITS    (8 * sizeof(unsigned long))

    typedef struct {
        unsigned long fds_bits [__FDSET_LONGS];
    } __kernel_fd_set;

    #define __FDSET_LONGS   (__FD_SETSIZE/__NFDBITS)

    #define __FD_SETSIZE    1024

    起关键作用的就是红字部分。




    展开全文
  • C/C++:Linux select 1024 文件描述符限制

    千次阅读 2019-07-02 13:58:30
    C/C++:Linux select 1024 文件描述符限制 通常来说,Linuxselect调用要求文件描述符的值小于1024,也就是说,fd set中的每个文件描述符的值域为:[0,1023]。 如果超过,Linuxselect调用会发生什么? 环境: ...

    C/C++:Linux select 1024 文件描述符限制

    通常来说,Linux下select调用要求文件描述符的值小于1024,也就是说,fd set中的每个文件描述符的值域为:[0,1023]。

    如果超过,Linux下select调用会发生什么?

    环境:

    [test1280@localhost ~]$ uname -a
    Linux localhost.localdomain 3.10.0-327.el7.x86_64 #1 SMP Thu Nov 19 22:10:57 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux
    

    方法:

    通过dup2生成指定数值的文件描述符,并将其与标准输入关联,select的读集合包含且只包含指定数值文件描述符。

    代码:

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <string.h>
    #include <errno.h>
    #include <sys/socket.h>
    
    int main(int argc, char *argv[])
    {
    	if (argc != 2)
    	{
    		fprintf(stderr, "usage: %s fd\n", argv[0]);
    		exit(1);
    	}
    
    	int fd = atoi(argv[1]);
    	if (fd < 3) // <0 0 1 2
    	{
    		fprintf(stderr, "fd domain: (2, fd_max]\n");
    		exit(1);
    	}
    
    	fprintf(stdout, "fd size: %d\n", FD_SETSIZE);
    
    	// 创建指定文件描述符,与标准输入关联
    	if (dup2(0, fd) == fd)
    	{
    		fprintf(stdout, "dup2 ok! new fd: %d\n", fd);
    	}
    	else
    	{
    		fprintf(stderr, "dup2 error: %d(%s)\n", errno, strerror(errno));
    		exit(1);
    	}
    
    	// 设为非阻塞
    	long flags = fcntl(fd, F_GETFL);	
    	fcntl(fd, F_SETFL, flags|O_NONBLOCK);
    
    	fprintf(stdout, "will into main loop...\n");
    
    	while (1)
    	{
    		fd_set readSet;
    		FD_ZERO(&readSet);
    		FD_SET(fd, &readSet);
    
    		struct timeval tv;
    		tv.tv_sec = 3;
    		tv.tv_usec = 0;
    
    		int res = select(fd + 1, &readSet, NULL, NULL, &tv);
    		if (res == -1) {
    			fprintf(stderr, "select error: %d(%s)\n", errno, strerror(errno));
    			exit(1);
    		} else if (res == 0) {
    			fprintf(stdout, "timeout...\n");
    		} else {
    			static char buff[1024];
    			int count = read(fd, buff, sizeof(buff));
    			fprintf(stdout, "select return %d, read count %d\n", res, count);
    		}
    	}
    
    	exit(0);
    }
    
    

    编译:

    [test1280@localhost ~]$ gcc -o main main.c -g -Wall
    

    运行:

    case 1(正常态):

    [test1280@localhost ~]$ ./main 10
    fd size: 1024
    dup2 ok! new fd: 10
    will into main loop...
    timeout...
    timeout...
    test1280timeout...
    
    select return 1, read count 9
    timeout...
    ^C
    

    case 2(异常态):

    [test1280@localhost ~]$ ./main 1280
    fd size: 1024
    dup2 ok! new fd: 1280
    will into main loop...
    select error: 9(Bad file descriptor)
    

    可读、可写、异常文件描述符集合包含大于1024的文件描述符时,执行select将返回EBADF错误。

    但是,并不总是这样的!

    在另一个程序中,将一个大于1024的FD加入到select可读监听集合执行select时,发生:

    此FD没有输入数据,不可读,select并没有等待指定的时间返回0,而是立刻返回一个正数指代存在可读FD。

    我没有能在以上的代码中复现这个问题。(以上代码执行select发现非法FD,直接返回EBADF错误)

    在网络上别人的博客中,曾出现过段错误的异常:

    https://my.oschina.net/u/1780368/blog/491863

    man 2 select:

    POSIX allows an implementation to define an upper limit, advertised
    via the constant FD_SETSIZE, on the range of file descriptors that
    can be specified in a file descriptor set. The Linux kernel imposes
    no fixed limit, but the glibc implementation makes fd_set a fixed-
    size type, with FD_SETSIZE defined as 1024, and the FD_*() macros
    operating according to that limit. To monitor file descriptors
    greater than 1023, use poll(2) instead.
    According to POSIX, select() should check all specified file
    descriptors in the three file descriptor sets, up to the limit
    nfds-1. However, the current implementation ignores any file
    descriptor in these sets that is greater than the maximum file
    descriptor number that the process currently has open. According to
    POSIX, any such file descriptor that is specified in one of the sets
    should result in the error EBADF.

    An fd_set is a fixed size buffer. Executing FD_CLR() or FD_SET()
    with a value of fd that is negative or is equal to or larger than
    FD_SETSIZE will result in undefined behavior.

    Although there are some ways to increase this limit (because of you’re using Linux, everything is possible), select() call can only listen 1024 file descriptor at the same time and all of the file descriptor number must be less than 1024.

    总结:

    1.select要求三个入参被监听集合的FD(取值)不超过1024;由此可推2、4:

    2.select要求三个入参被监听集合的FD(数量)不超过1024;

    3.若超过1024,执行select可能发生段错误,可能发生立刻返回不阻塞(以及错误的返回值结果),等等。

    4.即使select监听集合中只有一个FD,如果FD值大于1024,同样有问题。

    参考:

    1.https://linux-tips.com/t/is-it-possible-to-listen-file-descriptor-greater-than-1024-with-select/45
    2.https://my.oschina.net/u/1780368/blog/491863
    3.http://man7.org/linux/man-pages/man2/select.2.html
    4.http://bbs.chinaunix.net/thread-1791112-1-1.html
    5.https://blog.codingnow.com/2014/02/select_bug.html

    展开全文
  • 当然是在有输入或者输出时文件描述符的读写状态改变咯,比如标准输入的文件描述符是0,如果用select来等待0号文件描述符,那么当在键盘上敲字符时开始,就是文件描述符的读写状态改变之时,这时select函数就会返回;...

    当然是在有输入或者输出时文件描述符的读写状态改变咯,比如标准输入的文件描述符是0,如果用select来等待0号文件描述符,那么当在键盘上敲字符时开始,就是文件描述符的读写状态改变之时,这时select函数就会返回;对于套接字描述符来说也是这样,用select来等待一个服务器描述符,那么当有新的连接请求时(服务器描述符等待请求时是一个读描述符,当有新请求时实际上是有一个输入),服务器描述符的读写状态改变,select函数返回。顺便说一下,检查哪个文件描述符发生改变,可以用FD_ISSET宏来进行检测

    展开全文
  • 当某个程序打开文件时,操作系统返回相应的文件描述符,程序为了处理该文件必须引用此描述符。所谓的文件描述符是一个低级的正整数。最前面的三个文件描述符(0,1,2)分别与标准输入(stdin),标准输出(stdout)...
  • select文件描述符上限与1024的关系

    千次阅读 2020-05-28 00:41:11
    select中存放文件描述符的数组大小FD_SETSIZE为1024 进程的文件描述符上限默认是1024,正是因为这个原因,select设计时才把数组大小设计为1024 二、问题来了 进程的文件描述符上限是可以手动修改的 # 查看进程的...
  • 查看受计算机硬件限制的文件描述符上限 cat/vim /proc/sys/fs/file-max 通过配置文件修改文件上限值 vim /etc/security/limits.conf 在文件末尾添加两行如下代码,将文件上限值设为8000,该值不能超过步骤1得到的受...
  • linux文件描述符

    2014-09-14 21:44:01
    3、当创建进程时,通常默认会有3个文件描述符(0,1,2),0代表标准输入,1代表标准输出,2代表标准错误,它们统称为标准IO,所以如果进程通过open打开一个文件的时候,文件描述符会从3开始,fd的值其实就是进程中打开...
  • select、poll、epoll是三个常用的I/O复用,之前使用过程中一直没很深入思考,只知道①select文件描述符上限 ②poll是select的改进,去掉了文件描述符上限 ③epoll是前两者的增强版,也没有文件描述符上限 直到今天...
  • Linux中,内核利用文件描述符(File Descriptor)即文件句柄,来访问文件。文件描述符在形式上是一个非负整数。实际上,它是一个索引值,指向内核为每一个进程所维护的该进程打开文件的记录表。打开现存文件或新建...
  • select中存放文件描述符的数组大小FD_SETSIZE为1024 进程的文件描述符上限默认是1024,正是因为这个原因,select设计时才把数组大小设计为1024 二、问题来了 进程的文件描述符上限是可以手动修改的 # 查看进程的文件...
  • 文件描述符

    千次阅读 2017-01-18 22:42:18
    linux下一切皆文件,文件描述符是内核为了高效的管理已经被打开的文件所创建的索引,它是一个非负整数,用于指代被打开的文件,所有执行I/O操作的系统调用都是通过文件描述符完成的。 在linux中,进程是通过...
  • 一直不知道为什么select文件描述符限制是比较小的? 于是去查看内核5.6的版本,其中在/include/uapi/linux/posix_types.h有说明 /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _LINUX_...
  • Linux中,内核利用文件描述符(File Descriptor)即文件句柄,来访问文件。文件描述符是非负整数。打开现存文件或新建文件时,内核会返回一个文件描述符。读写文件也需要使用文件描述符来指定待读写的文件。宏FD_...
  • 大多数UNIX文件I/O只需用到5个函数open,read,write,lseek,close。当使用open或者create函数打开或创建一个新文件时,内核向进程返回一个文件描述符文件描述符是一个非负整数(也...UNIX/LINUX shell中,文件描述符0代
  • 表头文件 #include #include #include 定义函数 int select(int n,fd_set * readfds,fd_set * writefds,fd_set * exceptfds,struct timeval * timeout); 函数说明 select()用
  • 文件描述符&文件指针

    千次阅读 2017-01-19 17:43:05
     在linux操作系统中打开或者创建一个文件就会获得文件描述符,那仫什仫是文件描述符呢?我们知道在linux下一切皆文件,文件描述符是OS为了高效的管理已经被打开的文件所创建的一个索引,它是一个很小的正整数,所有...
  • Linux文件描述符Linux系统中几乎所有可读写的对象都可视为文件,比如标准输入输出、磁盘文件、套接字、管道等,都可以用read函数读取数据,用write函数写入数据。 这一点相对于Windows系统来说更加统一,在Windows...
  • select文件描述符集合 : fd_set

    千次阅读 2018-03-01 16:27:21
    在使用select时我们必定会使用到fd_set,那么fd_set究竟是什么呢? 一、fd_set的相关介绍 在网络编程中,经常用到selec系统调用来判断套接字上是否存在数据可读,或者能否向一个套接字写入数据。其原型为:  ...
  • 还是其他文件或命名管道或设备句柄)建立联系,建立联系的工作由程序员完成,当调用select()时,由内核根据IO状态修改fe_set的内容,由此来通知执行了select()的进程哪一socket或文件可读。  多端口复用函数select...
  • select系统调用原型如下:#include <sys/select.h> int select(int nfds, fd_set* readfds, fd_set* writefds, ...参数readfds, writefds, exceptfds参数分别指向可读、可写和异常事件对应的文件描述符集合。哪些情况下
  • linux文件描述符的介绍  (2012-10-02 16:01:56) 转载▼ 标签:  描述符   调用   返回   进程   限制   it 分类: linux 当某个程序打开文件时,...
  • 文件描述符和文件指针

    千次阅读 2017-05-07 11:38:32
    一、什么是文件描述符? 在linux系统中,“一切皆文件”所以设备也是以文件的形式存在的。对一个设备进行操作必须先打开这个文件,而打开这个文件就会用到文件描述符文件描述符是一个很小的正整数,每个进程在PCB...
  •       sudo vi /etc/security/limits.conf 在end of file前面加上这两句 * soft nofile 65536 * hard nofile 65536 保存退出即可            
  • 文件描述符以及file结构体

    千次阅读 2017-05-09 17:14:00
    一、什么是文件描述符Linux下一切皆文件,对于内核而言,所有打开的文件都通过文件描述符引用,文件描述符是一个非负整数,当打开一个现有文件或者创建一个新文件时,内核向进程返回一个文件描述符。当读、写一个...
  • Linux中,内核利用文件描述符(File Descriptor)即文件句柄,来访问文件。文件描述符是非负整数。打开现存文件或新建文件时,内核会返回一个文件描述符。读写文件也需要使用文件描述符来指定待读写的文件。宏FD_...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 52,648
精华内容 21,059
关键字:

linuxselect文件描述符

linux 订阅