编程知识 cdmana.com

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

编程语言: 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;//参数1 
    float *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;//参数1 
    float *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个下载卷下载 (滑稽)

版权声明
本文为[程序员进化不脱发!]所创,转载请带上原文链接,感谢
https://blog.csdn.net/weixin_43134049/article/details/104364442

Scroll to Top