Tuve este problema también. Tiene una fuga de identificador de archivo. Puede depurar esta imprimiendo una lista de todos los identificadores de archivos abiertos (en sistemas POSIX):
void showFDInfo()
{
s32 numHandles = getdtablesize();
for (s32 i = 0; i < numHandles; i++)
{
s32 fd_flags = fcntl(i, F_GETFD);
if (fd_flags == -1) continue;
showFDInfo(i);
}
}
void showFDInfo(s32 fd)
{
char buf[256];
s32 fd_flags = fcntl(fd, F_GETFD);
if (fd_flags == -1) return;
s32 fl_flags = fcntl(fd, F_GETFL);
if (fl_flags == -1) return;
char path[256];
sprintf(path, "/proc/self/fd/%d", fd);
memset(&buf[0], 0, 256);
ssize_t s = readlink(path, &buf[0], 256);
if (s == -1)
{
cerr << " (" << path << "): " << "not available";
return;
}
cerr << fd << " (" << buf << "): ";
if (fd_flags & FD_CLOEXEC) cerr << "cloexec ";
// file status
if (fl_flags & O_APPEND ) cerr << "append ";
if (fl_flags & O_NONBLOCK) cerr << "nonblock ";
// acc mode
if (fl_flags & O_RDONLY ) cerr << "read-only ";
if (fl_flags & O_RDWR ) cerr << "read-write ";
if (fl_flags & O_WRONLY ) cerr << "write-only ";
if (fl_flags & O_DSYNC ) cerr << "dsync ";
if (fl_flags & O_RSYNC ) cerr << "rsync ";
if (fl_flags & O_SYNC ) cerr << "sync ";
struct flock fl;
fl.l_type = F_WRLCK;
fl.l_whence = 0;
fl.l_start = 0;
fl.l_len = 0;
fcntl(fd, F_GETLK, &fl);
if (fl.l_type != F_UNLCK)
{
if (fl.l_type == F_WRLCK)
cerr << "write-locked";
else
cerr << "read-locked";
cerr << "(pid:" << fl.l_pid << ") ";
}
}
Por volcar todos los archivos abiertos se darán cuenta rápidamente donde su pérdida de identificador de archivo es.
Si su servidor genera subprocesos. P.ej. si se trata de un servidor de estilo "fork", o si está generando otros procesos (por ejemplo, a través de cgi), debe asegurarse de crear sus manejadores de archivo con "cloexec", tanto para los archivos reales como para los sockets.
Sin cloexec, cada vez que realiza un fork o spawn, todos los identificadores de archivos abiertos se clonan en el proceso secundario.
También es muy fácil cerrar las tomas de red, p. Ej. simplemente abandonándolos cuando la parte remota se desconecta. Esto se escapa maneja como loco.
Edito /etc/security/limits.conf con: – linjunhalida
nombre de usuario hard nofile 20000 – linjunhalida