循环创建多线程时保证参数的有效性

2024-04-11 00:32

本文主要是介绍循环创建多线程时保证参数的有效性,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

循环创建多线程时保证参数的有效性    
当我们需要在一个循环中传递参数时,使用使用函数的方法一般都是:    
for(int   I=0;I <100;I++)
{                  
fun(I);           //使用函数传递i   
}    


每一个循环都会等待fun(I);函数执行完后再进行下一个循环。    
但是当我们需要这个循环中创建线程,并将I的参数传递给线程时,如依然使用以上方法,会造成什么情况呢?    
DWORD   WINAPI   ThreadFun(LPVOID   lpParam)
{                             //线程函数                  
Int   *I   =   (int   *)lpParam;                  Return   0;   
}        


int   I;    
for(I=0;I <100;I++)
{    
DWORD   dwThreadId;            HANDLE   hThread;             
hThread   =   CreateThread(NULL,0,ThreadFunc,&I,0,&dwThreadId);  
}    


好了,到这里我们就可以发现,在循环中,我们创建线程并传递的参数是I=1后,主程序有可能在执到下一次循环时,第一次的ThreadFun函数仍未执行,而此时的I已经等2了,如果ThreadFun再来调用               
Int   *I   =   (int   *)lpParam;语句时,显然不是我们想要的结果。        
解决此问题的一种方法,便是可以使用静态数组来保存所要传递的参数。
如下: 
   
int   I;    
static   int   nPara[100];           //此句需定义为全局    
for(I=0;I <100;I++)
{    
DWORD   dwThreadId;    
HANDLE   hThread;    
NPara[I]=I;                 //保存参数          
hThread   =   CreateThread(NULL,0,ThreadFunc,&nPara[I],0,&dwThreadId); 
}    
此时,所有参数均保存在nPara数组中,刚才的问题是解决了。


接下来又有了新的问题,让我们一起来看看吧:  
  1、如果需要创建的线程不止100,而是非常的大,而且我们也并不知道会有多少次循环的时侯。  
  2、如果我们需要传递的参数不单单只是一个int型的I,而是一个类。那么我们声明的时侯


(假设线程数量最大为65535)则:    
static   CMYClass   myClass[65535];   


编译之后,得到的文件将会堆上一大堆的垃圾。相信任何一位程序都不想看到自己的程序上面堆了一堆垃圾在上面吧。 那么,还有没有更好的办法解决呢。答案是一定的,这里,我就讲一下我自己常用的方法:动态创建对像传递参数。
  
一提到动态创建,我们自然会想到new   与   delete   ,
对了,我想说的也正是他们的使用。    
假设参数类型为:    
typedef   struct   _PARA
{  
int   I;            
DWORD   dwNumber;            
HWND   hOther;    
}Para;  


使用new在堆栈中申请一遍空间,在使用完后必需使用delete将其释放。    


int   I;    
for(I=0;I <100;I++)
{    
DWORD   dwThreadId;    
HANDLE   hThread;     
Para   *myPara   =   new   Para;  
MyPara-> I   =   I;   MyPara-> dwNumber   =   0   ;//自定   
MyPara   -> hOther   =   GetSafeHWnd();//当前窗体句柄           
hThread   =   CreateThread(NULL,0,ThreadFunc,myPara,0,&dwThreadId); //线程函数  
}           


DWORD   WINAPI   ThreadFun(LPVOID   lpParam)
{                             
//线程函数                  
Para   *myPara   =   (Para   *)lpParam;                  //执行其他功能
delete   []   myPara;                                 //释放                 
Return   0;   
}  
  
这样的话,也就不怕传递的参数多少与线程的数量太大了。另外如有需要的话可以加上一个线程计数器,保证当前线程的最大数量。   
通常情况,我比较喜欢把线程处理放在一个类中处理,在主程序中尽量不与线程打交道。        


在循环中使用new 可以保证每次申请到的内存的地址不会是同一个(即不会重复),从而传递给每个线程的参数也互不冲突,互不干扰,相互独立,在线程内部使用完参数后,根据接收的地址,使用delete释放申请的内存块。 
用结构,然后将结构的指针传给CreateThread()的参数lpParameter。需要  注意:
结构应该是“静态的”或是“全局的”或者是“动态分配的”。
如果使用局部  变量,有可能在线程调用这个结构时,结构已经不在栈中了。  
struct   StructA  
{           
int   n1,   n2,   n3,   n4,   n5;  
};    


DWORD   WINAPI   ThreadFun(LPVOID*   param)  
{
StructA*   pa   =   (StructA*)param;          //这儿就可以访问结构中的变量了         
//......           return   1;  
}    
void   TestFunc()  
{           
DWORD   dwID;            
//下面的写法不对          
StructA   a;  
        CreateThread(NULL,   0,   ThreadFun,   &a,   0,   &dwID);            
//下面的写法是对的          
static   StructA   a;           
CreateThread(NULL,   0,   ThreadFun,   &a,   0,   &dwID);  

这篇关于循环创建多线程时保证参数的有效性的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/892592

相关文章

Java线程池核心参数原理及使用指南

《Java线程池核心参数原理及使用指南》本文详细介绍了Java线程池的基本概念、核心类、核心参数、工作原理、常见类型以及最佳实践,通过理解每个参数的含义和工作原理,可以更好地配置线程池,提高系统性能,... 目录一、线程池概述1.1 什么是线程池1.2 线程池的优势二、线程池核心类三、ThreadPoolE

C#高效实现在Word文档中自动化创建图表的可视化方案

《C#高效实现在Word文档中自动化创建图表的可视化方案》本文将深入探讨如何利用C#,结合一款功能强大的第三方库,实现在Word文档中自动化创建图表,为你的数据呈现和报告生成提供一套实用且高效的解决方... 目录Word文档图表自动化:为什么选择C#?从零开始:C#实现Word文档图表的基本步骤深度优化:C

Python列表的创建与删除的操作指南

《Python列表的创建与删除的操作指南》列表(list)是Python中最常用、最灵活的内置数据结构之一,它支持动态扩容、混合类型、嵌套结构,几乎无处不在,但你真的会创建和删除列表吗,本文给大家介绍... 目录一、前言二、列表的创建方式1. 字面量语法(最常用)2. 使用list()构造器3. 列表推导式

JavaWeb项目创建、部署、连接数据库保姆级教程(tomcat)

《JavaWeb项目创建、部署、连接数据库保姆级教程(tomcat)》:本文主要介绍如何在IntelliJIDEA2020.1中创建和部署一个JavaWeb项目,包括创建项目、配置Tomcat服务... 目录简介:一、创建项目二、tomcat部署1、将tomcat解压在一个自己找得到路径2、在idea中添加

Java利用Spire.Doc for Java实现在模板的基础上创建Word文档

《Java利用Spire.DocforJava实现在模板的基础上创建Word文档》在日常开发中,我们经常需要根据特定数据动态生成Word文档,本文将深入探讨如何利用强大的Java库Spire.Do... 目录1. Spire.Doc for Java 库介绍与安装特点与优势Maven 依赖配置2. 通过替换

C++多线程开发环境配置方法

《C++多线程开发环境配置方法》文章详细介绍了如何在Windows上安装MinGW-w64和VSCode,并配置环境变量和编译任务,使用VSCode创建一个C++多线程测试项目,并通过配置tasks.... 目录下载安装 MinGW-w64下载安装VS code创建测试项目配置编译任务创建 tasks.js

java创建xls文件放到指定文件夹中实现方式

《java创建xls文件放到指定文件夹中实现方式》本文介绍了如何在Java中使用ApachePOI库创建和操作Excel文件,重点是如何创建一个XLS文件并将其放置到指定文件夹中... 目录Java创建XLS文件并放到指定文件夹中步骤一:引入依赖步骤二:创建XLS文件总结Java创建XLS文件并放到指定文件

Java JAR 启动内存参数配置指南(从基础设置到性能优化)

《JavaJAR启动内存参数配置指南(从基础设置到性能优化)》在启动Java可执行JAR文件时,合理配置JVM内存参数是保障应用稳定性和性能的关键,本文将系统讲解如何通过命令行参数、环境变量等方式... 目录一、核心内存参数详解1.1 堆内存配置1.2 元空间配置(MetASPace)1.3 线程栈配置1.

SpringMVC配置、映射与参数处理​入门案例详解

《SpringMVC配置、映射与参数处理​入门案例详解》文章介绍了SpringMVC框架的基本概念和使用方法,包括如何配置和编写Controller、设置请求映射规则、使用RestFul风格、获取请求... 目录1.SpringMVC概述2.入门案例①导入相关依赖②配置web.XML③配置SpringMVC

Java 虚拟线程的创建与使用深度解析

《Java虚拟线程的创建与使用深度解析》虚拟线程是Java19中以预览特性形式引入,Java21起正式发布的轻量级线程,本文给大家介绍Java虚拟线程的创建与使用,感兴趣的朋友一起看看吧... 目录一、虚拟线程简介1.1 什么是虚拟线程?1.2 为什么需要虚拟线程?二、虚拟线程与平台线程对比代码对比示例:三