首页 > 代码库 > 动态开辟指定数量的线程来查找动态开辟的数组中的1000000数据中的值

动态开辟指定数量的线程来查找动态开辟的数组中的1000000数据中的值



1、项目包结构

array.h

#ifndef_ARRAY_H_

#define_ARRAY_H_

 

/************************************************************************/

/*初始化数组                                                          */

/************************************************************************/

externvoidinitArrayStoreSpace(int **arr,intn);

 

/************************************************************************/

/*初始化数组内容                                                      */

/************************************************************************/

externvoidinitArrayContent(int *arr,intn);

 

/************************************************************************/

/*打印制定的数组                                                      */

/************************************************************************/

externvoidprintArrayContent(int *arr,intn);

 

/************************************************************************/

/*                                                                     */

/************************************************************************/

externvoidfreeArrayStoreSpace(int *arr);

 

#endif

arrayImpl.c

#include<stdio.h>

#include<stdlib.h>

#include"array.h"

 

/************************************************************************/

/*由于栈的大小有限,所以这个时候要在堆上开辟空间                      */

/************************************************************************/

voidinitArrayStoreSpace(int **arr,intN)

{

   if (N < 0)

   {

       printf("对不起,您要的数组大小不能小于0");

       return;

   }

   else

   {

       *arr = (int *)malloc(sizeof(int)*N);

   }

}

 

/************************************************************************/

/*初始化数组的内容                                                    */

/************************************************************************/

voidinitArrayContent(int *arr,intN)

{

   inti = 0;

   //注意,定义变量一定要指向要给NULL,不然会报错

   int *px = arr;

   for (px;px <arr +N;px++)

   {

       *px = ++i;

   }

}

 

/************************************************************************/

/*打印制定的数组,将数组的值赋值成1-N                                  */

/************************************************************************/

voidprintArrayContent(int *arr,intN)

{

   inti = 0;

   int *px = arr;

   for (px;px <arr +N;px++)

   {

       printf("%d\n", *px);

   }

}

 

/************************************************************************/

/*释放内存空间                                                        */

/************************************************************************/

voidfreeArrayStoreSpace(int *arr)

{

   free(arr);

}

find.h

#ifndef_FIND_H_

#define_FIND_H_

 

/************************************************************************/

/*普通方式进行查找                                                    */

/************************************************************************/

externvoidfind(void *p);

 

/************************************************************************/

/*通过二分查找的方式进行查找                                          */

/************************************************************************/

externvoidbinarySearch(void *p);

 

#endif

 

findImpl.c

#include<stdio.h>

#include<stdlib.h>

#include<Windows.h>

#include"thread.h"

#include"find.h"

 

/************************************************************************/

/*如果是想让线程使用,这里必须是void *p类型的                         */

/************************************************************************/

voidfind(void *p)

{

   //指针类型转换

   structthreadStruct *pstruct = (structthreadStruct *)p;

   int *px = pstruct->start;

   //内存的遍历,从地址开始累加100个元素的大小,遍历所有元素

   for (px;px <pstruct->start + pstruct->length;px++)

   {

       Sleep(100);

       if (*(pstruct->pflag) != 0)

       {

           printf("属下%d无能,其他线程已经找到",pstruct->identify);

           //并且获取系统时间

 

           //这个地方关闭线程,如果直接返回,这时候这个线程自动关闭了。

           return;

       }

 

       //判断是否相等

       if (*px == pstruct->num)

       {

           //查找

           printf("\n%d个线程找到%d,数值地址是:%p\n",pstruct->identify, *px,px);

           //改变标识,代表找到

           *(pstruct->pflag) = 1;

           *(pstruct->addr) = px;

           return;

       }

 

   }

   printf("\n没有找到第%d个线程",pstruct->identify);

 

   return;

}

 

/************************************************************************/

/*通过二分查找的方式进行查找,这里有待检测                             */

/************************************************************************/

voidbinarySearch(void *p)

{

   structthreadStruct *pstruct = (structthreadStruct *)p;

   int *low = pstruct->start;

   int *high = pstruct->start + pstruct->length;

   while (low <= high)

   {

       //这里说明指针相减得到的是中间的差值

       int *mid = low + ((high - low) >> 1);

       if (pstruct->num < *mid)

       {

           high =mid - 1;

       }

       elseif (pstruct->num > *mid)

       {

           low =mid + 1;

       }

       else

       {

           //找到后将标识改成1

           *pstruct->pflag = 1;

           *pstruct->addr = &mid;

           return;

       }

   }

   if (low > high)

   {

       printf("\n%d线程没有找到",pstruct->identify);

       return;

   }

}

thread.h

#ifndef_THREAD_H_

#define_THREAD_H_

 

structthreadStruct

{

   int *start;   //表示要查找的首地址

   intlength;   //限定长度,从首地址开始只能找到后续的length个数值

   intnum;      //要查找的数据

   intidentify; //线程的编号

   int *pflag;   //传递flag的地址,通过这个指针可以修改flag的值

   int **addr;   //存放所找数值所在的地址指针的地址

};

 

/************************************************************************/

/*为线程开辟空间                                                       */

/************************************************************************/

externvoidinitThreadArrayStoreSpace(structthreadStruct **threadArr,intthreadnum);

 

/************************************************************************/

/*初始化线程内容,第二个参数表示的是数组                              */

/************************************************************************/

externvoidinitThreadContent(structthreadStruct *threadArr,intlen,

   int *arr,intn,inttargetNum,intthreadnum);

 

/************************************************************************/

/*打印结构体内容                                                                    */

/************************************************************************/

externvoidprintStructItemContent(structthreadStruct *threadArr,intn);

 

/************************************************************************/

/*释放线程数组的内存空间                                              */

/************************************************************************/

externvoidfreeThreadStoreSpace(structthreadStruct *threadArr);

 

/************************************************************************/

/*使用初始化好的线程执行查找动作                                                                    */

/************************************************************************/

externvoidsearchNumByMutiThread(structthreadStruct *threadArr,intn);

 

#endif

 

threadImpl.c

#include<stdio.h>

#include<stdlib.h>

#include<process.h> //调用多线程的时候要用到的头文件

#include<Windows.h>

#include"find.h"

#include"thread.h"

 

/*要注意的是这里不能把变量定义在头文件中*/

/*定义是否找到的标识*/

intflag = 0;

/*这里表示数值所在位置*/

int *numAddress = NULL;

/*定义时间值*/

 

/************************************************************************/

/*为线程开辟空间                                                       */

/************************************************************************/

voidinitThreadArrayStoreSpace(structthreadStruct **threadArr,intTNUM)

{

   if (TNUM < 0)

   {

       printf("对不起,您的线程数不能小于0.\n");

       return;

   }

   else

   {

       //因为是结构体数组,所以这里的struct threadStruct类型的

       *threadArr = (structthreadStruct *)malloc(sizeof(structthreadStruct) *TNUM);

   }

}

 

/************************************************************************/

/*初始化线程内容,第二个参数表示的是数组                              */

/************************************************************************/

voidinitThreadContent(structthreadStruct *threadArr,intLENGTH,

   int *arr,intN,inttargetNum,intTNUM)

{

   inti = 0;

   structthreadStruct *px = threadArr;

   for (px;px <threadArr +TNUM;px++)

   {

       //指向数组地址(注意这里的int *)

       px->start = arr +i *LENGTH;

       if (N - i *LENGTH >=LENGTH)

       {

           //定义每个所寻数组的大小

           px->length = LENGTH;

       }

       else

       {

          //定义每个所寻数组的大小

           px->length = N -i *LENGTH;

       }

 

       //定义线程要查找的内容

       px->num = targetNum;

       //每个线程的标识id

       px->identify = i;

       //是否找的标识的地址

       px->pflag = &flag;

       //存放元素所在位置的地址

       px->addr = &numAddress;

       

       //通过下面这句查看进程编号

       //printf("\n%d\n",px->identify);

       //Sleep(100);

       //_beginthread(find,0, &px);

       i++;

   }

 

}

 

/************************************************************************/

/*打印每个结构体的内容                                                                   */

/************************************************************************/

voidprintStructItemContent(structthreadStruct *threadArr,intn)

{

   //注意,定义变量一定要指向要给NULL,不然会报错

   structthreadStruct *px = threadArr;

   for (px;px <threadArr +n;px++)

   {

       printf("\n\n指向第一个位置的值是:%d\n", *px->start);

       printf("结构体id=%d,指向的数组地址start = %p,搜寻范围length = %d\n",px->identify,px->start,px->length);

       printf("查找目标值num=%d,标识的地址&flag = %p,存放元素所在位置的地址addr = %p\n\n",px->num,px->pflag,px->addr);

   }

 

   //第二种方式打印

   //for (i = 0; i < n;i++)

   //{

   // printf("\n指向的数组地址:%p,", threadArr[i].start);

   //}

}

 

/************************************************************************/

/*释放线程数组的内存空间                                              */

/************************************************************************/

voidfreeThreadStoreSpace(structthreadStruct *threadArr)

{

   free(threadArr);

}

 

/************************************************************************/

/*使用开辟的线程进行查找                                              */

/************************************************************************/

voidsearchNumByMutiThread(structthreadStruct *threadArr,intn)

{

   //这里的n表示开辟n个线程

   inti;

   for (i = 0; i <n;i++)

   {

       _beginthread(find,0,&threadArr[i]);

   }

}

 

main.c

#include<stdio.h>

#include<stdlib.h>

#include<crtdbg.h>       //做内存泄露检测所需的头文件

#include"array.h"

#include"thread.h"

#include"windows.h"

 

#define_CRTDBG_MAP_ALLOC//开启内存检测

#defineN 1000000        //定义数组的大小

#defineTNUM 100         //定义TNUM的线程

#defineLENGTH 10000     //定义每个线程能够查找的数组的长度(注意:N <= TNUM * LENGTH)

#defineTARGETNUM 1000   //要查找的目标数值

 

intmain(intargc,char *argv[])

{

   //要注意的定义一个指针,一般的是要给它指向NULL,避免野指针

   int *arr = NULL;

   //堆上开辟数组空间,注意,如果要修改一段内存的值,要把指针的地址传递进去。

   initArrayStoreSpace(&arr,N);

   //初始化数组内容

   initArrayContent(arr,N);

 

   //定义线程

   structthreadStruct *threadArr;

   //为线程开辟空间

   initThreadArrayStoreSpace(&threadArr,TNUM);

   //初始化线程内容

   initThreadContent(threadArr,LENGTH,arr,N,TARGETNUM,TNUM);

 

   //打印数组内容

   //printArrayContent(arr, N);

   printStructItemContent(threadArr,TNUM);

 

   //获取当前时间

   //传递数组的时候传递数组的名称就可以了。

   searchNumByMutiThread(threadArr,TNUM);

 

   //注意,如果没有考虑线程同步和死锁问题,这里要设置休眠时间,

   //否则会将数组的内容释放。导致错误出现。

   Sleep(100000);

   

   //释放线程数组的内存空间

   freeThreadStoreSpace(threadArr);

   //释放数组所占的内存空间

   freeArrayStoreSpace(arr);

 

   //printf("\n\n%d,%p\n\n", *numAddress,numAddress);//打印地址,还有数据

 

   //加上这一句之后在启动调试后的输出窗口中看是否有内存泄露

   _CrtDumpMemoryLeaks();  

   system("pause");

   return 0;

}