sleep() 会影响 pthread 执行吗?

Posted

技术标签:

【中文标题】sleep() 会影响 pthread 执行吗?【英文标题】:Does sleep() affect pthread execution? 【发布时间】:2021-04-03 18:32:18 【问题描述】:

我对这个例子感到困惑:

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

void *thread_func() 
 
    sleep(1); // removing this changes the result
    printf("\n");
    return NULL;
 

int main() 
 
    int i;

    for (i = 0; i < 10000; i++) 
    
        pthread_t tid; 
        pthread_create(&tid, NULL, thread_func, NULL); 
      

    pthread_exit(NULL); 
    return 0; 

如果我使用sleep(1) 运行它,我会按预期计算 2047 行,没有它 10000。这是怎么回事?

编辑:将预期行数更正为 10000。

【问题讨论】:

你为什么期望 10000 个线程,每个打印一个空行,产生 3000 行? 你认为pthread_exit(NULL); 会做什么? 10000 个线程非常多,您确定 pthread_create() 有时不会因为达到某些限制而失败吗?你应该检查它的返回值来看看。 【参考方案1】:

由于您的程序在退出之前不会等待其线程,因此发生的情况是,在退出程序销毁所有线程之前,它有一个模糊定义的运行时间。

更新:pthread_exit 确实在等待线程。对于正在运行的线程。我怀疑正在发生的是pthread_create 创建的线程在pthread_exit 之前没有完全构造,然后程序退出。部分线程构造发生在新线程中,因此如果它从未被安排运行,那么该线程也可能不存在。

创建 10,000 个线程需要时间。摧毁它们也是如此。与此同时,显然有 3,000 个线程设法到达 printf 语句。

打印的时间和数量取决于许多不同的因素,因此也可能是随机的。

【讨论】:

通过调用pthread_exit() 离开main() 预计不会结束进程(与returning 相反),但“主”线程。 感谢您的回答,您的怀疑当然是正确的。 pthread_create 失败。由于perror 检查,我选择了其他答案。【参考方案2】:

抛开显示的代码尝试创建 10000 个线程,如果创建成功,将打印 10000 行而不是 3000 行,核心问题是:

与不等待相比,如果每个线程等待 1 秒,为什么printing 的线程更少?

可能的推理:

每个线程都会消耗资源。因此,并发存在的最大线程数是有限的。

如果每个线程在结束前等待 1 秒,则可以假设可用资源被消耗得更快,然后线程立即退出。因此,如果资源耗尽,线程的创建就会失败,代码会忽略它,而只是尝试创建下一个。

要查看代码的实际情况,应记录创建失败的情况,如下所示:

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

void *thread_func(void) 
 
    sleep(1); /* Removing this probably lowers the number of failed creations. */
    printf("\n");
    return NULL;
 

int main(void) 
 
    int i;

    for (i = 0; i < 10000; i++) 
    
        pthread_t tid; 
        if (errno = pthread_create(&tid, NULL, thread_func, NULL))
        
          perror("pthread_create() failed");
        
      

    pthread_exit(NULL); 

    /* Never arriving here. */
    return 0; 

上述代码打印的总行数预计为10000行,有的空行到stdout,有的列出创建失败到stderr

【讨论】:

是的,谢谢,这确实解决了这个谜。我从不使用 C 编程,否则我可能会本能地检查错误。当我做./threads_corrected 2&gt;&amp;1 | grep -i failed | wc -l ...我看到丢失的7953次失败尝试!

以上是关于sleep() 会影响 pthread 执行吗?的主要内容,如果未能解决你的问题,请参考以下文章

睡眠时间是不是计入执行时间限制?

pthread.h - 自愿CPU是否是调度另一个用户级线程的唯一触发器?

如何不使用pthread

pthread_once的pthread_once

Linux多线程编程 - sleep 和 pthread_cond_timedwait

需要在线程任务中正确使用sleep()