【问题标题】:How to fix occasional EINVAL error when calling pthread_create如何在调用 pthread_create 时修复偶尔出现的 EINVAL 错误
【发布时间】:2019-08-31 06:35:07
【问题描述】:

问题

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

创建线程时出错。 errno = 22: 无效参数

我的尝试

我只在valgrind 中运行我的代码时发现了这个问题。即使那样,它也只是有时会产生此错误。因此,我倾向于认为时机是一个因素。我不认为我有竞争条件,因为这个函数不依赖任何共享数据。也许我对如何使用堆栈有疑问?我一直未能从手册页中发现任何有用的线索,除了 EINVAL 的意思是“'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);
}

【问题讨论】:

  • heap_int 函数只是将 sockfd 复制到堆中并返回指向堆上该位置的指针;这里没有太大的兴趣。 你问这个问题是因为你不知道哪里出了问题。因为你不知道哪里出了问题,所以你无法知道什么是感兴趣的,什么是不感兴趣的。
  • ...事实上,我对heap_int() 非常非常感兴趣,至少将其排除为可能的促成因素。它的返回值似乎是pthread_create() 的唯一参数,其有效性可能会有所不同。
  • 但是,您的代码当然应该验证pthread_attr_init()pthread_attr_setdetachstate() 都成功了。他们的失败似乎不太可能,但假设此类失败不会发生并不是一种许可。
  • @JohnBollinger 所有值都是作为 pthread_create 参数的值。它只传递给线程函数。
  • pthread_attr_initpthread_attr_setdetachstate 是否有可能返回错误?

标签: c linux pthreads valgrind


【解决方案1】:

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

函数receive_async每秒被调用几次。即使我正在创建分离线程,Valgrind 的虚拟环境运行速度也比本地环境慢得多。所以情况是我创建线程的速度比 Valgrind 破坏它们的速度要快。 Valgrind 对它可以使用的线程数进行了限制,默认限制为 500。

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

【讨论】:

  • 您可以尝试使用 --fair-sched=yes valgrind 选项。这可以确保线程之间更好的公平性,这可能会有所帮助。
  • @phd 这不是一个坏主意,我得试一试。我实际上仍然可以使用 Valgrind,我只需要小心我通过我的应用程序抽取的数据量。 (就我而言,太多的数据 = 太多的线程。)
猜你喜欢
  • 1970-01-01
  • 2011-01-31
  • 2011-07-07
  • 2012-06-08
  • 1970-01-01
  • 2021-11-17
  • 2014-03-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多