news 2026/5/1 10:32:55

Linux 线程(POSIX)核心教程

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Linux 线程(POSIX)核心教程

一、线程核心概论

1.1 基本定义

Linux 中,线程被称为 “轻量级进程(LWP,Light Weight Process)”,线程属于进程—— 一个进程可以包含多个线程,所有线程共享进程的资源(如内存空间、文件描述符、信号处理等),同时拥有独立的执行流。

1.2 核心作用

与进程一致,线程的核心价值是实现并发执行,尤其适合处理:

  • 耗时任务(如 IO 操作、网络通信);
  • 并行计算(如多核心数据处理);
  • 程序模块化拆分(如一个线程处理输入,一个线程处理输出)。

1.3 关键特征

维度核心描述
资源分配进程是系统最小的资源分配单位(如内存、CPU 时间片);线程是系统最小的执行单位
层级关系进程内的所有线程是平级关系,无父子之分;进程默认包含一个 “主线程”(main 函数对应的线程)
资源范围线程共享进程的全局资源(堆、全局变量、文件描述符),但拥有独立的栈区(默认 8MB)

二、线程与进程的核心区别

特性线程进程
资源共享共享进程资源(堆、全局变量等),仅栈区独立资源完全独立(虚拟地址空间隔离)
稳定性一个线程崩溃会导致整个进程崩溃单个进程崩溃不影响其他进程
创建开销仅需开辟独立栈区(8MB),开销极低需创建完整虚拟地址空间(3GB),开销大
并发度高(切换成本低)低(切换需切换地址空间)
通信方式直接读写共享变量(需同步)需 IPC(管道、消息队列、共享内存等)

三、线程编程核心步骤(POSIX 标准)

Linux 线程编程遵循 POSIX 标准(pthread 库),核心流程为:创建多线程线程空间执行任务线程资源回收(线程退出后栈区默认不释放,需手动 / 自动回收)

3.1 线程相关命令(调试 / 监控)

1. 查看线程信息

bash

运行

# 查看线程的PID、PPID、LWP(轻量级进程ID)、状态、命令 ps -eLo pid,ppid,lwp,stat,comm # 更详细的线程信息(含线程ID、CPU占用等) ps -eLf
2. 辅助命令(路径控制)

线程 / 进程的工作路径控制依赖以下函数(常与线程任务结合):

c

运行

// 获取当前工作路径 char *getcwd(char *buf, size_t size); // 参数:buf-存储路径的数组;size-数组最大长度 // 返回值:成功返回buf指针,失败返回NULL // 切换工作路径 int chdir(const char *path); // 参数:path-目标路径(绝对/相对) // 返回值:成功0,失败-1

3.2 线程核心函数(POSIX)

1. 创建线程:pthread_create

c

运行

#include <pthread.h> int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);
  • 功能:创建一个新线程,线程启动后执行start_routine函数;
  • 参数
    • thread:输出参数,存储新线程的 ID(需提前定义);
    • attr:线程属性(如栈大小、分离属性),默认传NULL(使用默认属性);
    • start_routine:线程的执行函数(回调函数),格式为void* 函数名(void*)
    • arg:传给回调函数的参数(void * 类型,可传递任意数据);
  • 返回值:成功返回 0,失败返回错误码(非 0)。
2. 获取当前线程 ID:pthread_self

c

运行

pthread_t pthread_self(void);
  • 功能:获取当前线程的 ID;
  • 返回值:当前线程 ID(类型为unsigned long int,打印用%lu)。
3. 线程退出:pthread_exit

c

运行

void pthread_exit(void *retval);
  • 功能:线程主动退出(替代 return,更适合线程场景);
  • 参数retval:线程退出的返回值(“临死遗言”),可被pthread_join获取;
  • 注意:主线程调用pthread_exit仅退出自身,不影响其他子线程。
4. 取消线程:pthread_cancel

c

运行

int pthread_cancel(pthread_t thread);
  • 功能:主动请求终止指定线程;
  • 参数thread:要取消的线程 ID;
  • 返回值:成功 0,失败非 0;
  • 注意:线程需处于 “可取消状态” 才会响应(默认可取消)。
5. 阻塞回收线程资源:pthread_join

c

运行

int pthread_join(pthread_t thread, void **retval);
  • 功能:阻塞等待指定线程退出,并回收其资源(栈区);
  • 参数
    • thread:要回收的线程 ID;
    • retval:输出参数,存储线程的退出返回值(对应pthread_exit的参数);
  • 返回值:成功 0,失败非 0;
  • 核心特点:若线程未退出,调用者会阻塞,直到线程结束。
6. 设置线程分离属性:pthread_detach

c

运行

int pthread_detach(pthread_t thread);
  • 功能:设置线程为 “分离属性”,线程退出后资源(栈区)由系统自动回收;
  • 参数thread:要设置的线程 ID(可传pthread_self()设置自身);
  • 返回值:成功 0,失败非 0;
  • 核心价值:无需调用pthread_join,避免僵尸线程(线程退出后资源未释放);
  • 注意:设置分离属性后,无法再调用pthread_join回收该线程。

四、线程编程实战示例

4.1 基础示例:创建线程 + 阻塞回收

c

运行

#include <stdio.h> #include <stdlib.h> #include <pthread.h> #include <unistd.h> // 线程执行函数 void* thread_func(void* arg) { char *msg = (char*)arg; printf("子线程ID:%lu,参数:%s\n", pthread_self(), msg); sleep(2); // 线程退出,返回值为"thread exit" pthread_exit((void*)"thread exit"); } int main() { pthread_t tid; int ret; void *retval; // 创建线程 ret = pthread_create(&tid, NULL, thread_func, (void*)"hello thread"); if (ret != 0) { perror("pthread_create failed"); exit(1); } printf("主线程ID:%lu,创建子线程ID:%lu\n", pthread_self(), tid); // 阻塞回收线程,获取返回值 ret = pthread_join(tid, &retval); if (ret != 0) { perror("pthread_join failed"); exit(1); } printf("子线程退出,返回值:%s\n", (char*)retval); return 0; }

4.2 编译 & 运行

bash

运行

# 编译(必须链接pthread库) gcc thread_demo.c -o thread_demo -lpthread # 运行 ./thread_demo

4.3 输出结果

plaintext

主线程ID:140709267896000,创建子线程ID:140709259507456 子线程ID:140709259507456,参数:hello thread 子线程退出,返回值:thread exit

4.4 分离属性示例

c

运行

#include <stdio.h> #include <pthread.h> #include <unistd.h> void* thread_func(void* arg) { // 设置自身为分离属性 pthread_detach(pthread_self()); printf("子线程ID:%lu,执行任务\n", pthread_self()); sleep(2); printf("子线程退出,资源自动回收\n"); pthread_exit(NULL); } int main() { pthread_t tid; pthread_create(&tid, NULL, thread_func, NULL); // 主线程等待3秒,确保子线程执行完成 sleep(3); printf("主线程退出\n"); return 0; }

五、线程编程核心注意事项

  1. 编译必须链接 pthread 库:pthread 是独立库,编译时需加-lpthread,否则报 “undefined reference to pthread_create”;
  2. 资源共享与同步:线程共享进程资源,多线程操作共享变量时需加互斥锁(pthread_mutex),避免数据竞争;
  3. 线程退出方式
    • 子线程可通过pthread_exit主动退出;
    • 主线程用pthread_exit仅退出自身,用exit会终止整个进程;
  4. 资源回收
    • 非分离线程必须调用pthread_join回收,否则会产生 “僵尸线程”;
    • 分离线程无需回收,系统自动释放资源;
  5. 线程安全:避免在多线程中使用非线程安全函数(如strtok),优先使用线程安全版本(如strtok_r)。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/1 6:55:33

【华尔街都在用的风险对冲方法】:基于R语言的GARCH模型实战解析

第一章&#xff1a;金融风险对冲的核心逻辑与GARCH模型概述 在现代金融市场中&#xff0c;资产价格的波动性是影响投资决策和风险管理的关键因素。金融风险对冲的核心逻辑在于通过构建反向头寸或使用衍生工具&#xff0c;抵消潜在的价格不利变动带来的损失。这一过程依赖于对波…

作者头像 李华
网站建设 2026/4/25 0:59:01

检索结果暴露风险频发,你的Dify权限配置做对了吗?

第一章&#xff1a;检索结果的 Dify 权限校验在构建基于 Dify 的智能应用时&#xff0c;确保检索结果的安全性与访问控制至关重要。权限校验机制不仅保护敏感数据不被未授权用户访问&#xff0c;还能根据用户角色动态过滤返回内容。Dify 提供了灵活的权限管理接口&#xff0c;可…

作者头像 李华
网站建设 2026/5/1 10:29:17

【限时收藏】私有化Dify备份最佳实践:7步构建坚不可摧的数据防线

第一章&#xff1a;私有化 Dify 备份策略的核心价值在企业级 AI 应用部署中&#xff0c;Dify 作为一款支持可视化编排与模型集成的低代码平台&#xff0c;其数据资产和配置信息的安全性至关重要。私有化部署环境下&#xff0c;系统管理员需自主掌控数据生命周期&#xff0c;而完…

作者头像 李华
网站建设 2026/4/25 7:27:15

面试数据库八股文五问五答第四期

面试数据库八股文五问五答第四期 作者&#xff1a;程序员小白条&#xff0c;个人博客 相信看了本文后&#xff0c;对你的面试是有一定帮助的&#xff01; ⭐点赞⭐收藏⭐不迷路&#xff01;⭐ 1&#xff09;什么情况下 mysql 会索引失效&#xff1f; 不使用索引列进行查询&a…

作者头像 李华
网站建设 2026/4/25 19:03:53

【RL 】PROCESS REINFORCEMENT THROUGH IMPLICIT RE- WARDS

https://arxiv.org/pdf/2502.01456https://arxiv.org/pdf/2502.01456 &#x1f4a1; PRIME提出通过隐式过程奖励&#xff08;Implicit Process Rewards&#xff09;解决大型语言模型&#xff08;LLM&#xff09;强化学习中稠密奖励&#xff08;dense rewards&#xff09;的在线…

作者头像 李华
网站建设 2026/4/18 2:19:18

LobeChat vs ChatGPT:谁才是真正的开源替代之选?

LobeChat vs ChatGPT&#xff1a;谁才是真正的开源替代之选&#xff1f; 在大语言模型席卷全球的今天&#xff0c;ChatGPT 已经成为智能对话系统的代名词。它的出现不仅重新定义了人机交互的方式&#xff0c;也催生了一波AI应用开发热潮。然而&#xff0c;当企业开始将这类技术…

作者头像 李华