Ich hatte dieses Problem auch. Sie haben ein Dateihandle-Leck. Sie können dies debuggen, indem Sie eine Liste aller geöffneten Datei-Handles Ausdrucken (auf POSIX-Systemen):
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 << ") ";
}
}
Durch alle geöffneten Dateien Dumping aus Sie schnell wird herausfinden, wo Ihre Datei Handle-Leck ist.
Wenn Ihr Server Subprozesse hervorbringt. Z.B. Wenn es sich um einen Server im Fork-Stil handelt oder wenn Sie andere Prozesse generieren (z. B. über CGI), müssen Sie sicherstellen, dass Sie Ihre Datei-Handles mit "cloexec" erstellen - sowohl für echte Dateien als auch für Sockets.
Ohne Cloexec werden bei jedem Fork- oder Spawn-Aufruf alle geöffneten Dateizugriffsnummern im untergeordneten Prozess geklont.
Es ist auch sehr einfach zu versäumen, Netzwerk-Sockets zu schließen - z. Verlassen Sie sie einfach, wenn der Remote-Teilnehmer die Verbindung trennt. Dies wird Griffe wie verrückt auslaufen lassen.
Ich bearbeite /etc/security/limits.conf mit: – linjunhalida
Benutzername HardNofile 20000 – linjunhalida