• 【PTHREAD】线程状态


    1 链接态线程

    int pthread_join(pthread_t thread, void **retval);
    int pthread_tryjoin_np(pthread_t thread, void **retval);
    int pthread_timedjoin_np(pthread_t thread, void **retval, const struct timespec *abstime);
    
    • 1
    • 2
    • 3
    • pthread_join

      • 阻塞函数
      • 参数retval用于接收线程的返回值。如果不需要,设置为NULL
      • 调用该函数的线程将等待参数thread所标识的线程的退出
      • 参数thread所标识的线程的资源在调用pthread_join时释放
    • pthread_tryjoin_np

      • 该函数执行非阻塞的链接。
      • 如果调用该函数时,参数thread指定的线程已终止,则其功能与pthread_join相同
      • 如果调用该函数时,参数thread指定的线程尚未终止,则该函数以错误的方式立即返回
    • pthread_timedjoin_np

      • 带超时时间的链接。
      • 如果线程尚未终止,且线程在参数abstime指定的时间内结束,则其功能与pthread_join相同
      • 如果超时在线程终止前到期,则函数返回调用超时错误。

    2 案例:链接态线程使用之pthread_join

    • 源码

      #include 
      #include 
      #include 
      #include 
      
      void *start_routine(void *ptr)
      {
          printf("子线程(%lu)开始运行...\n", pthread_self());
      
          sleep(3);
      
          printf("子线程(%lu)即将退出...\n", pthread_self());
          return (void*)"9999";
      }
      
      int main(int argc, char const *argv[])
      {
          printf("主线程(%lu)开始运行...\n", pthread_self());
      
          pthread_t thread_id;
          pthread_create(&thread_id, NULL, start_routine, NULL);
          
          void *retval = NULL;
          pthread_join(thread_id, &retval);
          printf("子线程的返回值为:%s\n", (const char*)retval);
      
          printf("主线程(%lu)即将退出...\n", pthread_self());
          exit(EXIT_SUCCESS);
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
    • 输出

      主线程(140647242364736)开始运行…
      子线程(140647242360576)开始运行…
      子线程(140647242360576)即将退出…
      子线程的返回值为:9999
      主线程(140647242364736)即将退出…

    3 案例:链接态线程使用之pthread_tryjoin_np

    • 源码

      #include 
      #include 
      #include 
      #include 
      
      void *start_routine(void *ptr)
      {
          printf("子线程(%lu)开始运行...\n", pthread_self());
      
          sleep(3);
      
          printf("子线程(%lu)即将退出...\n", pthread_self());
          return (void*)"9999";
      }
      
      void TEST_Join(int timeout)
      {
          printf("\n");
      
          pthread_t thread_id;
          pthread_create(&thread_id, NULL, start_routine, NULL);
      
          sleep(timeout);
          void *retval = NULL;
          int ret = pthread_tryjoin_np(thread_id, &retval);
          printf("函数返回值     :%d\n", ret);
          printf("子线程的返回值为:%s\n", (const char*)retval);
      
          printf("\n");
      }
      
      int main(int argc, char const *argv[])
      {
          printf("主线程(%lu)开始运行...\n", pthread_self());
      
          TEST_Join(0);   // 调用函数时,子线程尚未结束
          sleep(5);
          TEST_Join(5);   // 调用函数是,子线程已终结
      
          printf("主线程(%lu)即将退出...\n", pthread_self());
          exit(EXIT_SUCCESS);
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35
      • 36
      • 37
      • 38
      • 39
      • 40
      • 41
      • 42
    • 输出

      主线程(140402546759488)开始运行…

      子线程(140402546755328)开始运行…
      函数返回值 :16
      子线程的返回值为:(null)

      子线程(140402546755328)即将退出…

      子线程(140402538362624)开始运行…
      子线程(140402538362624)即将退出…
      函数返回值 :0
      子线程的返回值为:9999

      主线程(140402546759488)即将退出…

    4 案例:链接态线程使用之pthread_timedjoin_np

    • 源码

      #include 
      #include 
      #include 
      #include 
      #include 
      
      void *start_routine(void *ptr)
      {
          printf("子线程(%lu)开始运行...\n", pthread_self());
      
          sleep(3);
      
          printf("子线程(%lu)即将退出...\n", pthread_self());
          return (void*)"9999";
      }
      
      void TEST_Join(int timeout)
      {
          pthread_t thread_id;
          pthread_create(&thread_id, NULL, start_routine, NULL);
      
          struct timespec ts;
          ts.tv_sec = 5;
          ts.tv_nsec = 0;
      
          void *retval = NULL;
          time_t start, end; 
          time(&start);
          int ret = pthread_timedjoin_np(thread_id, &retval, &ts);
          time(&end);
          printf("函数耗时     :%lf\n", difftime(end, start));
          // ETIMEDOUT = 110;等待在线程结束前终止
          // EINVAL = 22
          printf("函数返回值     :%d\n", ret);  
          printf("子线程的返回值为:%s\n", (const char*)retval);
      }
      
      int main(int argc, char const *argv[])
      {
          printf("主线程(%lu)开始运行...\n", pthread_self());
          TEST_Join(1);   // 调用函数时,子线程尚未结束
          sleep(5);
          TEST_Join(5);   // 调用函数是,子线程已终结
      
          printf("主线程(%lu)即将退出...\n", pthread_self());
          exit(EXIT_SUCCESS);
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35
      • 36
      • 37
      • 38
      • 39
      • 40
      • 41
      • 42
      • 43
      • 44
      • 45
      • 46
      • 47
    • 输出

      未测试出效果

    5 分离态线程

    int pthread_detach(pthread_t thread);
    
    • 1
    • 分离态线程,在线程结束时自动释放资源
    • 分离态线程,无法获得其返回值

    6 案例:分离态线程使用

    • 源码

      #include 
      #include 
      #include 
      #include 
      
      void *start_routine(void *ptr)
      {
          printf("子线程(%lu)开始运行...\n", pthread_self());
      
          sleep(3);
      
          printf("子线程(%lu)即将退出...\n", pthread_self());
          return (void*)"9999";
      }
      
      int main(int argc, char const *argv[])
      {
          printf("主线程(%lu)开始运行...\n", pthread_self());
      
          pthread_t thread_id;
          pthread_create(&thread_id, NULL, start_routine, NULL);
          pthread_detach(thread_id);
      
          sleep(5);
      
          printf("主线程(%lu)即将退出...\n", pthread_self());
          exit(EXIT_SUCCESS);
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
    • 输出

      主线程(140334013024064)开始运行…
      子线程(140334013019904)开始运行…
      子线程(140334013019904)即将退出…
      主线程(140334013024064)即将退出…

  • 相关阅读:
    Time Series Data Augmentation for Deep Learning: A Survey
    【CSS】css转换、css过渡、css动画_09
    带你吃透Servlet核心编程下篇(完整图文教程)
    牛掰的dd命令,cpi0配合find备份(不会主动备份),od查看
    通过海康私有协议Ehome/ISUP协议将海康摄像头、录像机等设备统一接入到LiveNVR Web流媒体平台实现统一汇聚及Web播放等的配置说明,
    MySQL中的排序与分页
    FANUC机器人电气控制柜内部硬件电路和模块详细介绍
    Windows 11上Dev C++ 5.11 提示 Failed to execute xxx Error 0的一种解决方法
    docker docker-compose.yml
    【Azure Developer】App Service + PubSub +JS 实现多人版黑客帝国文字流效果图
  • 原文地址:https://blog.csdn.net/zhy29563/article/details/126669997