Augmentation de la limite de FD SETSIZE et select

je veux augmenter la valeur de la macro fd_setsize pour mon système. Est-il possible d'augmenter FD_SETSIZE choisissez donc ne manquera pas

14
demandé sur mpromonet 2011-11-02 10:02:50

5 réponses

Par les normes, il n'y a aucun moyen d'augmenter FD_SETSIZE . Certains programmes et bibliothèques (libevent vient à l'esprit) tentent de contourner ce problème en allouant de l'espace supplémentaire pour l'objet fd_set et en passant des valeurs plus grandes que FD_SETSIZE aux macros FD_* , mais c'est une très mauvaise idée car des implémentations robustes peuvent effectuer une vérification des limites de l'argument et avorter si c'est hors de portée.

j'ai une solution alternative qui devrait toujours travail (même si ce n'est pas obligatoire selon les normes). Au lieu d'un seul objet fd_set , attribuez-en un tableau assez grand pour contenir le FD max dont vous aurez besoin, puis utilisez FD_SET(fd%FD_SETSIZE, &fds_array[fd/FD_SETSIZE]) etc. pour accéder à l'ensemble.

11
répondu R.. 2011-11-02 07:16:14

je suggère aussi d'utiliser poll si possible. Et il existe plusieurs bibliothèques de traitement d '" événements "comme libevent ou libev (ou les capacités d'événements de Glib de GTK, ou QtCore , etc) qui devraient vous aider. Il y a aussi des choses comme epoll . Et votre problème est lié à C10k

12
répondu Basile Starynkevitch 2011-11-02 07:39:58

il serait préférable (et facile) de le remplacer par poll. Généralement, poll() est un simple drop-in pour remplacer select () et n'est pas limité par le 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.
}

devient:

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
}

vous devez inclure le sondage.h pour la structure pollfd.

si vous avez besoin d'écrire aussi bien que de lire, mettez le drapeau events comme POLLIN | POLLOUT.

8
répondu Simon Gymer 2014-11-21 16:01:45

il est possible d'augmenter FD_SETSIZE overiding __FD_SETSIZE (défini dans sys/types.h ) avant d'inclure sys/select.h .

si on procède comme ça on peut mettre FD_SETSIZE à 2048 :

#include <sys/types.h>
#undef __FD_SETSIZE
#define __FD_SETSIZE 2048
#include <sys/select.h>
#include <stdio.h>

int main()
{
    printf("FD_SETSIZE:%d sizeof(fd_set):%d\n",FD_SETSIZE,sizeof(fd_set));
    return 0;
}

affichera:

FD_SETSIZE: 2048 sizeof (fd_set): 128

cependant si la valeur FD_SETSIZE suit la valeur modifiée, sizeof (fd_set) doit être 256 (2048/8) et non 128 (1024/8). C'est parce que l'inclusion de sys/types.h définit déjà fd_set avec 1024.


afin d'utiliser un plus grand fd_set , il est possible de définir une étendue comme ceci :

#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;
}

Cette affiche :

FD_SETSIZE: 2048 sizeof (fd): 256

sélectionner: 2045


Afin d'ouvrir plus de 1024 graveurs de fichiers, il est nécessaire d'augmenter la limite en utilisant par exemple ulimit -n 2048 .
6
répondu mpromonet 2016-06-21 19:58:46

en fait, il est une façon d'augmenter FD_SETSIZE sous windows. son défini dans winsock.h et par microsoft eux-mêmes vous pouvez l'augmenter en le définissant simplement avant que vous incluez winsock.h

http://support.microsoft.com/kb/111855

je le fais tout le temps et n'ai eu aucun problème la plus grande valeur que j'ai utilisée était d'environ 5000 pour un serveur que je développais

1
répondu BrierMay 2013-02-18 03:58:50