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

简介:  1、项目包结构 array.h #ifndef _ARRAY_H_ #define _ARRAY_H_   /************************************************************************/ /* 初始化数组                          


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 = &mid;

            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;

}

目录
相关文章
|
7月前
|
存储 前端开发 Java
【C++ 多线程 】C++并发编程:精细控制数据打印顺序的策略
【C++ 多线程 】C++并发编程:精细控制数据打印顺序的策略
208 1
|
3月前
|
消息中间件 监控 安全
服务Down机了,线程池中的数据如何保证不丢失?
在分布式系统与高并发应用开发中,服务的稳定性和数据的持久性是两个至关重要的考量点。当服务遭遇Down机时,如何确保线程池中处理的数据不丢失,是每一位开发者都需要深入思考的问题。以下,我将从几个关键方面分享如何在这种情况下保障数据的安全与完整性。
72 2
|
19天前
|
消息中间件 监控 Java
线程池关闭时未完成的任务如何保证数据的一致性?
保证线程池关闭时未完成任务的数据一致性需要综合运用多种方法和机制。通过备份与恢复、事务管理、任务状态记录与恢复、数据同步与协调、错误处理与补偿、监控与预警等手段的结合,以及结合具体业务场景进行分析和制定策略,能够最大程度地确保数据的一致性,保障系统的稳定运行和业务的顺利开展。同时,不断地优化和改进这些方法和机制,也是提高系统性能和可靠性的重要途径。
114 62
|
2月前
|
缓存 安全 Java
使用 Java 内存模型解决多线程中的数据竞争问题
【10月更文挑战第11天】在 Java 多线程编程中,数据竞争是一个常见问题。通过使用 `synchronized` 关键字、`volatile` 关键字、原子类、显式锁、避免共享可变数据、合理设计数据结构、遵循线程安全原则和使用线程池等方法,可以有效解决数据竞争问题,确保程序的正确性和稳定性。
51 2
|
6月前
|
缓存 NoSQL Java
Java高并发实战:利用线程池和Redis实现高效数据入库
Java高并发实战:利用线程池和Redis实现高效数据入库
514 0
|
7月前
|
消息中间件 Java Kafka
实时计算 Flink版操作报错之Apache Flink中的SplitFetcher线程在读取数据时遇到了未预期的情况,该怎么解决
在使用实时计算Flink版过程中,可能会遇到各种错误,了解这些错误的原因及解决方法对于高效排错至关重要。针对具体问题,查看Flink的日志是关键,它们通常会提供更详细的错误信息和堆栈跟踪,有助于定位问题。此外,Flink社区文档和官方论坛也是寻求帮助的好去处。以下是一些常见的操作报错及其可能的原因与解决策略。
|
3月前
|
消息中间件 存储 Java
服务重启了,如何保证线程池中的数据不丢失?
【8月更文挑战第30天】为确保服务重启时线程池数据不丢失,可采用数据持久化(如数据库或文件存储)、使用可靠的任务队列(如消息队列或分布式任务队列系统)、状态监测与恢复机制,以及分布式锁等方式。这些方法能有效提高系统稳定性和可靠性,需根据具体需求选择合适方案并进行测试优化。
226 5
|
4月前
处理串口线程数据的函数
【8月更文挑战第4天】处理串口线程数据的函数。
31 4
|
4月前
|
数据处理 Python
解锁Python多线程编程魔法,告别漫长等待!让数据下载如飞,感受科技带来的速度与激情!
【8月更文挑战第22天】Python以简洁的语法和强大的库支持在多个领域大放异彩。尽管存在全局解释器锁(GIL),Python仍提供多线程支持,尤其适用于I/O密集型任务。通过一个多线程下载数据的例子,展示了如何使用`threading`模块创建多线程程序,并与单线程版本进行了性能对比。实验表明,多线程能显著减少总等待时间,但在CPU密集型任务上GIL可能会限制其性能提升。此案例帮助理解Python多线程的优势及其适用场景。
45 0
|
4月前
|
NoSQL Redis
Lettuce的特性和内部实现问题之在同步调用模式下,业务线程是如何拿到结果数据的
Lettuce的特性和内部实现问题之在同步调用模式下,业务线程是如何拿到结果数据的