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;
}