1. 程式人生 > >64.文件載入內存進行多線程以及根據索引文件進行多線程索引

64.文件載入內存進行多線程以及根據索引文件進行多線程索引

lose 線程id 路徑 i++ size 讀取文件 獲取字符串 pst 測試

一.文件載入內存進行多線程檢索

  • 獲取並定義行數以及定義索引和文本的路徑
    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.文件載入內存進行多線程以及根據索引文件進行多線程索引