1、项目包结构
array.h
#ifndef _ARRAY_H_
#define _ARRAY_H_
/************************************************************************/
/* 初始化数组 */
/************************************************************************/
extern void initArrayStoreSpace(int **arr,int n);
/************************************************************************/
/* 初始化数组内容 */
/************************************************************************/
extern void initArrayContent(int *arr, int n);
/************************************************************************/
/* 打印制定的数组 */
/************************************************************************/
extern void printArrayContent(int *arr,int n);
/************************************************************************/
/* */
/************************************************************************/
extern void freeArrayStoreSpace(int *arr);
#endif
arrayImpl.c
#include <stdio.h>
#include<stdlib.h>
#include "array.h"
/************************************************************************/
/* 由于栈的大小有限,所以这个时候要在堆上开辟空间 */
/************************************************************************/
void initArrayStoreSpace(int **arr, int N)
{
if (N < 0)
{
printf("对不起,您要的数组大小不能小于0");
return;
}
else
{
*arr = (int *)malloc(sizeof(int)* N);
}
}
/************************************************************************/
/* 初始化数组的内容 */
/************************************************************************/
void initArrayContent(int *arr, int N)
{
int i = 0;
//注意,定义变量一定要指向要给NULL,不然会报错
int *px = arr;
for (px; px < arr + N; px++)
{
*px = ++i;
}
}
/************************************************************************/
/* 打印制定的数组,将数组的值赋值成1-N */
/************************************************************************/
void printArrayContent(int *arr, int N)
{
int i = 0;
int *px = arr;
for (px; px < arr + N; px++)
{
printf("%d\n", *px);
}
}
/************************************************************************/
/* 释放内存空间 */
/************************************************************************/
void freeArrayStoreSpace(int *arr)
{
free(arr);
}
find.h
#ifndef _FIND_H_
#define _FIND_H_
/************************************************************************/
/* 普通方式进行查找 */
/************************************************************************/
extern void find(void *p);
/************************************************************************/
/* 通过二分查找的方式进行查找 */
/************************************************************************/
extern void binarySearch(void *p);
#endif
findImpl.c
#include <stdio.h>
#include <stdlib.h>
#include <Windows.h>
#include "thread.h"
#include "find.h"
/************************************************************************/
/* 如果是想让线程使用,这里必须是void *p类型的 */
/************************************************************************/
void find(void *p)
{
//指针类型转换
struct threadStruct *pstruct = (struct threadStruct *)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;
}
/************************************************************************/
/* 通过二分查找的方式进行查找,这里有待检测 */
/************************************************************************/
void binarySearch(void *p)
{
struct threadStruct *pstruct = (struct threadStruct *)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;
}
else if (pstruct->num > *mid)
{
low = mid + 1;
}
else
{
//找到后将标识改成1
*pstruct->pflag = 1;
*pstruct->addr = ∣
return;
}
}
if (low > high)
{
printf("\n%d线程没有找到", pstruct->identify);
return;
}
}
thread.h
#ifndef _THREAD_H_
#define _THREAD_H_
struct threadStruct
{
int *start; //表示要查找的首地址
int length; //限定长度,从首地址开始只能找到后续的length个数值
int num; //要查找的数据
int identify; //线程的编号
int *pflag; //传递flag的地址,通过这个指针可以修改flag的值
int **addr; //存放所找数值所在的地址指针的地址
};
/************************************************************************/
/*为线程开辟空间 */
/************************************************************************/
extern void initThreadArrayStoreSpace(struct threadStruct **threadArr, int threadnum);
/************************************************************************/
/* 初始化线程内容,第二个参数表示的是数组 */
/************************************************************************/
extern void initThreadContent(struct threadStruct *threadArr, int len,
int *arr, int n, int targetNum, int threadnum);
/************************************************************************/
/* 打印结构体内容 */
/************************************************************************/
extern void printStructItemContent(struct threadStruct *threadArr, int n);
/************************************************************************/
/* 释放线程数组的内存空间 */
/************************************************************************/
extern void freeThreadStoreSpace(struct threadStruct *threadArr);
/************************************************************************/
/* 使用初始化好的线程执行查找动作 */
/************************************************************************/
extern void searchNumByMutiThread(struct threadStruct *threadArr, int n);
#endif
threadImpl.c
#include <stdio.h>
#include <stdlib.h>
#include <process.h> //调用多线程的时候要用到的头文件
#include <Windows.h>
#include "find.h"
#include "thread.h"
/*要注意的是这里不能把变量定义在头文件中*/
/*定义是否找到的标识*/
int flag = 0;
/*这里表示数值所在位置*/
int *numAddress = NULL;
/*定义时间值*/
/************************************************************************/
/*为线程开辟空间 */
/************************************************************************/
void initThreadArrayStoreSpace(struct threadStruct **threadArr, int TNUM)
{
if (TNUM < 0)
{
printf("对不起,您的线程数不能小于0.\n");
return;
}
else
{
//因为是结构体数组,所以这里的struct threadStruct类型的
*threadArr = (struct threadStruct *)malloc(sizeof(struct threadStruct) * TNUM);
}
}
/************************************************************************/
/* 初始化线程内容,第二个参数表示的是数组 */
/************************************************************************/
void initThreadContent(struct threadStruct *threadArr, int LENGTH,
int *arr, int N, int targetNum, int TNUM)
{
int i = 0;
struct threadStruct *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++;
}
}
/************************************************************************/
/* 打印每个结构体的内容 */
/************************************************************************/
void printStructItemContent(struct threadStruct *threadArr, int n)
{
//注意,定义变量一定要指向要给NULL,不然会报错
struct threadStruct *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);
//}
}
/************************************************************************/
/* 释放线程数组的内存空间 */
/************************************************************************/
void freeThreadStoreSpace(struct threadStruct *threadArr)
{
free(threadArr);
}
/************************************************************************/
/* 使用开辟的线程进行查找 */
/************************************************************************/
void searchNumByMutiThread(struct threadStruct *threadArr, int n)
{
//这里的n表示开辟n个线程
int i;
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 //开启内存检测
#define N 1000000 //定义数组的大小
#define TNUM 100 //定义TNUM的线程
#define LENGTH 10000 //定义每个线程能够查找的数组的长度(注意:N <= TNUM * LENGTH)
#define TARGETNUM 1000 //要查找的目标数值
int main(int argc, char *argv[])
{
//要注意的定义一个指针,一般的是要给它指向NULL,避免野指针
int *arr = NULL;
//堆上开辟数组空间,注意,如果要修改一段内存的值,要把指针的地址传递进去。
initArrayStoreSpace(&arr, N);
//初始化数组内容
initArrayContent(arr, N);
//定义线程
struct threadStruct * 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;
}