Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux 为什么在pthread\u key\u create中出现EAGAIN?_Linux_Pthreads - Fatal编程技术网

Linux 为什么在pthread\u key\u create中出现EAGAIN?

Linux 为什么在pthread\u key\u create中出现EAGAIN?,linux,pthreads,Linux,Pthreads,有时,当我试图用pthread_key_create创建密钥时,我会得到一个EAGAIN错误代码。有可能知道确切的原因吗 文件说: 系统缺少创建另一个特定于线程的数据密钥所需的资源,或者系统对每个进程的密钥总数施加的限制[PTHREAD_keys_MAX]将被超过 如何检查这是否是钥匙的限制?也许有一种监控工具可以用来检查系统中已经打开了多少个键,还有多少可以使用 关于我们的代码,有一点很重要:我们使用fork并运行多个进程。每个进程可以有多个线程 我发现当我们使用fork时,线程键没有独立的限

有时,当我试图用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;
}
当我在Ubuntu16.04上运行这个例子时,我发现如果我使用与limit1024相同数量的键,子进程就不能创建任何新的线程键。但如果我对父进程和子进程使用512个键,我可以运行它而不会出错。

最大值:

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

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

考虑使用。

正如您所知,fork的工作方式通常是在内存中复制进程,然后作为父级和子级从每个副本中的同一点继续执行。这是fork的返回码所指示的

为了执行fork,必须复制流程的内部结构。内存、堆栈、打开的文件,可能还有线程本地存储密钥。每个系统的fork实现都不同。有些系统允许您自定义被复制的进程区域,请参见Linux clone2接口。然而,这个概念仍然是一样的


因此,请看示例代码:如果在父进程中分配1024个键,则每个子进程都会继承一个完整的键表,并且没有备用键可供使用,从而导致错误。如果在父级中仅分配512个键,则每个子级都会继承一个半空的键表,并有512个备用键可供使用,因此不会出现错误。

假设您指的是PTHREAD_keys_MAX,它在中定义。通过每次增加一个原子int,可以轻松跟踪调用pthread_key_create的次数,然后在得到错误后比较这两个值。但在我的系统上是1024。为什么要创建那么多不同的线程局部变量?似乎不对。显示你的代码;我敢打赌,您在尝试使用它们的过程中犯了一些错误。@Shawn是的,我们在Apache+fork中创建了许多进程,每个进程可能有许多线程。所以使用原子计数器不是一个好主意,因为我需要在所有进程中使用这样的计数器。嗯?进程的数量无关紧要;每个都有自己的一套钥匙。进程中的线程数也不重要;重要的是一个特定进程拥有的线程本地存储密钥的数量。对于特定于线程的数据的概念,您肯定有一些不理解的地方。显示一个。@Shawn我为fork创建了一个小示例,看起来进程的数量很重要。使用1024时,您的子进程不能再创建任何键,因为父进程在fork之前已经创建了最大数量的键。。。