web-dev-qa-db-fra.com

Augmentez la taille de la pile sous Linux avec setrlimit

en lisant des informations sur la façon d'augmenter la taille de la pile pour une application c ++ compilée avec gnu, au moment de la compilation, j'ai compris que cela peut être fait avec setrlimit au début du programme. Néanmoins, je n'ai pas pu trouver d'exemple réussi sur la façon de l'utiliser et dans quelle partie du programme l'appliquer afin d'obtenir une taille de pile de 64 Mo pour un programme c ++, quelqu'un pourrait-il m'aider?

Merci

21
asdf

Normalement, vous devez définir la taille de pile au début, e, g, au début de main(), avant d'appeler toute autre fonction. Typiquement, la logique serait:

  • appeler getrlimit pour obtenir la taille actuelle de la pile
  • si la taille actuelle <la taille de pile requise, alors
    • appeler setrlimit pour augmenter la taille de la pile à la taille requise

En C, cela pourrait être codé quelque chose comme ceci:

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

int main (int argc, char **argv)
{
    const rlim_t kStackSize = 64L * 1024L * 1024L;   // min stack size = 64 Mb
    struct rlimit rl;
    int result;

    result = getrlimit(RLIMIT_STACK, &rl);
    if (result == 0)
    {
        if (rl.rlim_cur < kStackSize)
        {
            rl.rlim_cur = kStackSize;
            result = setrlimit(RLIMIT_STACK, &rl);
            if (result != 0)
            {
                fprintf(stderr, "setrlimit returned result = %d\n", result);
            }
        }
    }

    // ...

    return 0;
}
20
Paul R

Vérifiez si le maximum d'exécution à l'exécution le limite:

[wally@zf conf]$  ulimit -all
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 16114
max locked memory       (kbytes, -l) 32
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1024
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 10240
cpu time               (seconds, -t) unlimited
max user processes              (-u) 16114
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

Notez que la taille de la pile, par défaut, est limitée à 10 Mo. Donc pour l'augmenter à 64 Mio:

[wally@zf conf]$ ulimit -s 64M
-bash: ulimit: 64M: invalid number
[wally@zf conf]$ ulimit -s 65536
[wally@zf conf]$ ulimit -all
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 16114
max locked memory       (kbytes, -l) 32
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1024
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 65536
cpu time               (seconds, -t) unlimited
max user processes              (-u) 16114
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited
11
wallyk

Pour dépasser la limite stricte de setrlimit (sur OSX, ses 64 Mo par défaut uniquement), créez un nouveau thread à l'aide de pthreads avec une taille de pile de votre choix. Voici un extrait C:

    // Call function f with a 256MB stack.
    static int bigstack(void *(*f)(void *), void* userdata) {

      pthread_t thread;
      pthread_attr_t attr;

      // allocate a 256MB region for the stack.
      size_t stacksize = 256*1024*1024;
      pthread_attr_init(&attr);
      pthread_attr_setstacksize(&attr, stacksize);

      int rc = pthread_create(&thread, &attr, f, userdata);
      if (rc){
        printf("ERROR: return code from pthread_create() is %d\n", rc);
        return 0;
      }
      pthread_join(thread, NULL);
      return 1;

    }
4
Taylor