当前位置: 首页 > news >正文

【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);
  • 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 <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <pthread.h>
    
    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);
    }
    
  • 输出

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

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

  • 源码

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <pthread.h>
    
    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);
    }
    
  • 输出

    主线程(140402546759488)开始运行…

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

    子线程(140402546755328)即将退出…

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

    主线程(140402546759488)即将退出…

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

  • 源码

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <pthread.h>
    #include <time.h>
    
    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);
    }
    
  • 输出

    未测试出效果

5 分离态线程

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

6 案例:分离态线程使用

  • 源码

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <pthread.h>
    
    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);
    }
    
  • 输出

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

相关文章:

  • 网易云音乐项目————项目准备
  • 计算机网络——应用层の选择题整理
  • LabVIEW通过网络传输数据
  • 【PTHREAD】线程属性
  • 如何做好项目管理?项目管理和团队协作是关键
  • 《嵌入式 – GD32开发实战指南》第20章 GD32的存储结构
  • Vue模块语法上(插值指令过滤器计算属性-监听属性)
  • 初识网络
  • Linux的OpenLava配置
  • MySQL如何记忆
  • 【回溯算法】leetcode 78. 子集
  • stm32f4xx-外部中断
  • Tricentis NeoLoad:自动化的企业性能测试平台
  • Linux内核中网络部分结构以及分布
  • 从无到有的基于QT软件的DIY桌面番茄钟(上)
  • JS中 map, filter, some, every, forEach, for in, for of 用法总结
  • 【Redis学习笔记】2018-06-28 redis命令源码学习1
  • 【个人向】《HTTP图解》阅后小结
  • 2017-08-04 前端日报
  • conda常用的命令
  • java 多线程基础, 我觉得还是有必要看看的
  • JavaSE小实践1:Java爬取斗图网站的所有表情包
  • Median of Two Sorted Arrays
  • nginx 负载服务器优化
  • node学习系列之简单文件上传
  • React 快速上手 - 06 容器组件、展示组件、操作组件
  • Redux 中间件分析
  • RxJS: 简单入门
  • Spring声明式事务管理之一:五大属性分析
  • Sublime Text 2/3 绑定Eclipse快捷键
  • webpack入门学习手记(二)
  • 阿里云爬虫风险管理产品商业化,为云端流量保驾护航
  • 力扣(LeetCode)965
  • 漂亮刷新控件-iOS
  • 前端路由实现-history
  • 让你的分享飞起来——极光推出社会化分享组件
  • 融云开发漫谈:你是否了解Go语言并发编程的第一要义?
  • 使用parted解决大于2T的磁盘分区
  • 通过npm或yarn自动生成vue组件
  • Linux权限管理(week1_day5)--技术流ken
  • 摩拜创始人胡玮炜也彻底离开了,共享单车行业还有未来吗? ...
  • 我们雇佣了一只大猴子...
  • # Apache SeaTunnel 究竟是什么?
  • (10)Linux冯诺依曼结构操作系统的再次理解
  • (一)基于IDEA的JAVA基础12
  • (转)c++ std::pair 与 std::make
  • (转)scrum常见工具列表
  • (转载)虚幻引擎3--【UnrealScript教程】章节一:20.location和rotation
  • .net core 客户端缓存、服务器端响应缓存、服务器内存缓存
  • .NET Micro Framework初体验
  • .net中应用SQL缓存(实例使用)
  • /deep/和 >>>以及 ::v-deep 三者的区别
  • @entity 不限字节长度的类型_一文读懂Redis常见对象类型的底层数据结构
  • @property括号内属性讲解
  • []新浪博客如何插入代码(其他博客应该也可以)