新闻详情

新闻详情

首页 / 资讯中心 / 详情

Linux多线程

发布时间:2026/9/3 5:58:58来源:尧图网络
Linux多线程
1.线程一个进程里面可以分出多条执行小路每一条小路就是一个线程。把进程看作一栋房子房子进程拥有完整配套资源水电、家具、空间内存地址空间线程就是房子里不同干活的人每个人私有自己手上的笔记本栈、寄存器所有人共享这套房子的全部东西堆、全局变量、文件一个人出事线程崩溃整栋房子直接报废进程退出// pthread_create.c #include stdio.h #include stdlib.h #include unistd.h #include string.h #include pthread.h //子线程执行代码 void* working(void* arg) { printf(子线程ID%ld\n, pthread_self()); for (int i 0; i 3; i) { printf(child%d\n, i); } } int main() { //创建一个子线程 pthread_t tid; pthread_create(tid, NULL, working, NULL); //父线程执行代码 printf(父线程ID%ld\n, pthread_self()); for (int i 0; i 3; i) { printf(father%d\n, i); } while (1) { sleep(2); } return 0; }线程退出#include pthread.hvoid pthread_exit(void *retval);参数指针指向线程退出时携带的数据线程回收#include pthread.h // 这是一个阻塞函数, 子线程在运行这个函数就阻塞 // 子线程退出, 函数解除阻塞, 回收对应的子线程资源, 类似于回收进程使用的函数 wait() int pthread_join(pthread_t thread, void **retval);一次只能回收一个二级指针。pthread_exit() 传递出的数据的地址的地址回收子线程数据在子线程退出的时候可以使用pthread_exit()的参数将数据传出在回收这个子线程的时候可以通过phread_join()的第二个参数来接收子线程传递出的数据。void*万能指针只保存地址编译器不知道这个地址上放的是什么类型的数据不知道是 int、字符串还是结构体使用子线程栈// pthread_join.c #include stdio.h #include stdlib.h #include unistd.h #include string.h #include pthread.h // 定义结构 struct Persion { int id; char name[36]; int age; }; // 子线程的处理代码 void* working(void* arg) { printf(我是子线程, 线程ID: %ld\n, pthread_self()); for(int i0; i9; i) { printf(child i: %d\n, i); if(i 6) { struct Persion p; p.age 12; strcpy(p.name, tom); p.id 100; // 该函数的参数将这个地址传递给了主线程的pthread_join() pthread_exit(p); } } return NULL; // 代码执行不到这个位置就退出了 } int main() { // 1. 创建一个子线程 pthread_t tid; pthread_create(tid, NULL, working, NULL); printf(子线程创建成功, 线程ID: %ld\n, tid); // 2. 子线程不会执行下边的代码, 主线程执行 printf(我是主线程, 线程ID: %ld\n, pthread_self()); for(int i0; i3; i) { printf(i %d\n, i); } // 阻塞等待子线程退出 void* ptr NULL; // ptr是一个传出参数, 在函数内部让这个指针指向一块有效内存 // 这个内存地址就是pthread_exit() 参数指向的内存 pthread_join(tid, ptr); // 打印信息 struct Persion* pp (struct Persion*)ptr; printf(子线程返回数据: name: %s, age: %d, id: %d\n, pp-name, pp-age, pp-id); printf(子线程资源被成功回收...\n); return 0; }子线程函数里构造结构体拿到这块数据的内存地址0xaaapthread_exit( (void*)0xaaa )把子线程退出返回值设置成结构体数据的地址主线程定义一级指针void *ptr NULL;调用pthread_join(tid, ptr)ptr是ptr 变量自身的地址二级指针仅函数内部使用函数内部改写主线程的 ptrptr 0xaaa执行完 join 之后ptr 就是保存结构体数据地址的一级指针struct Persion *pp (struct Persion *)ptr;pp同样是结构体类型的一级指针强制转换不是为了 “匹配 ptr 本身存储的值地址数字不变”而是给编译器补充内存类型信息ptr 是无类型万能指针void*编译器不知道这块内存布局强转为struct Persion*之后编译器才认识-name / -age这种结构体成员访问语法。ptr和pp两个变量存完全相同的内存编号 0xaaa唯一区别指针类型不一样但是代码有问题p是子线程栈局部变量当pthread_exit执行完 →子线程销毁子线程的整个栈全部释放回收地址0xaaa已经变成无效内存 主线程后面通过pp去访问一块已经释放掉的内存 →野指针结果不可控随机垃圾值得到的数据会是乱码位于同一虚拟地址空间中的线程虽然不能共享栈区数据但是可以共享全局数据区和堆区数据因此在子线程退出的时候可以将传出数据存储到全局变量、静态变量或者堆内存中。在下面的例子中将数据存储到了全局变量中使用主线程栈#include stdio.h #include stdlib.h #include unistd.h #include string.h #include pthread.h struct person { int id; int age; }; void* working(void* arg) { //在子线程里面直接修改p //新建一个结构体指针p用来接受arg struct person* p (struct person*)arg; printf(我是子线程, 线程ID: %ld\n, pthread_self()); for (int i 0; i 9; i) { printf(child i: %d\n, i); if (i 6) { //使用主线程栈内存 p-age 12; p-id 10; pthread_exit(p);//把同一个地址再次作为返回值传出 } } return NULL; } int main() { //创建一个子线程 pthread_t pid; struct person p; //主线程栈内存传递给子线程 pthread_create(pid, NULL, working, p);//p就是working函数里面的arg printf(子线程创建成功, 线程ID: %ld\n, pid); // 2. 子线程不会执行下边的代码, 主线程执行 printf(我是主线程, 线程ID: %ld\n, pthread_self()); for (int i 0; i 3; i) { printf(i %d\n, i); } // 阻塞等待子线程退出 void* ptr NULL; // ptr是一个传出参数, 在函数内部让这个指针指向一块有效内存 // 这个内存地址就是pthread_exit() 参数指向的内存 pthread_join(pid, ptr); // 打印信息 printf(age: %d, id: %d\n,p.age, p.id); printf(子线程资源被成功回收...\n); return 0; }实现思路主线程在自己的栈上定义结构体变量struct Persion p创建子线程把主线程局部变量 p 的地址传给子线程函数子线程通过这个地址直接修改主线程栈上这块结构体的数据子线程执行到 i6 时调用pthread_exit(p)把同一个地址再次作为返回值传出主线程用pthread_join阻塞等待子线程结束回收线程资源主线程直接打印自己栈上变量p的值拿到子线程修改后的结果。线程分离pthread_detach()分离后主线程可以继续自己的操作线程取消pthread_cancel主线程调用线程取消函数只要在子线程中进行了系统调用当子线程执行到这个位置就挂掉了。关于系统调用有两种方式直接调用Linux系统函数调用标准C库函数为了实现某些功能在Linux平台下标准C库函数会调用相关的系统函数线程ID比较pthread_equal
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

【Bonjour】从《我的女友景甜》小作文到实现一个简易区块链:原理与Python代码详解 2026/9/3 6:59:07

【Bonjour】从《我的女友景甜》小作文到实现一个简易区块链:原理与Python代码详解

我沉默了 他以为我不想来~~~~一、一场精心策划的流量收割 2026年8月27日晚,波场TRON创始人孙宇晨(币圈人送外号"孙割")在外网发了一篇六千字长文《我的女友景甜》。同一天,他的律师已向法院递交诉状,起诉景甜…

阅读更多 →
老款英特尔Mac安装Windows驱动指南:BootCamp 6.1.7071.zip详解与避坑 2026/9/3 6:59:06

老款英特尔Mac安装Windows驱动指南:BootCamp 6.1.7071.zip详解与避坑

简介:本资源是苹果官方Boot Camp 6.1.7071驱动与辅助软件安装包,专为2018–2019年款带Touch Bar的MacBook Pro机型设计,覆盖13英寸四端口、13英寸及15英寸带触控条等主流型号,解决Windows系统在新款Mac硬件上无法识别键盘背光、触…

阅读更多 →
Delphi EhLib控件库深度解析:无源码版本集成与实战应用指南 2026/9/3 6:59:06

Delphi EhLib控件库深度解析:无源码版本集成与实战应用指南

简介:本资源是专为Delphi 13.1开发者打造的EhLib.VclFmx 13.0.015增强控件库,面向中高级Windows桌面与跨平台应用开发者,解决VCL/FMX项目中数据感知、界面美化及快速集成等核心开发痛点。压缩包含2000个文件,总计349.63MB&#xf…

阅读更多 →
220kV 变电站创优配套安全生产动画制作要点 2026/9/3 6:59:06

220kV 变电站创优配套安全生产动画制作要点

安全生产动画不只是单纯培训素材,也可以纳入变电站创优工程安全文明施工佐证资料,不少电力建设单位容易忽略这一点。长沙尚格影视以汨罗西 220kV 变电站国网优质工程金银奖申报配套影像项目为例,聊聊创优项目安全生产动画该怎么做。汨罗西 22…

阅读更多 →
基于SpringBoot的网课订阅与用户管理系统 2026/9/3 6:59:06

基于SpringBoot的网课订阅与用户管理系统

1. 项目背景与意义随着在线教育的快速发展,网课平台的数量和规模持续增长,用户对课程订阅、学习进度管理和个性化内容推荐的需求日益强烈。传统的手工管理方式在课程上架、订阅记录、用户权限控制等方面效率低下,难以支撑大规模并发访问和精细…

阅读更多 →
Python实现Markdown到Word格式转换:PasteMD工具开发全解析 2026/9/3 6:56:06

Python实现Markdown到Word格式转换:PasteMD工具开发全解析

简介:PasteMD 是一款面向程序员、技术文档撰写者及办公效率追求者的 Python 桌面工具,专为解决 Markdown、网页富文本及 AI 对话内容在 Word/WPS/Excel 中排版失真、粘贴繁琐的痛点而设计。它通过常驻系统托盘一键触发机制,结合 Pandoc 实现高…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞