pthread_create()函数参数详解和传参的使用

QT实战——多线程学习笔记(一) QT实战——多线程学习之POSIX线程库的学习 阅读详情

题外话:

用的vscode编译的程序。发现一个问题,就是编译的时候提示没有gcc,但是应该是安装了的。打开命令端,输入gcc -v,提示没有gcc。
因为安装了qt。默认的就有gcc,所以就打开qt的安装路径下C:\Qt\Qt5.12.4\Tools\mingw730_64\bin,路径下文件如下图所示
在这里插入图片描述
然后直接把该路径添加到环境变量,就可以使用gcc 和g++了
贼有意思,gcc也能编译,g++也能编译。
在linux下通过gcc编译c程序,g++编译c++程序,另外就是也没有加-lpthread连接线程库就编译通过了。
sleep函数使用的头文件<unistd.h>也可以编译通过,也就是说,并没有使用windows的库。

在这里插入图片描述


正题:

pthread_create是UNIX环境创建线程函数
头文件  #include<pthread.h>
函数声明   int pthread_create(pthread_t*restrict tidp,const pthread_attr_t
restrict_attr,void(start_rtn)(void),void *restrict arg);
返回值   若成功则返回0,否则返回出错编号   返回成功时,由tidp指向的内存单元被设置为新创建线程的线程ID。attr参数用于制定各种不同的线程属性。新创建的线程从start_rtn函数的地址开始运行,该函数只有一个万能指针参数arg,如果需要向start_rtn函数传递的参数不止一个,那么需要把这些参数放到一个结构中,然后把这个结构的地址作为arg的参数传入。   linux下用C开发多线程程序,Linux系统下的多线程遵循POSIX线程接口,称为pthread。   由 restrict 修饰的指针是最初唯一对指针所指向的对象进行存取的方法,仅当第二个指针基于第一个时,才能对对象进行存取。对对象的存取都限定于基于由 restrict 修饰的指针表达式中。 由 restrict 修饰的指针主要用于函数形参,或指向由 malloc() 分配的内存空间。restrict 数据类型不改变程序的语义。 编译器能通过作出 restrict 修饰的指针是存取对象的唯一方法的假设,更好地优化某些类型的例程。 参数   第一个参数为指向线程标识符的指针。   第二个参数用来设置线程属性。   第三个参数是线程运行函数的起始地址。   最后一个参数是运行函数的参数。   另外,在编译时注意加上-lpthread参数,以调用静态链接库。因为pthread并非Linux系统的默认库 示例   打印线程 IDs

	#include <pthread.h>
  #include <stdlib.h>
  #include <stdio.h>
  #include <unistd.h>
  #include <string.h>
  pthread_t ntid;
  void printids(const char *s)
  {
  pid_t pid;
  pthread_t tid;
  pid = getpid();
  tid = pthread_self();
  printf("%s pid %u tid %u (0x%x)\n", s,
  (unsigned int)pid, (unsigned int)tid, (unsigned int)tid);
  } void *thr_fn(void *arg)
  {
  printids("new thread: ");
  return((void *)0);
  }
  int main(void)
  {
  int err;
  err = pthread_create(&ntid, NULL, thr_fn, NULL);
  if (err != 0)
  printf("can't create thread: %s\n", strerror(err));
  printids("main thread:");
  sleep(1);
  exit(0);
  }
  $ gcc main.c -lpthread
  $ ./a.out


向线程函数传递参数详解:

向线程函数传递参数分为两种:

(1)线程函数只有一个参数的情况:直接定义一个变量通过应用传给线程函数。

例子:

#include <iostream>
#include <pthread.h>
using namespace std;
pthread_t thread;
void fn(void *arg)
{
    int i = *(int *)arg;
    cout<<"i = "<<i<<endl;
    return ((void *)0);
}
int main()
{
    int err1;
    int i=10;
   err1 = pthread_create(&thread, NULL, fn, &i);
    pthread_join(thread, NULL);
}

2、线程函数有多个参数的情况:这种情况就必须申明一个结构体来包含所有的参数,然后在传入线程函数,具体如下:

例子:
首先定义一个结构体:



struct  parameter

{
  int size,
  int count;
};

然后在main函数将这个结构体指针,作为void *形参的实际参数传递

struct parameter arg;

通过如下的方式来调用函数:

pthread_create(&ntid, NULL, fn,& (arg));

函数中需要定义一个parameter类型的结构指针来引用这个参数

void fn(void *arg)
{
    int i = *(int *)arg;
    cout<<"i = "<<i<<endl;
    return ((void *)0);
}


void thr_fn(void *arg)
{
       struct parameter *pstru;
       pstru = ( struct parameter *) arg;
       然后在这个函数中就可以使用指针来使用相应的变量的值了。
}

**

具体实例

**
主要解决以下三个问题
1.普通传参(只传一个参数)
2.结构体传参(传多个参数)

  1. 普通传参(只传一个参数)
    函数功能介绍,主线程一个while循环,等待变量的值,如果等于10就打印一句话。新创建的线程首先拿到传递过来的参数,然后再给参数赋值(相当于主线程已经等到了要的值)
#include <stdio.h>
#include <pthread.h>
#include <time.h>
#include <unistd.h>
//int sum = 0;

void *test(void *arg)
{
    printf("arg= %d\n",*(int *)arg);
     //int sum = *(int *)arg;
     int temp_run=1;
     temp_run = *(int *)arg;
     printf("tem_run= %d\n",temp_run);
    *(int *)arg = 10;
     temp_run = *(int *)arg;
    //sum = sum + 1;
     while(temp_run){
         temp_run --;
         if(temp_run == 2)
            printf("tem_run= %d\n",temp_run);
     }
}

int main()
{
    pthread_t pthread_id;
    int sum = 0;//局部变量,在main函数中,main没有结束,就不会释放。main是一个进程吗?一次执行过程
    int run = 1;
    int time = 10;
    int ret = -1;
    /*if(pthread_create(&pthread_id,NULL,test,&sum) != 0)
        printf("create error\n");
    */
   ret = pthread_create(&pthread_id,NULL,test,&sum);
   printf("ret = %d\n",ret);
    while(run)
    {
       /* 
            if(sum != time)
            sum++;
        */
       if(sum == time)
       {
        printf("------run end------\n");
            run = 0;
       }
    }

    //pthread_create(&pthread_id,NULL,test,&sum);//在while循环后创建线程,能执行到创建这一句吗?
    //sleep(5);//没有打印出来线程里的消息,是因为主线程已经结束了。睡眠五秒可以解决。另外一般都是调用ptread_join()
    pthread_join(pthread_id,NULL);//阻塞等待当前线程
    printf("sum=%d,run=%d,time=%d\n",sum,run,time);
    pthread_exit(&pthread_id);//结束当前线程,释放私有资源
    return 0;

}

上述代码注意的问题
1.创建线程的的位置,如果run函数的起始值为1,是不能再while后创建线程的,因为走不到创建线程这个位置。如果起始值为0,是可以用上述代码的。不然要把注释部分打开,吧下边的创建关闭。另外线程一旦创建,就不会存在while循环卡住的问题了,在线程内部开while是照样可以运行下边的话。线程是个并行的关系
2、关于局部变量问题。在线程中为传入的参数赋值了,赋值的时候注意是直接给传入进来的指针赋值,而不是将指针的值拿到修改,此时修改了之后,并没有传递回去,除非是全局变量。如果传入的形参是全局变量是可以的。在这里发现main的局部变量就是相当于全局变量? 另外全局变量可能会被局部变量覆盖,第一次的时候发现在线程处理函数中给sum赋值的时候,提示未定义,就直接定义了一个sum,此时的sum和自己想要的sum并不是一个,这个是局部变量。使用的时候就算赋值,也只是操作的局部变量
3.另外线程创建的时候要注意调用线程回收ptread_join。不然主线程会提前结束的话,线程处理函数可能来不及运行完。去掉线程回收函数,会发现线程中的打印都没有来得及打印就结束了。线程结束后调用线程退出函数pthread_exit,完成线程资源的回收

2.结构体传参(传多个参数)
函数功能介绍:
创建线程的时候,传递一个结构体,然后子线程中打印传入结构体的值,然后再给传入的参数赋值,有两种方式,一种是结构体整个赋值,一种是值对其中一个成员赋值,只对一个成员赋值效率较低。

#include <stdio.h>
#include <pthread.h>
#include <time.h>
#include <unistd.h>
//int sum = 0;
   typedef struct test
    {
        /* data */
        int test1;
        int test2;
    }TEST;
   
void *test(void *arg)
{
    //printf("arg= %d\n",*(int *)arg);
     //int sum = *(int *)arg;
    TEST *temp = (TEST *)arg; //强制类型转换,不加编译不过去
    temp->test1 = 10;
    temp->test2 = 111;
    printf("test1 = %d,test2 = %d\n",temp->test1,temp->test2);
  // (TEST *) arg->test1 = 10;//失败
    // arg->test1 = 10;//错误代码
  //  * (TEST *) arg.test1 = 10;//错误代码
  //  ((int *)(arg))->test1 = 10;//错误代码
    *( (int *) ( ( (TEST *) arg) -> test1 ) ) = 10;//成功,将参数转换成具体数据类型的指针,然后将指针成员转换成对应的具体数据类型,然后给其赋值。相对于下边的实现方法,贼卡,明显感觉处理速度慢
  //  *(TEST *)  arg = *temp;//成功,先给一个结构体指针赋值,在吧该结构体的赋值给参数结构体,记得类型转换。要加*(是内容的赋值,并不是地址赋值)
}

int main()
{
    pthread_t pthread_id;
    int run = 1;
    int time = 10;
    int ret = -1;
    TEST test_struct;
    /*if(pthread_create(&pthread_id,NULL,test,&sum) != 0)
        printf("create error\n");
    */
   ret = pthread_create(&pthread_id,NULL,test,&test_struct);
   printf("ret = %d\n",ret);
    while(run)
    {
       /* 
            if(sum != time)
            sum++;
        */
       if(test_struct.test1 == time)
       {
        printf("------run end------\n");
            run = 0;
       }
    }

    //pthread_create(&pthread_id,NULL,test,&sum);//在while循环后创建线程,能执行到创建这一句吗?
    //sleep(5);//没有打印出来线程里的消息,是因为主线程已经结束了。睡眠五秒可以解决。另外一般都是调用ptread_join()
    pthread_join(pthread_id,NULL);
    printf("run=%d,time=%d\n",run,time);
    pthread_exit(&pthread_id);
    return 0;

}
linux中的线程局部存储(TLS)实现线程间的同步和互斥pthread_key_create、pthread_setspecific、pthread_getspecific 由于线程局部存储是基于操作系统的特性,因此它可能会受到操作系统实现的影响。不同的操作系统可能会有不同的线程局部存储实现和限制。 阅读详情

相关推荐

从零到一:华为iMaster NCE-Campus部署中的Euler OS与FusionInsight深度解析

本文深入解析华为iMaster NCE-Campus部署中Euler OS与FusionInsight的关键技术要点,包括RAID配置、网络绑定技术、安装避坑指南及性能调优方案。通过实战经验和详细配置示例,帮助工程师提升部署效率与系统稳定性,确保华为企业级解决方案的高效运行。

f6g7h8i9j的博客 549

pthread_create函数详解(向线程函数传递参数)

一、pthread_create函数: 1、简介:pthread_create是UNIX环境创建线程的函数 2、头文件:#include &lt;pthread.h&gt; 3、函数声明: int pthread_create(pthread_t* restrict tidp,const pthread_attr_t* restrict_attr,void* (*start_rtn)(vo.........

mijichui2153的博客 16万+

Springboot计算机毕业设计校园树洞微信小程序【附源码】开题+论文+mysql+程序+部署

因此,开发一款专门针对校园用户的树洞微信小程序,为学生提供一个安全、私密、便捷的倾诉和交流平台,具有重要的现实意义和应用价值。通过本研究的实施,我们预期能够开发出一款功能全面、操作便捷的校园树洞微信小程序,为校园师生提供一个安全、私密、便捷的倾诉和交流平台。此外,通过不断优化和改进小程序的功能和服务,我们预期能够提升用户体验和满意度,推动校园树洞小程序的持续发展,并为校园生活的和谐与健康发展做出积极贡献。同时,通过不断优化小程序的功能和服务,提升用户体验和满意度,推动校园树洞小程序的广泛应用和持续发展。

光冯毕设程序 1666

【多线程编程学习笔记3】创建线程函数pthread_create()详解

申明:本学习笔记是在该教程的基础上结合自己的学习情况进行的总结,不是原创,想要看原版的请看C语言中文网的多线程编程(C语言+Linux),该网站有很多好的编程学习教程,尤其是关于C语言的。 前面章节中,我们通过调用 pthread_create() 函数成功创建了多个线程,本节就给大家详细讲解 pthread_create() 函数的用法。 pthread_create() 函数声明在<pthread.h>头文件中,语法格式如下: int pthread_create(pthread_t *.

qq_41854911的博客 1万+

保姆级教程:在PX4 Gazebo仿真中为Iris无人机挂载Intel D435i深度相机(含完整配置流程)

本文提供在PX4 Gazebo仿真环境中为Iris无人机挂载Intel D435i深度相机的完整配置流程,涵盖环境准备、模型部署、插件安装及调试技巧。通过详细步骤和常见问题解决方案,帮助开发者快速搭建深度相机仿真环境,适用于无人机视觉开发与算法测试。

weixin_28688385的博客 338

关于Selenium3在MicrosoftEdge浏览器中出现的问题

前言 最近在做web自动化测试,所用环境是java+selenium3.141.59+MicrosoftEdge(Chromium)浏览器。 在调试的过程中,出现了很多问题。比如selenium3在Edge浏览器中远程调用中,不支持addArguments方法等 问题 1.Edge浏览器弹窗问题 在测试过程中,会出现弹出窗提示 ...

zhucheng1994的博客 2197

pthread_create函数详解

是POSIX标准线程库中的一个函数,用于创建新线程。在C语言中,多线程编程成为了许多程序员必备的技能之一,而则是实现多线程的关键之一。通过本文对函数的详细解析,我们深入了解了其基本用法、参数说明以及使用示例。作为C语言中实现多线程的重要函数,为程序员提供了强大的多线程编程工具。

聚娃科技开发者博客 5701

SimMechanics二连杆仿真避坑指南:Solid模块坐标系设置与Rigid Transform常见错误

本文详细解析了SimMechanics中二连杆平面臂仿真的常见问题,重点探讨Solid模块坐标系设置与Rigid Transform模块的配置陷阱。通过实战案例和MATLAB代码示例,揭示多体系统仿真中的关键错误点,包括坐标系方向定义、参数匹配、端口连接规则等,帮助工程师有效规避仿真风险,提升建模效率。

weixin_29309213的博客 412

多线程操作 pthread_create pthread_join

进程是表示资源分配的基本单位,又是调度运行的基本单位。例如,用户运行自己的程序,系统就创建一个进程,并为它分配资源,包括各种表格、内存空间、磁盘空间、I/O设备等。然后,把该进程放人进程的就绪队列。进程调度程序选中它,为它分配CPU以及其它有关资源,该进程才真正运行。所以,进程是系统中的并发执行的单位。在Mac、Windows NT等采用微内核结构的操作系统中,进程的功能发生了变化:它只是资源分配的基本单位,而不再是调度运行的单位。在微内核系统中,真正调度运行的基本单位是线程。

TyearLin的专栏 4927

数字人接大模型第二步:语音克隆

推荐XTTS-v2项目,由Coqui公司开发的语音生成模型,专为多语言语音克隆和生成设计。它支持17种语言,包括英语、西班牙语、法语、德语、意大利语、葡萄牙语、波兰语、土耳其语、俄罗斯语、荷兰语、捷克语、阿拉伯语、中文、日语、匈牙利语、韩语和印地语。XTTS-v2的核心优势在于其仅需6秒的音频片段即可实现语音克隆,无需大量的训练数据。此外,它还支持情感和风格转移、跨语言语音克隆以及多语言语音生成,采样率高达24kHz。地址:https://github.com/archwesome/XTTS-v2。

404

Android 车载应用之快速入门

车载 Android 系统也被称为 Android Automotive OS,是对原始 Android 系统的一个功能扩充版本。与手机系统一样,Android Automotive OS 源代码完全开放,第三方供应商和汽车制造商可以官方源码的基础上自行开发和拓展,无论是编程语言还是各项接口,都与 Android 系统保持了一致。

xiangzhihong8的专栏 1112

linux 多线程传参问题(使用phread_create() 传参问题)

在使用pthread create()函数创建线程时,我们通常会将需要传递给新线程的参数打包到一个结构体中,然后传递这个结构体的地址12。这是因为pthread_.create()函数的第四个参数是一个void*类型,也就是一个万能指针3。这个指针可以指向任何类型的数据,包括结构体。 然而,如果我们直接传递一个变量的地址(例如局部变量),可能会遇到问题。这是因为局部变量在函数返回后会被销毁,而新线程可能会在该函数返回后才开始运行。这样,新线程就可能访问到已经被销毁的内存,导致未定义的行为4。 因此,我们通常

C++ 是一门不原谅粗心的语言,而我恰好喜欢这种不原谅。 我是 x,正在成为更严谨的 C++ 开发工程师的路上。 1800

新能源汽车电池及充电原理详解

本文详细介绍了新能源汽车的电池包结构、铅酸电池充放电原理,以及交流和直流充电的工作原理和优缺点。内容涵盖电池串联并联原因、充电设备如车载充电机、交流充电桩和直流充电桩的介绍,以及不同充电模式的连接方式。通过对充电过程的深入探讨,有助于读者理解新能源汽车的充电技术。

让你爱上电路设计 4526

pthread_create pthread_join 传参

一:pthread_create 进程创建 void*t1(void* v){ } int n=1; pthread_t tid1; int* niters=&n; pthread_create(&tid1, NULL, t1, (void*) niters); &tid1----进程号地址 t1–线程所指函数名,注意 t1 的返回值由 pthread_create ...

藏经阁 591

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

pthread_create 创建线程,传递参数

pthread_create是UNIX环境创建线程函数 头文件   #include&lt;pthread.h&gt; 函数声明   int pthread_create(pthread_t*restrict tidp,const pthread_attr_t *restrict_attr,void*(*start_rtn)(void*),void *restrict arg); 返回值   ...

jacklin_01的博客 1708

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

Linux多线程编程pthread_create传参的问题

但是我们传入值时,此时编译会出现报警,提示:从指针强制转换为不同大小的整数,这是由于void * 和 int 类型的长度是不一致的,我们可以通过打印 sizeof(void *) 和 sizeof(int) 来验证。所以在传参时可以传入静态变量的地址或动态分配的内存地址,这样就可以避免值异常和不同长度的类型之间的转换。从上述结果来看,执行结果并没有出现异常,但是在项目中,当传入线程的参数为局部变量的地址时,由于函数结束后会回收该地址,如果又重新分配给其他变量使用,这时候就会出现值异常。

有理论,有实验,有结论,可为一篇文章 1639

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

pthread_create如何传递多个参数

pthread_create如何传递多个参数 分类: C语言2012-06-19 08:44 98人阅读 评论(0) 收藏 举报 http://zhidao.baidu.com/question/315398992.html 涉及多参数传递给线程的,都需要使用结构体将参数封装后,将结构体指针传给线程 定义一个结构体 struct mypara {

jfkidear的专栏 2万+

Linux中线程的实现,线程的接口相关函数pthread_create、pthread_join、pthread_exit

线程的基本概念,操作系统中线程的实现,linux中线程的实现,线程与进程的区别,线程的接口相关函数,代码演示

m0_62689947的博客 1500

C程序员必须掌握的多线程技能:pthread_create参数详解(含函数指针与结构体传参)

掌握C语言多线程编程关键,深入解析pthread_create参数用法,涵盖函数指针与结构体传参技巧,适用于并发任务处理场景。提升程序性能,实现线程安全通信,值得收藏。

VarIsle的博客 1107

linux pthread创建线程传参,Linux中pthread_create传递参数的若干情况

0.背景介绍今天在工作中要使用pthread_create函数开启一个线程,并且需要传递参数,其中遇到了一些问题,现在来总结一下。1.pthread_create介绍函数原型:int pthread_create(pthread_t *tidp,const pthread_attr_t *attr, (void*)(*start_rtn)(void*),void *arg);第一个参数为指向线程标...

weixin_27066963的博客 2295

pthread_create/join函数学习

转自:https://blog.csdn.net/wushuomin/article/details/80051295。

QingTC 1049

【linux】多线程(二)线程控制pthread_create,pthread_join,pthread_exit,pthread_cancel,pthread_self

一、pthread线程库 二、线程创建pthread_create 三、线程等待pthread_join 四、零碎知识 全局变量 可重入函数 五、线程终止pthread_exit,pthread_cancel 获取线程的tid,pthread_self 六、线程函数传递对象 c++11中的多线程 七、线程的管理 八、如何理解pthread_join中的参数是二级指针retval 九、如何理解线程的独立栈

重铸自身根基的博客 1403

Linux系统下C语言多线程编程pthread_create()函数详解

pthread_create()函数介绍 pthread_create() 是UNIX操作系统(Linux、Unix、Mac OS等)中创建线程的函数,在头文件pthread.h中,函数模板如下: int pthread_create( pthread_t *tidp, const pthread_attr_t *attr, (void*)(*start_rtn)(void*), void *arg ); //返回值:若成功则返回0,否

zhangjianangyou的博客 3566

C++ pthread 线程传参

线程传参 (1)pthread_create(&semop_threadID, NULL, semopFun, a); int类型地址赋值给void * (2)num = (int *) param; void * 强制转换成 int * 运行结果 编译:g++ -o pthread pthread.cpp -lpthread 测试1 ...

weixin_42121713的博客 1300

【Linux系统编程】29.线程、pthread_self、pthread_create

【Linux系统编程】29.线程、pthread_self、pthread_create。

因心,三人水的博客 895

关于 pthread_create 传参的疑问

对于函数原型 int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg) 里的参数 arg,之前一直有疑问,就是把 &thread 传给 arg时,新创建的线程里是否能取到这个值呢?新线程里打印了入参 arg 的值:printf("in child thread id: %lu\n", *((pthread_t*)arg));

tianyexing2008的博客 327
上一篇: VMware 物理内存不足,无法使用配置的设置开启虚拟机
下一篇: [Linux] vim的高亮查找操作 reference : http://blog.chinaunix.net/uid-20732478-id-763411.html 使用了VIM这么久,
专业的坑
博客等级 码龄8年 6粉丝 26原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值