如何修复调用 pthread_create 时偶尔出现的 EINVAL 错误

How to fix occasional EINVAL error when calling pthread_create

问题

当我使用下面的代码创建分离线程时,pthread_create 有时会 return EINVAL。我想知道为什么会发生这种情况以及我应该如何解决它。发生错误时,下面的代码将打印以下行:

Error creating thread. errno = 22: Invalid argument

我试过的

我只在 运行 我在 valgrind 中的代码时才观察到这个问题。即使这样,它有时也会产生此错误。因此,我倾向于认为时机是一个因素。我认为我没有竞争条件,因为此功能不依赖于任何共享数据。也许我对如何使用堆栈有疑问?除了 EINVAL 表示 "Invalid settings in 'attr'."

之外,我未能从手册页中找到任何有用的线索

我 运行 我在 Ubuntu 14.04 申请。

代码

/**
 * Creates a detached thread to receive data from the socket referred to by
 * sockfd.
 */
void recieve_async(int sockfd) {
    pthread_t receive_thread;
    pthread_attr_t attr;
    int error = pthread_attr_init(&attr);
    if (error != 0) {
        printf("attr_init failed. errno = %d: %s\n", error, strerror(error));
    }
    error = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
    if (error != 0) {
        printf("attr_setdetachstate failed. errno = %d: %s\n", error,
               strerror(error));
    }
    error = pthread_create(&receive_thread, &attr, receive, (void *)sockfd);
    if (error != 0) {
        printf("Error creating thread. errno = %d: %s\n", error,
               strerror(error));
        exit(1);
    }
    pthread_attr_destroy(&attr);
}

原来这是一个bug in Valgrind。应该真正报告的错误是EAGAIN。

函数 receive_async 每秒被调用多次。即使我正在创建分离线程,Valgrind 的虚拟环境运行起来也比本地环境慢得多。所以情况是我创建线程的速度快于 Valgrind 销毁线程的速度。 Valgrind 对其可以使用的线程数施加了限制,默认限制为 500。

我能够通过命令 watch ps -o nlwp <pid> 监控我的应用程序使用的线程数。当 运行 在 Valgrind 中时,线程数不断增长,达到 500。当 运行 在 Valgrind 之外时,这个数字更合理(大约 4)并且不会无限增长。