64.文件载入内存进行多线程以及根据索引文件进行多线程索引

Posted 喵小喵~

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了64.文件载入内存进行多线程以及根据索引文件进行多线程索引相关的知识,希望对你有一定的参考价值。

一.文件载入内存进行多线程检索

  • 获取并定义行数以及定义索引和文本的路径
    1 char path[256] = "kaifangX.txt";
    2 char indexpath[256] = "indexkaifangX.txt";
    3 #define N 20151574

     

  • 索引的结构体
    1 //索引内存结构体
    2 struct index  
    3 {
    4     //索引内存首地址
    5     int *pindex;
    6     //文件总的行数
    7     int length;
    8 }allindex = {0};

     

  • 初始化索引并将索引写入到文件
    /初始化索引
    void  init(char *path)
    {
        //总长度等于行数
        allindex.length = N;
        //初始化分配
        allindex.pindex = calloc(N, sizeof(int));
    
        //打开文件,以二进制文件方式读取
        FILE*pf = fopen(path, "rb");
        if (pf == NULL)
        {
            puts("file open fail");
        }
        else
        {
            //用于给索引赋值
            int allength = 0;
    
            for (int i = 0; i < N;i++)
            {
                char str[500] = { 0 };
                //获取字符串
                fgets(str, 500, pf);
                allindex.pindex[i] = allength;
                int length = strlen(str);
                //索引位置增加
                allength += length;
            }
            fclose(pf);
        }
        printf("\n结束生成");
    
        //写入到文件
        FILE *pfw = fopen(indexpath, "wb");
        fwrite(allindex.pindex, sizeof(int), allindex.length, pfw);
        fclose(pfw);
    }

     

  • 快速载入索引文件内存
     1 void quick()
     2 {
     3     //设置长度
     4     allindex.length = N;
     5     //初始化分配
     6     allindex.pindex = calloc(N, sizeof(int));
     7 
     8     //读取文件
     9     FILE *pfw = fopen(indexpath, "rb");
    10     //读取到内存中
    11     fread(allindex.pindex, sizeof(int), allindex.length, pfw);
    12     fclose(pfw);
    13 }

     

  • 创建线程的结构体
    1 //创建线程索引结构体
    2 struct info
    3 {
    4     int *pstart;//开始位置
    5     int length;//长度
    6     char findstr[20];//要查找
    7     int id;//线程编号
    8 
    9 };

     

  • 创建多线程函数
     1 //多线程函数
     2 void runmem(void *p)
     3 {
     4     //打开文件
     5     FILE *pf = fopen(path, "rb");
     6     //指针类型转换
     7     struct info *pi = p;
     8     //分别读取每个线程索引的位置
     9     for (int i = 0; i < pi->length;i++)
    10     {
    11         //索引的位置
    12         int tempnum = pi->pstart[i];
    13         //根据偏移读文件
    14         fseek(pf, tempnum, SEEK_SET);
    15         char str[512] = { 0 };
    16         fgets(str, 512, pf);
    17         //查找
    18         char *px = strstr(str, pi->findstr);
    19         if (px!=NULL)
    20         {
    21             printf("\n%d线程找到%s", pi->id, str);//打印找到的数据
    22         }
    23     }
    24     fclose(pf);
    25 }

     

  • 测试函数
     1     //载入内存
     2     quick();
     3     printf("请输入要查询的");
     4     char str[100] = { 0 };
     5     scanf("%s", str);
     6 
     7 //多线程数组个数
     8 #define nthread 100
     9     struct info pthread[nthread];//创建线程使用信息数组
    10     
    11     //如果能被整除
    12     if (N%nthread==0)
    13     {
    14         for (int i = 0; i < nthread;i++)
    15         {
    16             pthread[i].id = i;
    17             strcpy(pthread[i].findstr, str);//拷贝
    18             pthread[i].length = N / nthread;
    19             pthread[i].pstart = allindex.pindex + i*(N / nthread);//
    20             _beginthread(runmem, 0, &pthread[i]);//传递数据
    21         }
    22 
    23     }
    24     //如果不能被整除
    25     else
    26     {                         
    27         //先分配前n-1个
    28         for (int i = 0; i < nthread-1; i++)
    29         {
    30             pthread[i].id = i;
    31             strcpy(pthread[i].findstr, str);//拷贝
    32             pthread[i].length = N / (nthread-1);
    33             pthread[i].pstart = allindex.pindex + i*(N / (nthread-1));//
    34             _beginthread(runmem, 0, &pthread[i]);//传递数据
    35         }
    36 
    37         //分配最后一个
    38         {
    39             int i = nthread - 1;
    40             pthread[i].id = i;
    41             strcpy(pthread[i].findstr, str);//拷贝
    42             pthread[i].length = N % (nthread - 1);
    43             pthread[i].pstart = allindex.pindex + i * (N / (nthread - 1));//
    44             _beginthread(runmem, 0, &pthread[i]);//传递数据
    45         }
    46     }

     

二.根据索引文件进行多线程索引

  • 创建多线程索引结构体
     1 //文件检索多线程索引结构体
     2 struct finof
     3 {
     4     //起始的行数
     5     int  start;
     6     //结束的行数
     7     int end;
     8     //线程id
     9     int id;
    10     //要发现的数据
    11     char findstr[20];
    12 
    13 };

     

  • 文件索引多线程函数
     1 void runfile(void *p)
     2 {
     3     //获取传递至参数地址
     4     struct finof *pf = p;
     5     //打开索引文件
     6     FILE *pf1 = fopen(indexpath, "rb");
     7     //打开数据文件
     8     FILE *pf2 = fopen(path, "rb");
     9 
    10     //进行搜索
    11     for (int num = pf->start; num < pf->end; num++)
    12     {
    13         int indexnum;
    14         //移动到相应的行数对应的地址
    15         fseek(pf1, num*sizeof(int), SEEK_SET);
    16         //读取索引
    17         fread(&indexnum, sizeof(int), 1, pf1);
    18 
    19         //移动到索引对应的位置
    20         fseek(pf2, indexnum, SEEK_SET);
    21         char str[256] = { 0 };
    22         //读取数据
    23         fgets(str, 256, pf2);
    24         //寻找
    25         char *px = strstr(str, pf->findstr);
    26         if (px!=NULL)
    27         {
    28             printf("%d线程找到%s", pf->id, str);
    29         }
    30 
    31     }
    32     //关闭文件
    33     fclose(pf1);
    34     fclose(pf2);
    35 }

     

  • 测试函数
     1 printf("请输入要查询的");
     2     char str[100] = { 0 };
     3     scanf("%s", str);
     4 
     5 #define nthread 100
     6     struct finof pthread[nthread];//数组
     7     //如果能被整除
     8     if (N%nthread==0)
     9     {
    10         for (int i = 0; i < nthread;i++)
    11         {
    12             //每一个结构体对应的开始的行数
    13             pthread[i].start = (N / nthread)*i;
    14             //每一个结构体对应的结束的行数
    15             pthread[i].end = (N / nthread)*(i+1);
    16             //内容拷贝
    17             strcpy(pthread[i].findstr, str);
    18             pthread[i].id = i;
    19             //开始线程
    20             _beginthread(runfile, 0, &pthread[i]);
    21         }
    22     } 
    23     else
    24     {
    25         //分配起始行数和结尾行数
    26         for (int i = 0; i < nthread-1; i++)
    27         {
    28             pthread[i].start = (N / (nthread - 1))*i;
    29             pthread[i].end = (N / (nthread - 1))*(i + 1);
    30             strcpy(pthread[i].findstr, str);
    31             pthread[i].id = i;
    32             _beginthread(runfile, 0, &pthread[i]);
    33 
    34 
    35         }
    36         //最后一个线程
    37         int i = nthread - 1;
    38         pthread[i].start = (N / (nthread - 1))*i;
    39         pthread[i].end = (N / (nthread - 1))*i + N % (nthread - 1);
    40         strcpy(pthread[i].findstr, str);
    41         pthread[i].id = i;
    42         _beginthread(runfile, 0, &pthread[i]);
    43     }

     

以上是关于64.文件载入内存进行多线程以及根据索引文件进行多线程索引的主要内容,如果未能解决你的问题,请参考以下文章

Android异步载入全解析之大图处理

iOS-UIImageView载入网络下载的图片(异步+多线程)

使用多线程进行慢速 Ms 互操作

多线程实现多图片下载1

Python中多进程的使用

ImageLoader作用 AAAA