it-swarm.com.de

Bash-Fork: Wiederholung: Ressource vorübergehend nicht verfügbar

Ich versuche, ein Shell-Skript auszuführen, das einen Prozess mithilfe eines Shell-Skripts erstellt. Ich erhalte den vorübergehend nicht verfügbaren Fehler "Ressource". wie man erkennt, welches Limit (Speicher/Prozess/Dateianzahl) dieses Problem verursacht. Unten sind meine ulimit -a Ergebnisse.

core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 563959
max locked memory       (kbytes, -l) unlimited
max memory size         (kbytes, -m) unlimited
open files                      (-n) 65535
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) unlimited
cpu time               (seconds, -t) unlimited
max user processes              (-u) 10000000
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited
4
Viswanath

Für den Fall in den Kommentaren, dass Sie nicht viel Speicher pro Thread verwendet haben, haben Sie die Grenzwerte für cgroup überschritten. Der Standardwert liegt bei 12288, der Wert ist jedoch beschreibbar:

$ cat /sys/fs/cgroup/pids/user.slice/user-1000.slice/pids.max
12288
$ echo 15000 | Sudo tee /sys/fs/cgroup/pids/user.slice/user-1000.slice/pids.max
15000
$ cat /sys/fs/cgroup/pids/user.slice/user-1000.slice/pids.max
15000

Und wenn ich mein "what is the thread limit" -Programm (gefunden hier ) benutze, um vorher zu überprüfen:

$ ./thread-limit
Creating threads ...
100 threads so far ...
200 threads so far ...
...
12100 threads so far ...
12200 threads so far ...
Failed with return code 11 creating thread 12281 (Resource temporarily unavailable).
Malloc worked, hmmm

und danach:

$ ./thread-limit
Creating threads ...
100 threads so far ...
200 threads so far ...
300 threads so far ...
...
14700 threads so far ...
14800 threads so far ...
14900 threads so far ...
Failed with return code 11 creating thread 14993 (Resource temporarily unavailable).
Malloc worked, hmmm

Die obigen Zahlen sind natürlich nicht genau, da auf dem "Doug" -Benutzer noch einige andere Threads ausgeführt werden, z. B. meine SSH-Sitzungen mit meinem Server. Erkundigen Sie sich bei:

$ cat /sys/fs/cgroup/pids/user.slice/user-1000.slice/pids.current
8

Verwendetes Programm:

/* compile with:   gcc -pthread -o thread-limit thread-limit.c */
/* originally from: http://www.volano.com/linuxnotes.html */

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <string.h>

#define MAX_THREADS 100000
#define PTHREAD_STACK_MIN 1*1024*1024*1024
int i;

void run(void) {
  sleep(60 * 60);
}

int main(int argc, char *argv[]) {
  int rc = 0;
  pthread_t thread[MAX_THREADS];
  pthread_attr_t thread_attr;

  pthread_attr_init(&thread_attr);
  pthread_attr_setstacksize(&thread_attr, PTHREAD_STACK_MIN);

  printf("Creating threads ...\n");
  for (i = 0; i < MAX_THREADS && rc == 0; i++) {
    rc = pthread_create(&(thread[i]), &thread_attr, (void *) &run, NULL);
    if (rc == 0) {
      pthread_detach(thread[i]);
      if ((i + 1) % 100 == 0)
    printf("%i threads so far ...\n", i + 1);
    }
    else
    {
      printf("Failed with return code %i creating thread %i (%s).\n",
         rc, i + 1, strerror(rc));

      // can we allocate memory?
      char *block = NULL;
      block = malloc(65545);
      if(block == NULL)
        printf("Malloc failed too :( \n");
      else
        printf("Malloc worked, hmmm\n");
    }
  }
sleep(60*60); // ctrl+c to exit; makes it easier to see mem use
  exit(0);
}

Siehe auch hier

Wenn Sie nun über genügend Speicher verfügen, wird der nächste Grenzwert durch die maximale Standard-PID-Nummer definiert, die 32768 beträgt, die jedoch auch beschreibbar ist. Obvioulsy, um mehr als 32768 gleichzeitige Prozesse oder Aufgaben oder Threads zu haben, muss ihre PID höher sein dürfen:

$ cat /proc/sys/kernel/pid_max
32768
$ echo 80000 | Sudo tee /proc/sys/kernel/pid_max
80000
$ cat /proc/sys/kernel/pid_max
80000

Beachten Sie, dass absichtlich eine Zahl größer als 2 ** 16 gewählt wurde, um zu prüfen, ob dies tatsächlich zulässig war. Und so setzen Sie nun die cgroup max auf 70000:

$ echo 70000 | Sudo tee /sys/fs/cgroup/pids/user.slice/user-1000.slice/pids.max
70000
$ cat /sys/fs/cgroup/pids/user.slice/user-1000.slice/pids.max
70000

Beachten Sie an dieser Stelle, dass das oben aufgeführte Programm anscheinend ein Limit von 32768 Threads aufweist, auch wenn noch Ressourcen verfügbar sind, und wenden Sie daher eine andere Methode an. Mein Testserver mit 16 Gigabyte Speicher scheint bei etwa 62344 Aufgaben eine andere Ressource zu erschöpfen, obwohl noch Speicher verfügbar zu sein scheint.

$ cat /sys/fs/cgroup/pids/user.slice/user-1000.slice/pids.current
62344

oben:

top - 13:48:26 up 21:08,  4 users,  load average: 281.52, 134.90, 70.93
Tasks: 62535 total, 201 running, 62334 sleeping,   0 stopped,   0 zombie
%Cpu0  : 96.6 us,  2.4 sy,  0.0 ni,  1.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu1  : 95.7 us,  2.4 sy,  0.0 ni,  1.9 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu2  : 95.1 us,  3.1 sy,  0.0 ni,  1.8 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu3  : 93.5 us,  4.6 sy,  0.0 ni,  1.9 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu4  : 94.8 us,  3.4 sy,  0.0 ni,  1.8 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu5  : 95.5 us,  2.6 sy,  0.0 ni,  1.9 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu6  : 94.7 us,  3.5 sy,  0.0 ni,  1.9 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu7  : 93.8 us,  4.5 sy,  0.0 ni,  1.7 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem : 15999116 total,   758684 free, 10344908 used,  4895524 buff/cache
KiB Swap: 16472060 total, 16470396 free,     1664 used.  4031160 avail Mem

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
37884 doug      20   0  108052  68920   3104 R   5.7  0.4   1:23.08 top
24075 doug      20   0    4360    652    576 S   0.4  0.0   0:00.31 consume
26006 doug      20   0    4360    796    720 S   0.4  0.0   0:00.09 consume
30062 doug      20   0    4360    732    656 S   0.4  0.0   0:00.17 consume
21009 doug      20   0    4360    748    672 S   0.3  0.0   0:00.26 consume

Scheint, als hätte ich endlich meine Standardeinstellungen für ulimit getroffen, sowohl für Benutzerprozesse als auch für die Anzahl der Timer (Signale):

$ ulimit -i
62340
[email protected]:~$ ulimit -a
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 62340
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 32768
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) 62340
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

Wenn ich diese Grenzen anhebe, kann ich auf 69000 Threads zugreifen, was alles ist, wonach ich gefragt habe und wie weit ich gehen werde, um diese Antwort zu erhalten:

$ cat /sys/fs/cgroup/pids/user.slice/user-1000.slice/pids.current
69011

oben:

top - 16:39:43 up 33 min,  3 users,  load average: 314.59, 181.48, 105.27
Tasks: 69205 total, 234 running, 68971 sleeping,   0 stopped,   0 zombie
%Cpu(s): 93.7 us,  5.5 sy,  0.0 ni,  0.8 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem : 15999004 total,  2659452 free, 11393940 used,  1945612 buff/cache
KiB Swap: 16472060 total, 16472060 free,        0 used.  2866316 avail Mem

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
 4166 doug      20   0  115408  75956   3252 R   5.1  0.5   1:30.52 top
62667 doug      20   0   28916   1516   1320 R   3.7  0.0   0:01.14 ps
73184 doug      20   0    7196   4396   1600 S   0.9  0.0   0:09.95 try_stuff5
 2038 doug      20   0    4360    652    576 S   0.4  0.0   0:00.34 consume
 4594 doug      20   0    4360    652    580 S   0.4  0.0   0:00.14 consume
 5435 doug      20   0    4360    652    576 S   0.4  0.0   0:00.24 consume
 8891 doug      20   0    4360    688    612 S   0.4  0.0   0:00.14 consume

Irgendwann werden Sie in Schwierigkeiten geraten, aber es ist absolut erstaunlich, wie anmutig das System ins Stocken gerät. Ich habe 118000 Threads ausprobiert und das System ist total blockiert, und ich hatte viele dieser Fehler:

Feb 17 16:13:02 s15 kernel: [  967.907305] INFO: task waiter:119371 blocked for more than 120 seconds.
Feb 17 16:13:02 s15 kernel: [  967.907335]       Not tainted 4.10.0-rc8-stock #194
Feb 17 16:13:02 s15 kernel: [  967.907357] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.

Und meine durchschnittliche Auslastung stieg auf ~ 29000. Aber ich habe den Computer gerade für eine Stunde verlassen und es hat sich von selbst erledigt. Ich habe den Spin-Out der Threads um 200 Mikrosekunden pro Spin-Out gestaffelt und konnte dann 118000 Threads problemlos ausführen (zugegebenermaßen bei sehr geringem Ressourcenverbrauch pro Thread).

7
Doug Smythies