多线程索引


/*
多线程索引

*/
#define  _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<process.h>
#include<Windows.h>


#define LINE 13180806
//获取文件有多少行
int getLine(char *path)
{
	printf("开始统计文件行数.....\n");
	int sum = 0;
	FILE *pfr = fopen(path, "rb");
	if (pfr == NULL)
	{
		printf("文件打开失败!\n");
		return -1;
	}
	while (!feof(pfr))
	{
		char str[1024] = { 0 };
		fgets(str, 1024, pfr);
		sum++;
	}
	fclose(pfr);
	printf("文件行数统计结束。\n");
	return sum;
}
//索引结构体
struct indexinfo
{
	int *pindex;	//计录每行的首地址,做索引用
	int length;		//计录文件行数
}allindex;

//索引初始化
void init(char *path, char *indexpath)
{
	//要使用 rb 因为 \n 写到文件中会转换成 \r\n 占二个字节,而 \r读时只占一个字节,这样会有误差
	FILE *pfr = fopen(path, "rb");	
	FILE *pfw = fopen(indexpath, "wb");
	printf("内存空间分配...\n");
	allindex.pindex = calloc(LINE,sizeof(int));
	printf("内存空间分配结束。\n");

	int alllength = 0;	//记录每行的长度
	int i = 0;
	if (pfr == NULL||pfw ==NULL)
	{
		printf("文件打开失败!\n");
		return;
	}

	while (!feof(pfr))
	{
		char str[1024] = { 0 };
		fgets(str, 1024, pfr);	
		
		alllength += strlen(str);		
		i++;		
	}

	fclose(pfr);

	//把索引写入到文件
	printf("开始写入索引...\n");
	fwrite(allindex.pindex, sizeof(int), LINE, pfw);	
	fclose(pfw);
	printf("索引写入结束.\n");
}

//快速索引查询,即把索引文件加载到内存中进行查询
void quickindex(char *indexpath)
{
	//先他配内存空间给索引结构体
	allindex.pindex = calloc(LINE, sizeof(int));

	FILE *pfr = fopen(indexpath, "rb");	
	fread(allindex.pindex, sizeof(int), LINE, pfr);	
	fclose(pfr);
}

char *path = "e:\\dd.txt";
char *indexpath = "e:\\indxedd.txt";

//这是生成索引文件,下面可以测试按排查询。
void main1()
{
	//getLineString(path);

	//printf("%d\n", getLine(path));  //得到行数.要注意的是这儿使用的是 rb 进行的读取。
	//init(path, indexpath);		//初始索引,并把索引写进文件中。

	//下面是把索引加载到内存,然后输入行数,即可查出相应行的数据。
	quickindex(indexpath);		//把索引文件加载到内存这样查询速度更快。
	
	FILE *pfr = fopen(path, "rb");

	while (1)
	{
		int num = 0;
		printf("输入要查询的行数:");
		scanf("%d", &num);
		char info[256] = { 0 };
	
		fseek(pfr, allindex.pindex[num], SEEK_SET);
		fgets(info, 256, pfr);

		printf("%s\n", info);
	}

	fclose(pfr);


	system("pause");
}

//多线程结构所需要的信息
struct threadinfo
{
	int *start;		//线程开始查询的地址
	int length;			//线程查询的长度
	char findstr[20];	//要查询的字符串
	int id;		//线程编号
	
};

void runthread(void *p)
{
	struct threadinfo *pinfo = p;
	FILE *pfr = fopen(path, "rb");

	for (int i = 0; i < pinfo->length;i++)
	{
		int tempnum = pinfo->start[i];	//获取行的首地址(即离文件指针的距离)
		fseek(pfr, tempnum, SEEK_SET);
		char str[256] = { 0 };
		fgets(str, 256, pfr);
		char *px = strstr(str, pinfo->findstr);
		if (px)
		{
			printf("\n线程:%d 查询到信息:\n%s", pinfo->id, str);
			
		}
		
	}
	printf("\n线程:%d查询结束。\n", pinfo->id);
	fclose(pfr);
}



void main()
{
#define T 10	//分成多少个线程

	quickindex(indexpath);		//把索引文件载入到内存
	struct threadinfo thread[T];	//创建线程使用的信息数组
	char str[20] = { 0 };		//要查询的字符串
	printf("输入要查询的姓名或电话:");
	scanf("%s", str);
	HANDLE hd[T];
	if (LINE % T)
	{
		for (int i = 0; i < T; i++)
		{
			strcpy(thread[i].findstr, str);
			thread[i].start = allindex.pindex + i*(LINE / T);
			thread[i].length = LINE / T;
			thread[i].id = i + 1;
			hd[i] = _beginthread(runthread, 0, &thread[i]);
		}
	}
	else
	{
		for (int i = 0; i < T-1; i++)
		{
			strcpy(thread[i].findstr, str);
			thread[i].start = thread[i].start + i*LINE / (T-1);
			thread[i].length = LINE /(T-1);
			thread[i].id = i + 1;
			hd[i]= _beginthread(runthread, 0, &thread[i]);
		}
		int i = T -1;
		strcpy(thread[i].findstr, str);
		thread[i].start = thread[i].start + i*LINE / (T - 1);
		thread[i].length = LINE % (T-1);
		thread[i].id = i + 1;
		hd[i] = _beginthread(runthread, 0, &thread[i]);
	}

	WaitForMultipleObjects(T, hd, TRUE, INFINITE);	//等待所有的线程退出

	system("pause");
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值