Почему EAGAIN в pthread_key_create происходит? - PullRequest
0 голосов
/ 29 апреля 2019

Иногда, когда я пытаюсь создать ключ с pthread_key_create, я получаю код ошибки EAGAIN. Можно ли точно знать, почему?

Документация гласит:

Системе не хватало ресурсов, необходимых для создания другого ключа данных, специфичного для потока, или было бы превышено установленное системой ограничение на общее количество ключей на процесс [PTHREAD_KEYS_MAX].

Как проверить, был ли предел для ключей? Может быть, какой-нибудь инструмент контроля короля проверяет, сколько ключей уже открыто в системе и сколько еще можно использовать?

Одна важная вещь в нашем коде: мы используем fork() и выполняем несколько процессов. И каждый процесс может иметь несколько потоков.

Я обнаружил, что у нас нет независимого ограничения для ключей потоков, когда мы используем fork(). Вот небольшой пример.

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

size_t create_keys(pthread_key_t *keys, size_t number_of_keys)
{
    size_t counter = 0;
    for (size_t i = 0; i < number_of_keys; i++)
    {
        int e = pthread_key_create(keys + i, NULL);
        if (e)
        {
            printf("ERROR (%d): index: %ld, pthread_key_create (%d)\n", getpid(), i, e);
            break;
        }
        counter++;
    }

    return counter;
}

int main(int argc, char const *argv[])
{
    printf("maximim number of thread keys: %ld\n", sysconf(_SC_THREAD_KEYS_MAX));

    printf("process id: %d\n", getpid());

    const size_t number_of_keys = 1024;

    pthread_key_t keys_1[number_of_keys];
    memset(keys_1, 0, number_of_keys * sizeof(pthread_key_t));

    printf("INFO (%d): number of active keys: %ld\n", getpid(), create_keys(keys_1, number_of_keys));

    pid_t p = fork();
    if (p == 0)
    {
        printf("process id: %d\n", getpid());

        pthread_key_t keys_2[number_of_keys];
        memset(keys_2, 0, number_of_keys * sizeof(pthread_key_t));

        printf("INFO (%d): number of active keys: %ld\n", getpid(), create_keys(keys_2, number_of_keys));
    }

    return 0;
}

Когда я запускаю этот пример в Ubuntu 16.04, я вижу, что дочерний процесс не может создать новый ключ потока, если я использую то же количество ключей, что и ограничение (1024). Но если я использую 512 ключей для родительских и дочерних процессов, я могу запустить их без ошибок.

1 Ответ

0 голосов
/ 29 апреля 2019

Максимальное значение:

#include <unistd.h>
#include <stdio.h>

int main ()
{
  printf ("%ld\n", sysconf(_SC_THREAD_KEYS_MAX));
  return 0;
}

Рассмотрите возможность использования pthread_key_delete.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...