1 #define _CRT_SECURE_NO_WARNINGS
2 #include<stdio.h>
3 #include<stdlib.h>
4 #include <string.h>
5 #include <memory.h>
6 #include <process.h>
7 #include <Windows.h>
8
9 char *path = "dangdangwang.txt";
10
11 #define N 13180820
12
13 //存储所有的行的信息
14 char ** g_pp;
15 //创建线程的数组
16 struct threads *pthread;
17
18 //初始化全局变量g_pp
19 void init(char *path)
20 {
21 printf("init start");
22 g_pp = malloc(sizeof(char*)*N);
23 memset(g_pp, '\0', sizeof(char*)*N);//清空内容
24 FILE *pf = fopen(path, "r");
25
26 if (pf==NULL)
27 {
28 printf("init fail");
29 }
30 else
31 {
32 for (int i = 0; i < N;i++)
33 {
34 char str[1024] = { 0 };
35 //读取字符串
36 fgets(str, 1024, pf);
37 //获取长度
38 int length = strlen(str);
39 if (length >= 1)
40 {
41 //分配内存
42 g_pp[i] = malloc(sizeof(char)*(length + 1));
43 //清空内容
44 memset(g_pp[i], '\0', length + 1);
45 if (g_pp[i]!=NULL)
46 {
47 //拷贝
48 strcpy(g_pp[i], str);
49 }
50 }
51 }
52 fclose(pf);
53 }
54 printf("init end");
55 }
56
57 //线性查找
58 void search(char*str)
59 {
60
61 for (int i = 0; i < N;i++)
62 {
63 if (g_pp[i]!=NULL)
64 {
65 char *p = strstr(g_pp[i], str);
66 if (p != NULL)
67 {
68 printf("%s\n", g_pp[i]);//找到打印
69 }
70 }
71 }
72 }
73
74 //创建线程数组
75 struct threads
76 {
77 //指针数组的起始地址,指向的是一部分字符串,所以是二级指针
78 //(二级指针指向很多个一级指针)
79 char **ppstart;
80 //负责索引的长度
81 int length;
82 //线程编号
83 int id;
84 //查找的字符串
85 char *pstr;
86 };
87
88 //线程查找,传递的是线程结构体的信息
89 void searchthread(void *p)
90 {
91 //类型转换
92 struct threads *pinfo = p;
93 //遍历查找
94 for (int i = 0; i < pinfo->length;i++)
95 {
96 if (pinfo->ppstart[i]!=NULL)
97 {
98 char *p = strstr(pinfo->ppstart[i], pinfo->pstr);//查找
99 if (p!=NULL)
100 {
101 printf("线程%d找到%s\n", pinfo->id,pinfo->ppstart[i]);//找到
102 }
103 }
104 }
105 }
106
107 //创建线程,并且查找
108 void searchwiththread(char*str)
109 {
110 //线程是CPU核心的倍数
111 int num = 23;
112 //堆上开辟,线程结构体的信息
113 pthread = malloc(sizeof(struct threads) * 23);
114 //内存清零
115 memset(pthread, '\0', sizeof(struct threads )* 23);
116 //线程句柄分配内存
117 HANDLE *phd = malloc(sizeof(HANDLE) * 23);
118
119 //如果能够整除
120 if (N%num == 0)
121 {
122 for (int i = 0; i < num;i++)
123 {
124 pthread[i].id = i;
125 pthread[i].pstr = str;
126 //长度分配
127 pthread[i].length = N/num;
128 //起始地址
129 pthread[i].ppstart = g_pp+i*(N/num);
130 //创建线程
131 phd[i] = _beginthread(searchthread, 0, &pthread[i]);
132 }
133 }
134 //如果不能被整除
135 else
136 {
137 for (int i = 0; i < num-1; i++)
138 {
139 pthread[i].id = i;
140 pthread[i].pstr = str;
141 pthread[i].length = N / (num-1);
142 //起始地址
143 pthread[i].ppstart = g_pp + i*(N / (num-1));
144 //创建线程
145 phd[i] = _beginthread(searchthread, 0, &pthread[i]);
146 }
147 //处理最后一个
148 {
149 int i = num - 1;
150 pthread[i].id = i;
151 pthread[i].pstr = str;
152 pthread[i].length = N%(num-1);
153 //起始地址
154 pthread[i].ppstart = g_pp + i*(N / (num - 1));
155 //创建线程
156 phd[i] = _beginthread(searchthread, 0, &pthread[i]);
157 }
158 }
159 //等待所有线程退出
160 WaitForMultipleObjects(num, phd, TRUE, INFINITE);
161 }
162
163 //获取文件有多少行
164 int getN(char *path)
165 {
166 FILE *pf = fopen(path, "r");
167 if (pf == NULL)
168 {
169 return -1;
170 }
171 else
172 {
173 int i = 0;
174 while (!feof(pf))
175 {
176 char str[256] = { 0 };
177 fgets(str, 256, pf);
178 i++;
179 }
180 fclose(pf);
181 return i;
182 }
183 }
184
185 void main()
186 {
187 //初始化全局变量g_pp
188 init(path);
189 while (1)
190 {
191 char str[128] = { 0 };
192 scanf("%s", str);
193 //多线程查找
194 searchwiththread(str);
195 }
196 system("pause");
197 }