Límite creciente de FD_SETSIZE y seleccione

7 minutos de lectura

avatar de usuario
vivek goel

Quiero aumentar el valor de la macro FD_SETSIZE para mi sistema. ¿Hay alguna forma de aumentar FD_SETSIZE para que la selección no falle?

  • si, en mi caso lo necesito sobre 2048. ¿Hay alguna forma de configurarlo?

    – Vivek Goel

    2 de noviembre de 2011 a las 6:07

  • porque quiero aumentar el límite de mi servidor para admitir esa gran cantidad de conexión.

    – Vivek Goel

    2 de noviembre de 2011 a las 6:55

  • Sin ofender, pero pensando en aumentar FD_SETSIZE es una cosa bastante tonta que hacer. 2048 conexiones simultáneas (o más bien, más que eso) está dentro del rango donde epoll_wait supera ampliamente a ambos select y poll simplemente porque no necesita copia 8 kilobytes de datos cada vez y no necesita iterar más de dos mil descriptores cada vez.

    – Damon

    30 de agosto de 2013 a las 13:22


  • La respuesta real es: NO, no bajo Linux. Para BSD y Windows es posible redefinir FD_SETSIZE. Intentar hacerlo requiere piratería y seguramente conducirá a un problema futuro. Por lo tanto, prefiera el uso de la encuesta siempre que el valor máximo del descriptor pueda ser superior a 1024.

    – philippe lhardy

    15 de diciembre de 2013 a las 21:08

avatar de usuario
R.. GitHub DEJAR DE AYUDAR A ICE

Según los estándares, no hay forma de aumentar FD_SETSIZE. Algunos programas y bibliotecas (me viene a la mente libevent) intentan solucionar esto asignando espacio adicional para el fd_set objeto y pasando valores mayores que FD_SETSIZE al FD_* macros, pero esta es una muy mala idea ya que las implementaciones robustas pueden realizar una verificación de límites en el argumento y cancelar si está fuera de rango.

Tengo una solución alternativa que siempre debería funcionar (aunque los estándares no lo exigen). en lugar de un solo fd_set objeto, asigne una matriz de ellos lo suficientemente grande como para contener el fd máximo que necesitará, luego use FD_SET(fd%FD_SETSIZE, &fds_array[fd/FD_SETSIZE]) etc. para acceder al conjunto.

  • @dns: Esa es documentación falsa. 🙂 Por favor lee pubs.opengroup.org/onlinepubs/9699919799/functions/pselect.html. De acuerdo, bromas aparte, explique lo que cree que es “falso” sobre mi respuesta.

    – R.. GitHub DEJA DE AYUDAR A ICE

    14 mayo 2013 a las 14:15


  • según Microsoft, “Según los estándares, no hay forma de aumentar FD_SETSIZE” es falso porque y estoy citando palabra por palabra de Microsoft: “Este valor se usa para construir las estructuras fd_set utilizadas en select(). El valor predeterminado El valor en WINSOCK.H es 64. Si una aplicación está diseñada para poder trabajar con más de 64 sockets, defina el manifiesto FD_SETSIZE en cada archivo fuente antes de incluir WINSOCK.H”. por favor lee support.microsoft.com/kb/111855

    – Brier May

    11/08/2013 a las 23:30


  • bien, entonces, para ajustarse a los “estándares”, también puede aumentarlo en las variantes de Linux/unix/mac simplemente cambiando #define __FD_SETSIZE 1024 los siguientes 2 archivos /usr/include/bits/typesizes.h /usr/include/linux /posix_types.h, sin embargo, declaró que no puede aumentarlo y que puede, de cualquier manera, la respuesta es falsa

    – Brier May

    13 de agosto de 2013 a las 17:37

  • Eso tampoco es estándar. Ese es un truco específico de la implementación. Estoy de acuerdo en que en muchas implementaciones puede hacer un truco específico de implementaciones de esta forma, pero no es correcto según los estándares.

    – R.. GitHub DEJA DE AYUDAR A ICE

    13 de agosto de 2013 a las 17:41

  • @AndrewHacking: ¿Cuándo se cansará la gente de publicar comentarios erróneos sobre esto? Sí, algunas implementaciones lo permiten. No, no es válido según la especificación de la interfaz. El texto relevante es…

    – R.. GitHub DEJA DE AYUDAR A ICE

    9 de septiembre de 2014 a las 15:03

También sugiero usar poll si es posible. Y existen varias bibliotecas de procesamiento de “eventos” como evento libre o libre (o las habilidades de evento de Fácil de GTK, o QtCore, etc.) que deberían ayudarte. También hay cosas como encuesta. Y tu problema está relacionado con C10k

  • si. Creo que esta es la respuesta definitiva. Si uno de sus descriptores monitoreados cae por encima de 1024 en Linux, tiene que HACKEAR a través de la estructura fd_set (y correr el riesgo de tener más problemas de todos modos), o usar sondear lo que es… mejor.

    – philippe lhardy

    15 de diciembre de 2013 a las 21:11

  • Y tienes que rezar para que cada biblioteca que uses lo haga correctamente. La única solución que funciona para vivir con identificadores 1024 o comprender al 100 % el código de sus programas, incluidas todas las bibliotecas, y asegurarse de que nunca se use “seleccionar”.

    – Lotario

    24 de noviembre de 2019 a las 15:14

Sería mejor (y fácil) reemplazarlo con poll. En general, poll() es un simple reemplazo directo de select() y no está limitado por el 1024 de FD_SETSIZE…

fd_set fd_read;
int id = 42;
FD_ZERO(fd_read);
FD_SET(id, &fd_read);
struct timeval tv;
tv.tv_sec = 5;
tv.tv_usec = 0;
if (select(id + 1, &fd_read, NULL, NULL, &tv) != 1) {
   // Error.
}

se convierte en:

struct pollfd pfd_read;
int id = 42;
int timeout = 5000;
pfd_read.fd = id;
pfd_read.events = POLLIN;
if (poll(&pfd_read, 1, timeout) != 1) {
   // Error
}

Debe incluir poll.h para la estructura pollfd.

Si necesita escribir además de leer, configure el indicador de eventos como POLLIN | ENCUENTRO.

avatar de usuario
mpromonet

Para usar un fd_set mayor que FD_SETSIZE, es posible definir uno extendido como este:

#include <sys/select.h>
#include <stdio.h>

#define EXT_FD_SETSIZE 2048
typedef struct
{
    long __fds_bits[EXT_FD_SETSIZE / 8 / sizeof(long)];
} ext_fd_set;

int main()
{
    ext_fd_set fd;
    int s;
    printf("FD_SETSIZE:%d sizeof(fd):%ld\n", EXT_FD_SETSIZE, sizeof(fd));
    FD_ZERO(&fd);
    while ( ((s=dup(0)) != -1) && (s < EXT_FD_SETSIZE) )
    {
        FD_SET(s, &fd);
    }
    printf("select:%d\n", select(EXT_FD_SETSIZE,(fd_set*)&fd, NULL, NULL, NULL));
    return 0;
}

Esto imprime:

FD_SETSIZE:2048 tamaño de(fd):256

seleccione: 2045


Para abrir más de 1024 descriptores de archivos, es necesario aumentar el límite usando, por ejemplo, ulimit -n 2048.

avatar de usuario
Briermayo

en realidad hay ES una forma de aumentar FD_SETSIZE en Windows se define en winsock.h y según Microsoft, puede aumentarlo simplemente definiéndolo ANTES de incluir winsock.h:

Ver Número máximo de sockets que puede usar una aplicación (enlace antiguo), o la página más reciente Número máximo de sockets admitidos.

Lo hago todo el tiempo y no he tenido problemas. El valor más grande que he usado fue alrededor de 5000 para un servidor que estaba desarrollando.

  • BSD y Windows permiten configurar FD_SETSIZE. No en Linux, donde el tamaño interno de fd_set está configurado por __FD_SETSIZE que está codificado en 1024. Para Linux, es mejor usar la encuesta ya que slecet no puede funcionar para más de los primeros 1024 descriptores. de hecho, puede parecer que funciona en Linux, pero usará bits fuera del fd_set asignado, lo que seguramente corromperá la pila y causará bloqueos. Es por eso que la respuesta actual es asignarse más lugar en la pila a lo que no es muy bonito.

    – philippe lhardy

    15 de diciembre de 2013 a las 21:02

  • La pregunta trata sobre Linux, no sobre Windows.

    – promomonet

    10 de enero de 2015 a las 14:18

  • También se menciona aquí: docs.microsoft.com/en-us/windows/win32/api/winsock2/… (ctrl+f ‘FD_SETSIZE’)

    – Tomás

    25 de junio de 2021 a las 12:12


  • BSD y Windows permiten configurar FD_SETSIZE. No en Linux, donde el tamaño interno de fd_set está configurado por __FD_SETSIZE que está codificado en 1024. Para Linux, es mejor usar la encuesta ya que slecet no puede funcionar para más de los primeros 1024 descriptores. de hecho, puede parecer que funciona en Linux, pero usará bits fuera del fd_set asignado, lo que seguramente corromperá la pila y causará bloqueos. Es por eso que la respuesta actual es asignarse más lugar en la pila a lo que no es muy bonito.

    – philippe lhardy

    15 de diciembre de 2013 a las 21:02

  • La pregunta trata sobre Linux, no sobre Windows.

    – promomonet

    10 de enero de 2015 a las 14:18

  • También se menciona aquí: docs.microsoft.com/en-us/windows/win32/api/winsock2/… (ctrl+f ‘FD_SETSIZE’)

    – Tomás

    25 de junio de 2021 a las 12:12


¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad