Linux上C语言如何获取线程的返回值

文章目录

  • 一、线程的三个重要的应用程序接口(API)
    • 1.1 线程的创建
    • 1.2 线程的退出
    • 1.3 线程的等待
  • 二、让线程返回int类型的值
  • 二、让线程返回字符串(char*)类型的值

一、线程的三个重要的应用程序接口(API)

1.1 线程的创建

#include <pthread.h>
int pthread_create(pthread_t *restrict tidp, const pthread_attr_t *restrict attr, void *(*start_rtn)(void *), void *restrict arg);

当pthread_create成功返回0。

  1. tidp 指向的内存单元被设置为新创建线程的线程ID。
  2. attr 参数用于定制各种不同的线程属性,暂可以把它设置为 NULL,以创建默认属性的线程。(工作中也多用NULL)
  3. 新创建的线程从 start_rtn(函数指针)函数的地址开始运行,该函数只有一个无类型指针参数 arg
  4. 如果需要向 start_rtn 函数传递的参数不止一个,那么需要把这些参数放到一个结构中,然后把这个结构的地址作为 arg 参数传入。

1.2 线程的退出

单个线程可以通过以下三种方式退出,在不终止整个进程的情况下停止它的控制流:

  1. 线程只是从启动例程中返回,返回值是线程的退出码
  2. 线程可以被同一进程中的其他线程取消
  3. 线程调用pthread_exit
#include <pthread.h>
int pthread_exit(void *rval_ptr);

rval_ptr 是一个无类型指针,与传给启动例程的单个参数类似。进程中的其他线程可以通过调用 pthread_join 函数访问到这个指针。

1.3 线程的等待

#include <pthread.h>
int pthread_join(pthread_t thread, void **rval_ptr);
// 返回:若成功返回0,否则返回错误编号

调用这个函数的线程将一直阻塞,直到指定的线程调用pthread_exit、从启动例程中返回或者被取消。

  1. 如果例程只是从它的启动例程返回,rval_ptr 将包含返回码。
  2. 如果线程被取消,由 rval_ptr 指定的内存单元就置为PTHREAD_CANCELED。

可以通过调用pthread_join自动把线程置于分离状态,这样资源就可以恢复。如果线程已经处于分离状态,pthread_join 调用就会失败,返回 EINVAL。

如果对线程的返回值不感兴趣,可以把 rval_ptr 置为 NULL 。在这种情况下,调用 pthread_join 函数将等待指定的线程终止,但并不获得线程的终止状态。

  • 在 Linux 的 C 语言多线程环境中,启动例程通常指的是主线程(Main Thread)中的入口函数。在多线程程序中,主线程是程序的起点,它负责创建和管理其他线程,并在程序执行完成后终止整个进程。

  • 在 C 语言中,主线程的入口函数通常是 main 函数。main 函数是程序的入口点,当程序启动时,操作系统会调用 main 函数作为程序的起点。在多线程程序中,主线程的 main 函数会负责创建其他线程,分配资源,执行逻辑代码,并最终等待其他线程执行完成后终止整个进程。

  • 例程(routine)通常指的是一段执行特定任务的代码块或函数。在多线程环境中,每个线程都有自己的例程,用于定义线程要执行的任务。主线程的例程就是 main 函数,而其他线程的例程可以是通过线程创建函数(如 pthread_create)传入的函数指针,用于定义线程要执行的任务。

  • 总的来说,在 Linux 的 C 语言多线程环境中,启动例程指的是主线程的入口函数 main,而例程指的是线程要执行的任务代码块或函数。主线程的 main 函数负责创建其他线程,并启动线程执行各自的例程

二、让线程返回int类型的值

#include <stdio.h>
#include <pthread.h>void* fun1(void *arg)
{//static(全局变量): 保证函数调用结束后,变量值还在static int ret = 10;printf("t1:%ld thread is create\n", (unsigned long)pthread_self());printf("t1: %d\n", *((int*)arg));// 3.退出线程函数pthread_exit((void *)&ret);//pthread_join可以通过其第二个参数访问这个指针
}int main()
{//int pthread_create(pthread_t *restrict tidp, const pthread_attr_t *restrict attr, void *(*start_rtn)(void *), void *restrict arg);int ret;int param = 100;pthread_t t1;int *pret = NULL;//1.创建线程//                       线程属性 线程函数 线程函数参数ret = pthread_create(&t1, NULL, fun1, (void*)&param);if(ret == 0){printf("main:create t1 success\n");} else {perror("why t1 fail");}printf("main:%ld\n", (unsigned long)pthread_self());//打印主线程ID//2.等待线程函数退出pthread_join(t1, (void**)&pret);//等待线程结束,防止进程结束,线程还未执行完毕//4.输出线程int返回值printf("main: pret=%d\n", *pret);return 0;
}

二、让线程返回字符串(char*)类型的值

//demo3
#include <stdio.h>
#include <pthread.h>void* fun1(void *arg)
{static char* p = "t1 run out";//static(全局变量): 保证函数调用结束后,变量值还在printf("t1:%ld thread is create\n", (unsigned long)pthread_self());printf("t1: %d\n", *((int*)arg));//3.退出线程函数 返回返回值pthread_exit((void *)p);//pthread_join可以通过其第二个参数访问这个指针
}int main()
{//int pthread_create(pthread_t *restrict tidp, const pthread_attr_t *restrict attr, void *(*start_rtn)(void *), void *restrict arg);int ret;int param = 100;pthread_t t1;char *pret = NULL;//1.创建线程//                       线程属性 线程函数 线程函数参数ret = pthread_create(&t1, NULL, fun1, (void*)&param);if(ret == 0){printf("main:create t1 success\n");} else {perror("why t1 fail");}printf("main:%ld\n", (unsigned long)pthread_self());//打印主线程ID//2.等待线程pthread_join(t1, (void**)&pret);//等待线程结束,防止进程结束,线程还未执行完毕//4.输出线程字符串返回值printf("main: pret=%s\n", pret);return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/710506.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

PYCHARM PYSIDE6 QT 打包异常处理 no qt platform plugin could be initialized

安装有PYSIDE6的电脑 异常错误 … no qt platform plugin could be initialized … 变量名&#xff1a;QT_QPA_PLATFORM_PLUGIN_PATH &#xff08;一个字都不能改&#xff01;&#xff01;&#xff09; 自己环境变量值&#xff1a;D:\Users\topma\anaconda3\Lib\site-package…

React中对表格实现列表的拖拽排序

1. 效果:推拽手柄列 2. 实现: react中我们需要两个包来实现 ‘array-move’‘react-sortable-hoc’Installation Use npm $ npm install react-sortable-hoc --save 引入 import { arrayMoveImmutable } from array-move import { SortableContainer, SortableElement, Sort…

Jenkins笔记(一)

个人学习笔记&#xff08;整理不易&#xff0c;有帮助点个赞&#xff09; 笔记目录&#xff1a;学习笔记目录_pytest和unittest、airtest_weixin_42717928的博客-CSDN博客 目录 一&#xff1a;简单了解 二&#xff1a;什么是DevOps 三&#xff1a;安装Jenkins 四&#xff1…

Spring Boot 和 Spring Cloud: 区别与联系

Spring Boot 和 Spring Cloud: 区别与联系 在当今软件开发领域&#xff0c;微服务架构和快速开发成为了主流趋势。Spring框架作为Java生态系统中最流行的开发框架之一&#xff0c;也不例外地推出了Spring Boot和Spring Cloud这两个项目来满足这些需求。本文将详细探讨它们之间…

RK3568平台 EXPORT_SYMBOL的作用

一、EXPORT_SYMBOL 的作用 1.在一个模块中使用 EXPORT_SYMBOL(name)。name 表示函数或者变量等符号&#xff0c;它是对全部内核代码公开的&#xff0c;因此在您的内核模块中可以直接调用 name&#xff0c;即使用 EXPORT_SYMBOL 可以将一个函数以符号的方式导出给其他模块使用。…

MongoDB聚合运算符:$cond

文章目录 语法用法举例 $cond聚合运算符根据布尔表达式的结果返回两个表达式中的一个。 语法 { $cond: { if: <boolean-expression>, then: <true-case>, else: <false-case> } }或&#xff1a; { $cond: [ <boolean-expression>, <true-case>…

(案例贴2) html+css 倒计时器

欢迎大家使用这个计时器噢 老哥直接附代码咯. timer.html <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0">&l…

GitLab--Merge Request 权限管理

场景 团队在日常开发工作中需要进行分支管理&#xff0c;通常使用feature分支进行开发&#xff0c;然后依次合并到dev分支、release分支&#xff0c;整个代码合并过程不仅仅是代码合并还需要对代码进行审核&#xff0c;如果在线下进行审核合并&#xff0c;这样操作无法保留痕迹…

【力扣hot100】刷题笔记Day18

前言 晚上巩固一下今天的回溯题&#xff0c;基础不牢地动山摇&#xff0c;po一张代码随想录总结的 组合补充 77. 组合 - 力扣&#xff08;LeetCode&#xff09; class Solution:def combine(self, n: int, k: int) -> List[List[int]]:path []res []def backtrack(star…

go垃圾回收

1 go 垃圾回收变更 Go 语言的垃圾回收器&#xff08;GC&#xff09;自其诞生以来一直在不断演进和优化&#xff0c;以提高性能、减少暂停时间和对程序执行的影响。以下是一些关键的改进和变更点&#xff1a; 并发标记周期&#xff1a; Go 语言从一开始就采用了并发标记&#xf…

日立F-4700FL数据分析实验报告

实验设定 日立F-4700FL为荧光分光光度计,可输出三维光谱扫描结果到计算机。D和L为两种化合物。对4种不同的溶液进行三维光谱扫描,得到的光谱文件如下。 溶质光谱文件无K.txtDD.txtLL.txtD+LH.txt光谱文件(txt)的内容格式如下。 Sample: ... File name: ... Run date: ... …

[C#] 重难点区分[In]、[Out]、in、out、in T、out T

[In] 属性&#xff1a; - [In] 属性用于标识参数是一个输入参数。这意味着参数的值将被传递到方法或函数&#xff0c;但在其执行期间不会被修改。 - 当通过 P/Invoke 或 COM 互操作调用函数时&#xff0c;使用 [In] 属性指示参数的传递方式为输入。 - 示例&#xff1a…

深入探析:云计算与边缘计算在软件开发中的应用与挑战

随着互联网技术的飞速发展&#xff0c;云计算和边缘计算作为两种重要的计算模型&#xff0c;已经成为当今IT领域的热点话题。云计算通过将计算、存储、网络等资源集中在云端&#xff0c;为企业提供弹性、可靠、安全的计算服务。而边缘计算则是将部分计算任务从云端迁移到网络边…

BeautifulSoup解析 HTML标签Tag及属性attrs的常用方法

# 使用 BeautifulSoup 解析 HTML 内容 # BeautifulSoup 对象表示整个解析树或文档&#xff0c;可以用来遍历、搜索和操作文档。# 常用方法&#xff1a; # find(name, attrs, recursive, text, **kwargs)&#xff1a;在文档中查找第一个符合条件的元素&#xff0c;并返回该元素…

Java面试值之集合

集合 1.HashMap底层&#xff1f;扩容机制&#xff1f;1.7-1.8的升级&#xff1f;2.HashMap的长度为什么是2的幂次方&#xff1f;3.HashMap 插入1.7和1.8的区别&#xff1f;4.什么是红黑树&#xff1f;O(logn)5.HashMap为什么会使用红黑树&#xff1f;6.ArrayList底层&#xff1…

鸿蒙(HarmonyOS)项目方舟框架(ArkUI)之FlowItem容器组件

鸿蒙&#xff08;HarmonyOS&#xff09;项目方舟框架&#xff08;ArkUI&#xff09;之FlowItem容器组件 一、操作环境 操作系统: Windows 10 专业版、IDE:DevEco Studio 3.1、SDK:HarmonyOS 3.1 二、FlowItem组件 子组件 可以包含子组件。 接口 FlowItem() 使用该接口来…

免费音频剪辑

在数字时代&#xff0c;音频剪辑已成为许多职业和爱好者不可或缺的技能。无论是制作播客、教育视频、还是进行广告宣传&#xff0c;高质量的音频剪辑都能为作品增色不少。今天&#xff0c;我要为大家强烈安利一款免费且功能强大的音频剪辑工具&#xff0c;它绝对是你办公桌上不…

Kotti-基于Python的开源内容管理系统介绍与使用

前言 Kotti是一个基于Python的开源内容管理系统&#xff08;CMS&#xff09;&#xff0c;旨在为开发人员提供快速、简单和灵活的方式来构建Web应用。它基于Pyramid框架&#xff0c;使用SQLAlchemy进行数据库管理&#xff0c;支持自定义内容类型和可扩展的插件系统。本文将深入…

命令行启动mongodb服务器的问题及解决方案 -- Unrecognized option: storage.journal

目录 mongodb命令行启动问题 -- Unrecognized option: storage.journal问题日志&#xff1a;问题截图&#xff1a;问题来源&#xff1a;错误原因&#xff1a;解决方式&#xff1a; mongodb命令行启动问题 – Unrecognized option: storage.journal 同样是格式出问题的问题分析和…

《Spring Security 简易速速上手小册》第5章 高级认证技术(2024 最新版)

文章目录 5.1 OAuth2 和 OpenID Connect5.1.1 基础知识详解OAuth2OpenID Connect结合 OAuth2 和 OIDC 5.1.2 重点案例&#xff1a;使用 OAuth2 和 OpenID Connect 实现社交登录案例 Demo 5.1.3 拓展案例 1&#xff1a;访问受保护资源案例 Demo测试访问受保护资源 5.1.4 拓展案例…