动态开辟指定数量的线程来查找动态开辟的数组中的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;

}

目录
相关文章
|
5月前
|
Java 索引
多线程向设备发送数据
多线程向设备发送数据
85 0
|
5月前
|
数据采集 监控 调度
干货分享“用 多线程 爬取数据”:单线程 + 协程的效率反超 3 倍,这才是 Python 异步的正确打开方式
在 Python 爬虫中,多线程因 GIL 和切换开销效率低下,而协程通过用户态调度实现高并发,大幅提升爬取效率。本文详解协程原理、实战对比多线程性能,并提供最佳实践,助你掌握异步爬虫核心技术。
|
消息中间件 监控 安全
服务Down机了,线程池中的数据如何保证不丢失?
在分布式系统与高并发应用开发中,服务的稳定性和数据的持久性是两个至关重要的考量点。当服务遭遇Down机时,如何确保线程池中处理的数据不丢失,是每一位开发者都需要深入思考的问题。以下,我将从几个关键方面分享如何在这种情况下保障数据的安全与完整性。
298 2
|
消息中间件 监控 Java
线程池关闭时未完成的任务如何保证数据的一致性?
保证线程池关闭时未完成任务的数据一致性需要综合运用多种方法和机制。通过备份与恢复、事务管理、任务状态记录与恢复、数据同步与协调、错误处理与补偿、监控与预警等手段的结合,以及结合具体业务场景进行分析和制定策略,能够最大程度地确保数据的一致性,保障系统的稳定运行和业务的顺利开展。同时,不断地优化和改进这些方法和机制,也是提高系统性能和可靠性的重要途径。
317 62
|
10月前
|
SQL 数据建模 BI
【YashanDB 知识库】用 yasldr 配置 Bulkload 模式作单线程迁移 300G 的业务数据到分布式数据库,迁移任务频繁出错
问题描述 详细版本:YashanDB Server Enterprise Edition Release 23.2.4.100 x86_64 6db1237 影响范围: 离线数据迁移场景,影响业务数据入库。 外场将部分 NewCIS 的报表业务放到分布式数据库,验证 SQL 性能水平。 操作系统环境配置: 125G 内存 32C CPU 2T 的 HDD 磁盘 问题出现的步骤/操作: 1、部署崖山分布式数据库 1mm 1cn 3dn 单线启动 yasldr 数据迁移任务,设置 32 线程的 bulk load 模式 2、观察 yasldr.log 是否出现如下错
|
9月前
|
数据采集 存储 安全
Python爬虫实战:利用短效代理IP爬取京东母婴纸尿裤数据,多线程池并行处理方案详解
本文分享了一套结合青果网络短效代理IP和多线程池技术的电商数据爬取方案,针对京东母婴纸尿裤类目商品信息进行高效采集。通过动态代理IP规避访问限制,利用多线程提升抓取效率,同时确保数据采集的安全性和合法性。方案详细介绍了爬虫开发步骤、网页结构分析及代码实现,适用于大规模电商数据采集场景。
|
10月前
|
缓存 安全 Java
面试中的难题:线程异步执行后如何共享数据?
本文通过一个面试故事,详细讲解了Java中线程内部开启异步操作后如何安全地共享数据。介绍了异步操作的基本概念及常见实现方式(如CompletableFuture、ExecutorService),并重点探讨了volatile关键字、CountDownLatch和CompletableFuture等工具在线程间数据共享中的应用,帮助读者理解线程安全和内存可见性问题。通过这些方法,可以有效解决多线程环境下的数据共享挑战,提升编程效率和代码健壮性。
332 6
|
缓存 安全 Java
使用 Java 内存模型解决多线程中的数据竞争问题
【10月更文挑战第11天】在 Java 多线程编程中,数据竞争是一个常见问题。通过使用 `synchronized` 关键字、`volatile` 关键字、原子类、显式锁、避免共享可变数据、合理设计数据结构、遵循线程安全原则和使用线程池等方法,可以有效解决数据竞争问题,确保程序的正确性和稳定性。
343 57
|
缓存 NoSQL Java
Java高并发实战:利用线程池和Redis实现高效数据入库
Java高并发实战:利用线程池和Redis实现高效数据入库
975 0

热门文章

最新文章