news 2026/2/18 2:40:11

进程ID比较与传参

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
进程ID比较与传参

文章目录

  • pthread_equal()
    • 函数原型
      • 参数
      • 返回值
  • 线程参数传递
    • 传递指针
      • 优点
      • 注意事项
        • 数据生命周期管理
        • 多线程并发访问
    • 传递整型参数
      • 方式一:直接强制转换
      • 方式2:使用 intptr_t / uintptr_t(C99标准推荐)
      • 方式3:为单个整数动态分配内存
    • 传递复杂数据
      • 方式1:定义结构体
      • 方式2:为每个线程动态分配独立结构
    • 传参选择依据

pthread_equal()

  • POSIX标准只定义了线程相关数据类型的接口行为,没有规定其内部实现。在不同的操作系统或架构上:
    • pthread_t 可能是:unsigned long(Linux x86_64)、结构体指针(某些BSD系统)、整数索引等
    • 互斥锁、条件变量等可能有不同的内部布局
  • pthread_equal() 是 Pthreads 标准中专门用于比较两个线程 ID(pthread_t 类型)是否相等的函数,解决了 pthread_t 类型跨平台兼容性问题(避免直接用 == 比较的风险)
  • “不透明”的数据类型:
数据类型描述
pthread_t线程 ID
pthread_mutex_t互斥对象(mutex)
pthread_mutexattr_t互斥属性对象
pthread_cond_t条件变量(condition variable)
pthread_condattr_t条件变量的属性对象
pthread_key_t线程特有数据的键(Key)
pthread_once_t一次性初始化控制上下文(control context)
pthread_attr_t线程的属性对象

函数原型

#include<pthread.h>intpthread_equal(pthread_tt1,pthread_tt2);

参数

  • 要比较的线程 ID,如pthread_self()返回值、pthread_create输出的 ID

返回值

  • 非 0 值:t1 和 t2 指向同一个线程
  • 0:两个线程 ID 不相等
// 错误:不可移植if(tid1==tid2){...}// 正确:可移植if(pthread_equal(tid1,tid2)!=0){...}// 检查当前线程是否是特定线程if(pthread_equal(pthread_self(),main_thread_id)!=0){// 这是主线程}

线程参数传递

  • 线程参数传递主要涉及两种方式:
    • 传递指针:传递变量的地址(或字符串常量地址)
    • 传递整数值:将整数值直接转换为指针传递

传递指针

#include<pthread.h>#include<stdio.h>#include<stdlib.h>#include<errno.h>void*func(void*arg){char*str=(char*)arg;printf("%s\n",str);pthread_exit(NULL);}intmain(intargc,constchar*argv[]){pthread_ttid;char*str="Hello Thread!";intret=pthread_create(&tid,NULL,func,str);if(ret!=0){errno=ret;perror("pthread_create");exit(EXIT_FAILURE);}ret=pthread_join(tid,NULL);if(ret!=0){errno=ret;perror("pthread_create");exit(EXIT_FAILURE);}return0;}

优点

  • 可以传递任意复杂的数据结构
  • 传递效率高(只传指针,不拷贝数据)
  • 符合 void* 指针的设计初衷

注意事项

数据生命周期管理
// 危险:传递局部变量的地址voidcreate_thread(){charbuffer[64];// 栈上分配sprintf(buffer,"Thread data");pthread_create(&tid,NULL,func,buffer);// 函数返回时buffer被释放,但线程可能还在访问!}// <- 这里buffer的栈内存被回收!// 安全做法1:传递全局/静态变量staticcharbuffer[64];// 或全局变量voidcreate_thread(){sprintf(buffer,"Thread data");pthread_create(&tid,NULL,func,buffer);}// 安全做法2:动态分配voidcreate_thread(){char*buffer=malloc(64);sprintf(buffer,"Thread data");pthread_create(&tid,NULL,func,buffer);// 在线程函数中必须free!}// 安全做法3:传递字符串常量(只读段)pthread_create(&tid,NULL,func,"Constant string");
多线程并发访问
// 危险:多个线程共享同一数据指针intshared_data=0;for(inti=0;i<5;i++){// 所有线程都收到 &shared_data 的指针pthread_create(&tids[i],NULL,func,&shared_data);}// 线程间会竞争修改shared_data,需要同步机制!

传递整型参数

方式一:直接强制转换

#include<pthread.h>#include<stdio.h>#include<stdlib.h>#include<errno.h>void*func(void*arg){printf("arg:%d\n",(int)arg);pthread_exit(NULL);}intmain(intargc,constchar*argv[]){pthread_ttid;inta=10;intret=pthread_create(&tid,NULL,func,a);if(ret!=0){errno=ret;perror("pthread_create");exit(EXIT_FAILURE);}ret=pthread_join(tid,NULL);if(ret!=0){errno=ret;perror("pthread_create");exit(EXIT_FAILURE);}return0;}
  • 可以工作但是编译会报警告:
    • 可移植性问题:如果int和指针大小不同(如int是32位,指针是64位),转换可能丢失精度
    • 类型安全问题:绕过了类型系统,编译器无法检查
    • 标准未定义:C标准不保证这种转换的行为
  • 严格说来,对于intvoid*之间相互强制转换的后果,C语言标准并未加以定义。不过,大部分C语言编译器允许这样的操作,并且也能达成预期的目的

方式2:使用 intptr_t / uintptr_t(C99标准推荐)

#include<stdint.h>// 包含intptr_t的定义// 传递inta=10;pthread_create(&tid,NULL,func,(void*)(intptr_t)a);// 接收void*func(void*arg){intvalue=(int)(intptr_t)arg;// 先转intptr_t,再转int}
  • C99标准定义的有符号整数类型intptr_t,保证可以安全地存储指针值(转换为整数再转回指针不变)
  • 大小与指针相同,解决了可移植性问题

方式3:为单个整数动态分配内存

  • 过渡设计但安全
// 传递int*p=malloc(sizeof(int));*p=10;pthread_create(&tid,NULL,func,p);// 在线程函数中free(p)// 接收void*func(void*arg){intvalue=*(int*)arg;free(arg);// 得释放!// ...}

传递复杂数据

方式1:定义结构体

typedefstruct{intid;constchar*name;intpriority;void*device_handle;}ThreadParams;// 传递ThreadParams params={1,"SensorReader",10,dev_handle};pthread_create(&tid,NULL,sensor_thread,&params);// 注意:params必须是全局的或动态分配的// 如果params是局部变量,确保线程在函数返回前已使用完数据

方式2:为每个线程动态分配独立结构

for(inti=0;i<NUM_THREADS;i++){ThreadParams*params=malloc(sizeof(ThreadParams));params->id=i;params->name=thread_names[i];params->priority=priorities[i];pthread_create(&tids[i],NULL,worker_thread,params);// 在线程函数中free(params)}

传参选择依据

数据类型推荐方法代码示例注意事项
字符串常量直接传递pthread_create(..., "string")只读,安全
单个整数intptr_t转换(void*)(intptr_t)value可移植,简洁
单个指针直接传递(void*)&data注意生命周期
多个参数结构体指针(void*)&params结构体需全局或动态分配
大量数据传递数据指针(void*)large_buffer考虑拷贝开销 vs 共享风险
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/2/7 1:46:45

RabbitMQ实现异步任务分发,提升IndexTTS 2.0排队处理能力

RabbitMQ 实现异步任务分发&#xff0c;提升 IndexTTS 2.0 排队处理能力 在当前 AIGC 技术爆发式发展的背景下&#xff0c;语音合成已不再是实验室里的“黑科技”&#xff0c;而是广泛应用于视频创作、虚拟主播、有声读物等真实场景的核心工具。B站开源的 IndexTTS 2.0 凭借其高…

作者头像 李华
网站建设 2026/1/30 18:26:20

【R语言智能编码新纪元】:如何用GPT在10分钟内完成一周工作量

第一章&#xff1a;R语言与GPT融合的智能编码时代人工智能正以前所未有的速度重塑编程实践&#xff0c;而R语言作为统计计算与数据科学的核心工具&#xff0c;正在与大型语言模型&#xff08;如GPT系列&#xff09;深度融合&#xff0c;开启智能编码的新纪元。这一融合不仅提升…

作者头像 李华
网站建设 2026/2/13 23:08:15

虚拟骑行自由之路:构建无网络依赖的训练天堂

在数字时代&#xff0c;运动训练正经历着一场静默革命。当传统在线平台因网络波动而频频中断时&#xff0c;一种全新的解决方案正在悄然兴起——本地化虚拟骑行系统。这不仅是一次技术突破&#xff0c;更是对个人训练自主性的重新定义。 【免费下载链接】zwift-offline Use Zwi…

作者头像 李华
网站建设 2026/2/13 20:12:49

R语言ggplot2多图组合实战(间距调整终极指南)

第一章&#xff1a;R语言ggplot2多图组合实战&#xff08;间距调整终极指南&#xff09;在数据可视化项目中&#xff0c;常常需要将多个ggplot2图形组合成一张综合图表。灵活控制图形间的间距是实现专业排版的关键环节。本章介绍几种高效方法&#xff0c;帮助用户精确调整多图布…

作者头像 李华
网站建设 2026/2/4 9:38:57

【判别分析效率提升10倍】:R语言多元统计建模的黄金法则

第一章&#xff1a;判别分析在多元统计中的核心地位判别分析作为多元统计分析的重要工具&#xff0c;广泛应用于分类、模式识别与决策支持等领域。其核心目标是基于一组可观测变量&#xff0c;构建最优分类规则&#xff0c;将观测对象划分到预定义的类别中。该方法不仅具备良好…

作者头像 李华
网站建设 2026/2/16 18:12:45

Windows 11 LTSC系统微软商店缺失问题解决方案

Windows 11 LTSC系统微软商店缺失问题解决方案 【免费下载链接】LTSC-Add-MicrosoftStore Add Windows Store to Windows 11 24H2 LTSC 项目地址: https://gitcode.com/gh_mirrors/ltscad/LTSC-Add-MicrosoftStore Windows 11 LTSC版本以其卓越的稳定性和长期支持特性深…

作者头像 李华