您的位置:首页 > 编程语言 > C语言/C++

c++通过结构体(struct)全局变量在多线程中传递参数

2020-03-28 20:14 781 查看

编程语言: c++

运行运行环境:Linux version 4.19.42-v7+ (dom@dom-XPS-13-9370) (gcc version 4.9.3 (crosstool-NG crosstool-ng-1.22.0-88-g8460611)) #1219 SMP Tue May 14 21:20:58 BST 2019

目标:在一个线程运行的时候,主程序或者另一个线程,通过改变全局变量实时改变目标变量的做法,比如这里,楼主也就是我,为了在树莓派上运行一个tcp结构的客户端线程,并通过摄像头线程收集的数据实时的通过tcp客户端线程处理并发回服务端(这是只对两个线程间的数据传递,多个线程间的话大家记得用上线程互斥锁,避免数据错误)

首先呢,你不用用结构体,就单纯的设置个全局变量直接用呢也是可以的,用了结构图就封装性和可一致性而言就好很多了,尤其是面对需要很多个相同类型的参数需要定义的时候( ̄△ ̄)

示例一:直接用全局变量在线程和主程序间参数交互的例子
流程叙述:
1. 首先定义了一个float类型的全局变量 cha_zuo_you = 0;
2.还定义了个叫judje的函数,用于线程函数
3.好滴,我们从主函数开始,主函数内,创建一个线程号存在thread1里的线程
4,继续执行主程序,使得全局变量 cha_zuo_you每隔2秒加个一
5.在主程序执行的同时,线程thread1也开始执行它的程序,打印全局变量 cha_zuo_you的值,值得注意的是这里打印全局变量 cha_zuo_you值的时候,主程序也是在对全局变量 cha_zuo_you的值进行修改的,所以如果我们去掉sleep函数,有可能在某一段时间内打印多个相同的值或者,打印掉别的什么值.

在这里插入代码片#include <pthread.h>#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <iostream>#include <sstream>pthread_t thread1;//创建线程名称float cha_zuo_you = 0;//全局变量void * judje(void *arg)//注意好这里线程用的函数是带信号的哦,//具体原因参考pthread_create函数定义*(自己搜){while(1){printf(" 线程judje输出变量cha_zuo_you的值为: %f,并延时两秒 \n ",cha_zuo_you);sleep(2);}}int main(void){pthread_attr_t attr;pthread_attr_init(&attr);pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);//(以上3句用来设置线程的属性,//这里设置为PTHREAD_CREATE_DETACHED 则新线程不//能用pthread_join()来同步,且在退出时自行释放所占用的资源。)if (0 != pthread_create(&thread1, &attr, judje, NULL   ))//{printf("error when create pthread,%d\n", errno);return 1;}while(1){cha_zuo_you = cha_zuo_you + 1;printf("主程序将变量cha_zuo_you加一并延时两秒\n");sleep(2);}}

运行效果如下

示例二:接下来我们加上一个struct结构体

struct dir_motor{float a = 10;float *left_right = &cha_zuo_you;//参数1float *top_under = &cha_qian_hou;float *Re_lv = &Relative_distance;};

流程叙述(有变化的地方我用的斜体与^^):
1. ^^首先定义了4个float类型的全局变量 (包括全局变量cha_zuo_you );
2 ^^定义了一个叫dir_motor的结构体
3.定义了个叫judje的函数,用于线程函数
3.好滴,我们从主函数开始,主函数内,创建一个线程号存在thread1里的线程
4,继续执行主程序,使得全局变量 cha_zuo_you每隔2秒加个一
*5.^^在主程序执行的同时,线程thread1也开始执行它的程序,通过correct_num的值得出要打印的全局变量是哪一个(这里correct_num为1所以还是打印全局变量 cha_zuo_you的值),
这次值得注意的是这里打印了struct内定义的a的值,用于比较打印时候的不同

p = pstru->left_right;//left_right是一个float *类型的指针,printf(" 输出全局变量cha_zuo_you的值等于: %f \n ",*(p));printf("输出a类型的值%f\n",pstru->a);

//…我是分界线咯…

以下是通过结构体(struct)全局变量在多线程中传递参数的简单代码示例,大家注意全局变量使用的时候在结构体dir_motor中的定义和普通的结构体类自带变量类型(即a)的定义与在程序中引用的区别

下面是帮助大家理解程序为总结的话,建议边看程序边配上这里的图一起理解,当然如果你对c中的指针理解很深刻的话,直接看程序就好了

下面是帮助大家理解程序为总结的话,建议边看程序边配上这里的图(画得有点丑建议图片另存为后逆时针旋转90度看,随便小小的写一句,这篇文章我是只发布在CSDN上的,要是哪个公众号爬过去了,不要脸的作为它的原创或者收费的话,大家记得通知我哈,虽然自己水平一般咯)一起理解,当然如果你对c中的指针理解很深刻的话,直接看程序就好了

首先我们假定:
类型为float 星号类型的 *left_right 的地址为0x01
类型为float类型的 cha_zuo_you 的地址为0x11
类型为struct dir_motor星号类型的 pstru 的地址为0x56

有以下程序得出下面的话

1.pstru->left_right表示表示以pstru所在的地址(即0x56)中存储的值0x01为地址的变量的变量即left_right(这也是为什么在线程中输出cha_zuo_you的值的时候pstru->left_right要加上星号的原因)
2.pstru->a表示以pstru所在的地址(即0x56)中存储的值0x66为地址的变量的值即10.000000
(实际上pstru的地址0x56存储了4个地址即dir_motor结构体类的那4个类型的地址中存储的值即dir_motor结构体类那4个的地址,当然这个说法也是不准确的,一个物理地址空间的存储量是有限的,实际上这个叫pstru这个名称的地址空间在dir_motor结构体定义很多个变量的情况下是不止一个地址空间的,这里为了便于理解这个地址空间就简称为0x56了))
3.left_right变量的地址为0x01
4.*left_right表示以left_right变量的的地址(即0x01)中存储的的值0x11为地址的变量的值(即为0),即 *left_right = 0 (当然主程序每隔2秒便加了1的哈)

#include <pthread.h>#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <iostream>#include <sstream>pthread_t thread1;int correct_num = 1;float Relative_distance = 0;float cha_zuo_you = 0;float cha_qian_hou = 0;struct dir_motor{float a = 10;float *left_right = &cha_zuo_you;//参数1float *top_under = &cha_qian_hou;float *Re_lv = &Relative_distance;};struct dir_motor pstru1;//00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000//void * judje(void *arg){int num;float *p;dir_motor *pstru;pstru = (struct dir_motor *) arg;//(对arg的强制类型转换,即将指向 传入该judje线程函数的dir_motor类型//的pstru1变量的 指针arg 指向的类型空间变成dir_motor类型 )//多缓一缓理解switch (correct_num)//(通过全局变量correct_num选择指针p//指向什么类型(这里是指的left_right指针指的cha_zuo_you的//地址){case 1:p = pstru->left_right;//left_right是一个float *类型的指针,correct_num = correct_num + 1;num = 1;break;case 2:p = pstru->left_right;correct_num = correct_num + 1;num = 2;break;case 3:p = pstru->top_under;correct_num = correct_num + 1;num = 3;break;case 4:p = pstru->top_under;correct_num = correct_num + 1;num = 4;break;case 5:p = pstru->Re_lv;correct_num = correct_num + 1;num = 5;break;}while(1){printf("输出a类型的值%f\n",pstru->a);printf(" 线程judje输出变量cha_zuo_you的值为: %f,并延时两秒 \n ",*(p));sleep(2);}}int main(void){pthread_attr_t attr;pthread_attr_init(&attr);pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);if (0 != pthread_create(&thread1, &attr, judje, &pstru1   ))//将定义的pstru地址给judje中定义的指针pstru指{printf("error when create pthread,%d\n", errno);return 1;}while(1){cha_zuo_you = cha_zuo_you + 1;printf("主程序将变量cha_zuo_you加一并延时两秒\n");sleep(2);}}

以下为示例二运行图示

恩,linux下的运行文件放这里了,其实和上面一样的咯,
编译的时候用make,失败了(cpp改了没反应)
或者想重新生成编译文件,编译文件的名字自己在CMakeLists.txt改删除其他文件只保
留ResultColorTest.cpp CMakeLists.txt两个文件然后用
cmake . 重新生成 (想多个cpp文件一起编译的话要改CMakeLists.txt的内容的哈)

csdn1个下载卷下载 (滑稽)

  • 点赞
  • 收藏
  • 分享
  • 文章举报
知了的树发布了6 篇原创文章 · 获赞 1 · 访问量 162私信关注
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: