1. 线程创建:pthread_create()

pthread_create() 是 POSIX 线程库(pthread)中用于创建新线程的函数。调用该函数后系统就会启动一个与主线程并发的线程,并使其跳转到入口函数处执行。

#include <pthread.h>int pthread_create(pthread_t *thread,          // 指向线程标识符的指针const pthread_attr_t *attr, // 线程属性(通常设为 NULL 使用默认值)void *(*start_routine)(void*), // 线程执行的函数void *arg                   // 传递给线程函数的参数
);

参数说明: 

  1. pthread_t* thread:输出型参数,存储新创建线程的标识符(线程 ID)。
  2. const pthread_attr_t* attr:设置线程的属性(如栈大小、调度策略等)。 常用值:NULL(使用默认属性)。 
  3. void* (*)(void*) start_routine:新线程启动后执行的函数(线程入口点)。 要求:必须返回 void*,且接受一个 void* 参数。
  4. void* arg:传递给 start_routine 的参数。 注意:若无需参数,可传 NULL;若需传递多个参数,可封装为结构体。

返回值: 

  • 成功:返回 0。
  • 失败:返回错误码(如 EAGAIN、EINVAL 等),但不设置 errno。

示例代码: 

#include <iostream>
#include <cstring>
#include <unistd.h>
#include <pthread.h>
using namespace std;void* start_routine(void* arg)
{cout << "start_routine: 线程创建成功" << endl;return nullptr;
}int main()
{pthread_t tid;int n = pthread_create(&tid, nullptr, start_routine, nullptr);if(n != 0){cout << "线程创建失败: " << strerror(n) << endl;}while(true);return 0;
}


2. 线程等待:pthread_join()

pthread_join() 是 POSIX 线程库中用于等待线程结束并回收其资源的函数。

主线程如何取得线程运行结束的返回值呢?我们可以使用pthread_join()函数来对指定线程进行等待,并获取其返回值。和waitpid()函数一样,调用这个函数会使主线程阻塞在调用处直到被等待的指定线程运行结束

和多进程编程一样,线程如果不进行等待回收,那么其就会一直保留其运行结果等信息,造成内存泄漏。除此之外,与多进程编程不一样的是,一个进程的多个线程共享主线程的地址空间,一旦主线程退出,其创建的所有线程都会被强制终止,无论其是否执行完

所以在上面的例子当中,线程启动之后我们让主线程陷入了死循环当中,避免其提前退出。

#include <pthread.h>int pthread_join(pthread_t thread,     // 要等待的线程 IDvoid **retval         // 指向线程返回值的指针(可选)
);

核心功能:

  • 阻塞等待:调用 pthread_join() 的线程会暂停执行,直到目标线程终止。
  • 资源回收:线程终止后,其占用的系统资源(如线程描述符、栈空间)会被释放。 若不调用 pthread_join(),终止的线程会成为 “僵尸线程”,造成资源泄漏。
  • 获取返回值:通过 retval 参数获取目标线程的返回值(start_routine 的返回值或 pthread_exit() 的参数)。 

参数说明:

  1. pthread_t thread:指定要等待的线程 ID(由 pthread_create() 返回)。
  2. void** retval:输出型参数,存储线程的返回值(即线程函数 start_routine 的返回值)。 若无需获取返回值,可传 NULL。

 返回值:

  • 成功:返回 0。
  • 失败:返回错误码(如 EDEADLK、ESRCH 等)。

示例代码:

#include <iostream>
#include <cstring>
#include <unistd.h>
#include <pthread.h>
using namespace std;void* start_routine(void* arg)
{cout << "start_routine: 线程创建成功" << endl;for(int i = 0; i < 5; i++){cout << "计数----->" << i << endl;sleep(1);}return (void*)10;
}int main()
{pthread_t tid;int n = pthread_create(&tid, nullptr, start_routine, nullptr);if(n != 0){cout << "线程创建失败: " << strerror(n) << endl;}int result;int m = pthread_join(tid, (void**)&result);if(m != 0){cout << "线程等待失败: " << strerror(m) << endl; }cout << "线程的返回值为: " << result << endl;return 0;
}


3. 线程终止

除主线程以外,线程的正常终止有三种情况:

  1. 从入口函数的return处返回
  2. 调用pthread_exit()函数退出(调用exit()函数会导致整个进程退出)
  3. 某个线程调用pthread_cancel()来终止指定线程

 3.1 pthread_exit()

#include <pthread.h>void pthread_exit(void *retval);  // 无返回值,终止当前线程

核心功能:

  • 终止线程执行:调用 pthread_exit() 的线程会立即停止执行,并释放其占用的资源(如栈空间),但不会释放整个进程的资源。
  • 传递返回值:retval 作为返回值被传递给等待该线程的其他线程。
  • 不影响其他线程:仅终止当前线程,不会影响进程中的其他线程或主线程。

参数说明:

  • void* retval:线程的返回值,可通过 pthread_join() 的 retval 参数获取。 若无需返回值,可传 NULL。

3.2 pthread_self()

pthread_self()函数用于线程获取自身的线程ID。

#include <pthread.h>pthread_t pthread_self(void);  // 返回当前线程的 ID

返回调用该函数的线程的唯一标识符。

3.3 pthread_cancel()

pthread_cancel() 是 POSIX 线程库中用于请求终止某一个线程的函数。

#include <pthread.h>int pthread_cancel(pthread_t thread);  // 请求取消指定线程

 核心功能:

  • 发送取消请求:pthread_cancel() 向目标线程发送一个 “取消请求”,而非强制终止。线程是否响应以及如何响应取决于其取消状态和取消类型。
  • 取消点:预定义的系统调用(如 sleep()、read()、write()、pthread_join() 等),线程在执行这些函数时会检查并处理取消请求。

参数说明:

  • pthread_t thread:要取消的线程 ID(由 pthread_create() 返回)。 

返回值:

  • 成功:返回 0。
  • 失败:返回错误码(如 ESRCH,表示线程 ID 不存在)。 

 示例代码:

// 终止自己==pthread_exit()
pthread_cancel(pthread_self());

4. 线程分离:pthread_detach()

pthread_detach() 是 POSIX 线程库中用于将线程设置为分离状态的函数。

分离状态的线程在终止后,会自动释放其占用的系统资源(如线程描述符、栈空间),无需其他线程调用 pthread_join() 回收。

并且其他线程调用pthread_join()对分离状态的线程进行回收是非法的,会导致未定义错误。

#include <pthread.h> int pthread_detach(pthread_t thread); // 设置线程为分离状态

参数说明:

  • pthread_t thread:要设置为分离状态的线程 ID(由 pthread_create() 返回)。

返回值:

  • 成功:返回 0。
  • 失败:返回错误码(如 ESRCH、EINVAL 等)。 

注意事项:

  • 分离状态不可逆转:一旦线程被设置为分离状态,无法再变回 joinable 状态。
  • 返回值无法获取:分离线程的返回值会被自动丢弃,不能通过 pthread_join() 获取。
  • 资源释放的确定性:分离线程终止后,系统会立即回收其资源,无需等待其他线程操作。
  • 错误处理:若对已终止的线程调用 pthread_detach(),可能返回 ESRCH。 若对已分离的线程重复调用 pthread_detach(),可能返回 EINVAL。 

示例代码:

#include <stdio.h>
#include <pthread.h>
#include <unistd.h>void* detached_thread(void* arg) {printf("分离线程开始运行...\n");sleep(2);  // 模拟耗时操作printf("分离线程结束\n");return NULL;
}int main() {pthread_t thread_id;// 创建新线程if (pthread_create(&thread_id, NULL, detached_thread, NULL) != 0) {perror("线程创建失败");return 1;}// 将线程设置为分离状态if (pthread_detach(thread_id) != 0) {perror("设置分离状态失败");return 1;}printf("主线程继续执行,不等待分离线程\n");// 主线程可以提前退出,分离线程仍会继续执行sleep(1);printf("主线程退出\n");return 0;
}
// 分离自己
pthread_detach(pthread_self());

5. 线程标识符

在 Linux 系统中,pthread_t 类型的线程标识符(tid)本质上是一个轻量级进程(LWP)ID或指向线程控制块的指针。

5.1 线程控制块(TCB)

每个线程在内核中对应一个 task_struct 结构(与进程相同),但共享父进程的资源。

而在用户空间中,经过pthread库的包装之后另外设置了一种数据结构来维护额外的线程数据,即TCB,包括如下控制信息:

  • 线程状态(运行、阻塞等)
  • 线程栈地址和大小
  • 信号掩码
  • 内核 LWP ID

 5.2 pthread_t类型的本质

在 Linux 中,pthread_t 的具体类型定义取决于实现:

  • glibc/NPTL:pthread_t 通常是一个 struct pthread*,即指向线程控制块的指针
  • 用户可见性:pthread_t 对用户是不透明的,只能通过 POSIX 线程 API 操作。

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

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

相关文章

Ragflow 源码:ragflow_server.py

目录 介绍1. 初始化和配置2. 数据库管理3. 核心功能4. HTTP 服务5. 信号处理6. 调试支持 流程图系统架构 代码解释1. **初始化系统**2. **运行时控制**3. **核心服务** 介绍 ragflow_server.py 是 RAGFlow 项目的主服务器程序&#xff0c;负责启动和管理 RAGFlow 的核心服务。…

springboot企业级项目开发之项目测试——单元测试!

项目测试 项目测试是对项目的需求和功能进行测试&#xff0c;由测试人员写出完整的测试用例&#xff0c;再按照测试用例执行测试。项目测试是项目质量的保证&#xff0c;项目测试质量直接决定了当前项目的交付质量。 测试人员在开展测试之前&#xff0c;首先需要进行测试的需…

Linux kdump远程转存储配置手册教程

一、前言 kdump是一个Linux内核崩溃转储机制,当系统崩溃时,它可以捕获内核的内存转储信息,帮助分析崩溃原因。将转储文件存储到远程位置,便于集中管理和分析。本教程将详细介绍如何配置kdump将转储文件远程转存储。 二、安装kdump 在大多数Linux发行版中,kdump相关的工…

c++bind和forward完美转化

前言 1. std::bind概述 std::bind是C11引入的功能模板&#xff0c;位于<functional>头文件中&#xff0c;用于将函数、成员函数或函数对象与特定参数绑定&#xff0c;生成一个新的可调用对象。 1.1 基本用法 #include <iostream> #include <functional>v…

【Dify精讲】第14章:部署架构与DevOps实践【知识卡片】

第14章&#xff1a;部署架构与DevOps实践http://www.airinto.com/share/49997bb7 一、Docker 容器化方案&#xff1a;从开发到生产的统一 二、Kubernetes 部署&#xff1a;走向云原生 三、CI/CD 流程设计&#xff1a;自动化的艺术 四、高可用架构&#xff1a;让 AI 服务永不停歇…

el-cascader 设置可以手动输入也可以下拉选择

el-cascader 设置可以手动输入也可以下拉选择 稍微修改一下就可食用 <template slot"stationId" slot-scope""><div style"position: relative;"><!-- 可输入也可显示选项 --><el-input:value"stationNameInput"…

Unity Shader开发-着色器变体(1)-着色器变体概述

有时我们希望一份 Shader 源代码可能满足多种功能&#xff08;如处理法线贴图、自发光、不同光照模式、阴影&#xff0c;支持GPUInstacing等多种功能&#xff09;。所以我们需要能够实现Shader分支的方法。 一.Shader分支实现 主要有三种手段实现Shader分支&#xff1a; 1.静…

ECK 简化:在 GCP GKE Autopilot 上部署 Elasticsearch

作者&#xff1a;来自 Elastic Eduard Martin 学习如何使用 GKE Autopilot 和 ECK 在 GCP 上部署 Elasticsearch 集群。 想要获得 Elastic 认证&#xff1f;了解下一次 Elasticsearch Engineer 培训的时间&#xff01; Elasticsearch 拥有丰富的新功能&#xff0c;可以帮助你为…

测试一个软件的性能有哪些指标?

在测试软件性能时,通常会关注多个维度的指标,以评估系统在不同负载下的表现。以下是关键的性能测试指标分类和详细说明: 📊 核心性能指标分类 1. 响应时间(Response Time) 定义:从发送请求到接收到响应所花费的时间 细分: 平均响应时间:所有请求的平均耗时 *P90/P95…

浅析std::atomic<T>::compare_exchange_weak和std::atomic<T>::compare_exchange_strong

目录 std::atomic ::compare_exchange_weak 和 std::atomic ::compare_exchange_strong 核心原理 函数签名 核心区别 典型用法 1. compare_exchange_weak&#xff08;循环内重试&#xff09; 2. compare_exchange_strong&#xff08;单次尝试&#xff09; 底层机制 总…

举出一个异步接口测试的例子

以下是一个完整的 ​异步接口测试​ 实际案例&#xff0c;包含问题场景、解决方案、代码实现和面试回答技巧&#xff0c;适合在面试中展示技术深度&#xff1a; ​案例背景​ ​业务场景​&#xff1a; 测试一个AI图片生成平台的异步接口&#xff0c;用户提交生成请求后&#…

更新麒麟连不上外网

问题&#xff1a;更新麒麟连不上外网 处理&#xff1a;本地建个下载地址 建立文件夹/root/x86.rpm&#xff0c;子文件夹&#xff1a;Packages、repodata&#xff0c;和在线站点建的一样&#xff1a;Index of /NS/V10/V10SP1.1/os/adv/lic/base/x86_64/&#xff0c;然后就下载…

TensorFlow深度学习实战——使用Hugging Face构建Transformer模型

TensorFlow深度学习实战——使用Hugging Face构建Transformer模型 0. 前言1. 安装 Hugging Face2. 文本生成3. 自动模型选择和自动分词4. 命名实体识别5. 摘要生成6. 模型微调相关链接 0. 前言 除了需要实现特定的自定义结构&#xff0c;或者想要了解 Transformer 工作原理外&…

SAP-ABAP:SAP全模块的架构化解析,涵盖核心功能、行业方案及技术平台

一、核心业务模块&#xff08;Logistics & Operations&#xff09; 模块代号核心功能典型流程关键事务码物料管理MM采购/库存/发票校验采购到付款 (P2P)ME21N&#xff08;采购订单&#xff09;, MI31&#xff08;库存盘点&#xff09;销售与分销SD订单/定价/发货/开票订单…

实时预警!机场机坪井室无线智能液位监测系统助力安全降本

某沿海机场因地处多雨区域&#xff0c;每年雨季均面临排水系统超负荷运行压力。经勘测发现&#xff0c;5个井室因长期遭受地下水渗透侵蚀&#xff0c;井壁出现细微结构性裂缝&#xff0c;导致内部水位异常升高。作为机坪地下管网系统的核心节点&#xff0c;这些井室承担着雨水导…

边云协同 AI 视频分析系统设计方案

目录 一、项目背景与目标 二、系统架构概述 总体架构图 三、ER 图&#xff08;核心数据库设计&#xff09; 实体关系图简述 数据表设计&#xff08;简要&#xff09; 四、模型结构图&#xff08;边缘云端AI推理架构&#xff09; 边缘模型&#xff08;YOLOv5-tiny/PP-YO…

vue3整合element-plus

为项目命名 选择vue 框架 选择TS 启动测试&#xff1a; npm run dev 开始整合 element-plus npm install element-plus --save npm install unplugin-vue-components unplugin vitejs/plugin-vue --save-dev 修改main.ts import { createApp } from vue import ./style.cs…

【AI 测试】测试用例设计:人工智能语言大模型性能测试用例设计

目录 一、性能测试可视化架构图 &#xff08;1&#xff09;测试整体架构图 &#xff08;2&#xff09;测试体系架构图 &#xff08;3&#xff09;测试流程时序图 二、性能测试架构总览 &#xff08;1&#xff09;性能测试功能点 &#xff08;2&#xff09;测试环境要…

Windsurf SWE-1模型评析:软件工程的AI革命

引言 软件开发领域正经历着前所未有的变革&#xff0c;AI辅助编程工具层出不穷&#xff0c;但大多数仅专注于代码生成这一环节。Windsurf公司近期推出的SWE-1系列模型打破了这一局限&#xff0c;首次将AI应用扩展至软件工程的全流程。这一举措不仅反映了行业对AI工具认知的深化…

Qt for OpenHarmony 编译鸿蒙调用的动态库

简介 Qt for Harmony​ 是跨平台开发框架 ​Qt​ 与华为 ​OpenHarmony​ 操作系统的深度集成方案&#xff0c;由 Qt Group 与华为联合推动。其核心目标是为开发者提供一套高效工具链&#xff0c;实现 ​​“一次开发&#xff0c;多端部署”​&#xff0c;加速 OpenHarmony 生…