您的位置:首页 > 其它

简单的双线程数组循环队列缓冲区的实现

2010-02-10 10:52 786 查看
目的,随机生成一千万用户信息。

UserInfoGenerator.h文件:

#include <pthread.h>

#define 	USER_BUF_SIZE				200
#define		MAX_USER_NUM				10000000

//号段信息
typedef struct
{
char SegNo[10];
char AreaNo[10];
char Addr[20];//GBK编码,一个汉字占两个字节
char Kind[24];   //GBK编码,一个汉字占两个字节
int  NextNo;
}SegmentInfo;

//用户号段信息双向列表
typedef struct SegNode
{
SegmentInfo				*Segment;
struct SegNode		*Prev;
struct SegNode		*Next;
}SegmentNode;

typedef SegmentNode	*SegmentList;

//百家姓信息
typedef char Surname[3];//GBK编码,一个汉字占两个字节

typedef struct
{
char PhoneNo[14];
char Name[10];
char Addr[16];
char Kind[24];
}UserInfo;//结构体大小64字节

//生成用户信息的线程和写用户信息的线程之间的共享空间
typedef struct
{
UserInfo					User[USER_BUF_SIZE];
int								CreateItemNum;
int								WriteItemNum;
int								OccupySize;
int								NextIn;
int								NextOut;
pthread_mutex_t		Mutex;
pthread_cond_t		CreateCond;
pthread_cond_t		WriteCond;
}UserBuf;


UserInfoGenerator.c文件:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <assert.h>

#include "UserInfoGenerator.h"

SegmentList			segmentList;
Surname				 	surname[100];
UserBuf				 	*shareBuf;

void ReadInitFile()
{
FILE						*fSegment				= NULL;
FILE						*fSurname				= NULL;
unsigned long 	segmentFilePos 	= 0;
unsigned long 	readBufPos			= 0;
unsigned long		readLen					= 0;
char						readBuf[10 * 1024 + 1] = {0};
char						*pRec						= NULL;
char						*pFieldSep			= NULL;
char						*pFieldBegin		= NULL;
char						*pFieldEnd			= NULL;
char						*pNewLine				= NULL;

char						fieldSeg[10]		= {0};
char						fieldArea[10]		= {0};
char						fieldAddr[20]		= {0};
char						fieldKind[24]		= {0};

int							nameIndex 			= 0;
int 						segIndex				= 0;

SegmentNode			*pLastNode			= NULL;
SegmentNode			*pNewNode				= NULL;

//读取百家姓信息
fSurname		= fopen("surname.txt","r");
assert(NULL != fSurname);
readLen			= fread(readBuf, sizeof(char), 10 * 1024, fSurname);
assert(0 <= readLen && readLen <= 10 * 1024);
readBuf[readLen] = 0;
pRec				= readBuf;
while(NULL != pRec)
{
strncpy(surname[nameIndex++], pRec, 2);//GBK编码,两个字节
if(nameIndex >= 100)
{
break;
}
while('/0' != *pRec && '/n' != *pRec)
{
pRec++;		//找正在处理的姓氏行尾
}
pRec++;		  //指向下一个姓氏
}
if(NULL != fSurname)
{
fclose(fSurname);
fSurname = NULL;
}
//号段列表初始化
segmentList	= (SegmentNode *)malloc(sizeof(SegmentNode));
segmentList->Segment = NULL;
segmentList->Prev		 = NULL;
segmentList->Next		 = NULL;
pLastNode 					 = segmentList;
//读取号段信息
fSegment		= fopen("segment.txt","r");
assert(NULL != fSegment);
while(1)
{
memset(readBuf, 0, sizeof(readBuf));
fseek(fSegment, segmentFilePos, SEEK_SET);
readLen			= fread(readBuf, sizeof(char), 10 * 1024, fSegment);
readBufPos = 0;
if(readLen < 10)
{
break;
}
assert(0 <= readLen && readLen <= 10 * 1024);
readBuf[readLen] = 0;
pNewLine		= strrchr(readBuf, '/n');
pNewLine++;
*pNewLine		= '/0';
pRec				= readBuf;

while(NULL != pRec && '0' != *pRec)
{
memset(fieldSeg, 0, sizeof(fieldSeg));
memset(fieldArea, 0, sizeof(fieldArea));
memset(fieldAddr, 0, sizeof(fieldAddr));
memset(fieldKind, 0, sizeof(fieldKind));

//字段1--号段
pFieldBegin 	= pRec;
pFieldSep			= strstr(pFieldBegin, "|");
if(NULL == pFieldSep)
{
break;
}
pFieldEnd			= pFieldSep - 1;
strncpy(fieldSeg, pFieldBegin, pFieldEnd - pFieldBegin + 1);
//字段2--区号
pFieldBegin 	= pFieldSep	+ 1;
pFieldSep			= strstr(pFieldBegin, "|");
if(NULL == pFieldSep)
{
break;
}
pFieldEnd			= pFieldSep - 1;
strncpy(fieldArea, pFieldBegin, pFieldEnd - pFieldBegin + 1);
//字段3--地区
pFieldBegin 	= pFieldSep	+ 1;
pFieldSep			= strstr(pFieldBegin, "|");
if(NULL == pFieldSep)
{
break;
}
pFieldEnd			= pFieldSep - 1;
strncpy(fieldAddr, pFieldBegin, pFieldEnd - pFieldBegin + 1);
//字段4--类型
pFieldBegin 	= pFieldSep	+ 1;
pFieldSep			= strstr(pFieldBegin, "/r");
if(NULL == pFieldSep)
{
pFieldSep		= strstr(pFieldBegin, "/n");
if(NULL == pFieldSep)
{
pFieldSep		= strstr(pFieldBegin, "0");
}
}
if(NULL == pFieldSep)
{
break;
}
pFieldEnd			= pFieldSep - 1;
strncpy(fieldKind, pFieldBegin, pFieldEnd - pFieldBegin + 1);

pNewNode = (SegmentNode *)malloc(sizeof(SegmentNode));
pNewNode->Segment = (SegmentInfo *)malloc(sizeof(SegmentInfo));
strcpy(pNewNode->Segment->SegNo, fieldSeg);
strcpy(pNewNode->Segment->AreaNo, fieldArea);
strcpy(pNewNode->Segment->Addr, fieldAddr);
strcpy(pNewNode->Segment->Kind, fieldKind);
pNewNode->Segment->NextNo = 0;

pLastNode->Next = pNewNode;
pNewNode->Prev  = pLastNode;
pLastNode				= pNewNode;

segIndex++;

//指向新的一条记录
pRec 		=	strstr(pFieldSep, "/n") + 1;
}
readBufPos = pRec - readBuf;
segmentFilePos += readBufPos;
}
if(NULL != fSegment)
{
fclose(fSegment);
fSegment	= NULL;
}
//printf("nameIndex = [%d]/n", nameIndex);
//printf("segIndex = [%d]/n", segIndex);
}

void ReleaseResource()
{
SegmentNode		*pCurrentNode = segmentList;
SegmentNode		*pNextNode = NULL;

while(NULL != pCurrentNode)
{
if(NULL != pCurrentNode->Segment)
{
free(pCurrentNode->Segment);
}
pNextNode		= pCurrentNode->Next;
free(pCurrentNode);
pCurrentNode = pNextNode;
}
}

void *CreateUserInfo()
{
char		phoneNo[14] = {0};
char		name[10]		= {0};
char		addr[16]		= {0};
char		kind[24]		= {0};

int			nameIndex 	= 0;
int   	segRand			= 0;

int			isOver			= 0;

int     heading     = 0;//在双向列表中的搜索方向

SegmentNode	*pNode 	= segmentList->Next;

srand((int)time(NULL));
while(1)
{
memset(phoneNo, 0, sizeof(phoneNo));
memset(name, 0, sizeof(name));
memset(addr, 0, sizeof(addr));
memset(kind, 0, sizeof(kind));

pthread_mutex_lock(&shareBuf->Mutex);
while(shareBuf->OccupySize >= USER_BUF_SIZE)
{
pthread_cond_wait(&shareBuf->CreateCond,&shareBuf->Mutex);
}
while(shareBuf->OccupySize < USER_BUF_SIZE)
{
/**************************随机生成用户信息******************************/
//随机抽取姓氏
nameIndex  = rand() % 10;
strncpy(name, surname[nameIndex], 2);
//根据GB2312汉字编码空间,随机生成名
name[2]	= 0xB0 + rand() % (0xF7 - 0xB0 + 1);
name[3]	= 0xA1 + rand() % (0xFE - 0xA1 + 1);
name[4]	= 0xB0 + rand() % (0xF7 - 0xB0 + 1);
name[5]	= 0xA1 + rand() % (0xFE - 0xA1 + 1);
//随机抽取号段信息
segRand   = rand() % 100;
if(1 == heading)//前向搜索
{
while(segRand > 0 && NULL != pNode->Next)
{
pNode = pNode->Next;
segRand--;
}
if(NULL == pNode->Next)
{
heading = 0;
}
}
else//逆向搜索
{
while(segRand > 0 && segmentList != pNode->Prev)
{
pNode = pNode->Prev;
segRand--;
}
if(segmentList == pNode->Prev)
{
heading = 1;
}
}
if(pNode->Segment->NextNo > 9999)
{
continue;
}
else
{
//随机生成用户号码
sprintf(phoneNo, "%s%04d", pNode->Segment->SegNo, pNode->Segment->NextNo++);
//获取用户号码归属地
strcpy(addr, pNode->Segment->Addr);
//获取用户号码种类
strcpy(kind, pNode->Segment->Kind);
/************************************************************************/
//写入共享缓存
strcpy(shareBuf->User[shareBuf->NextIn].PhoneNo, phoneNo);
strcpy(shareBuf->User[shareBuf->NextIn].Name, name);
strcpy(shareBuf->User[shareBuf->NextIn].Addr, addr);
strcpy(shareBuf->User[shareBuf->NextIn].Kind, kind);
shareBuf->NextIn = (shareBuf->NextIn + 1) % USER_BUF_SIZE;
shareBuf->OccupySize++;
shareBuf->CreateItemNum++;
if(shareBuf->CreateItemNum >= MAX_USER_NUM)
{
isOver = 1;
}
}
}
pthread_cond_signal(&shareBuf->WriteCond);
pthread_mutex_unlock(&shareBuf->Mutex);

if(isOver)
{
pthread_exit(NULL);
}
}
}

void *WriteUserInfo()
{
FILE	*fUserInfo 		= fopen("userinfo.txt", "ab+");
char	userBuf[100] 	= {0};
int		isOver				= 0;
while(1)
{
pthread_mutex_lock(&shareBuf->Mutex);
while(shareBuf->OccupySize <= 0)
{
pthread_cond_wait(&shareBuf->WriteCond, &shareBuf->Mutex);
}
while(shareBuf->OccupySize > 0)
{
memset(userBuf, 0, sizeof(userBuf));
sprintf(userBuf, "%s|%s|%s|%s/n",
shareBuf->User[shareBuf->NextOut].PhoneNo,
shareBuf->User[shareBuf->NextOut].Name,
shareBuf->User[shareBuf->NextOut].Addr,
shareBuf->User[shareBuf->NextOut].Kind);
fwrite(userBuf, sizeof(char), strlen(userBuf), fUserInfo);
fflush(fUserInfo);
shareBuf->NextOut = (shareBuf->NextOut + 1) % USER_BUF_SIZE;
shareBuf->OccupySize--;

shareBuf->WriteItemNum++;
if(shareBuf->WriteItemNum >= MAX_USER_NUM)
{
isOver = 1;
}
}
pthread_cond_signal(&shareBuf->CreateCond);
pthread_mutex_unlock(&shareBuf->Mutex);

if(isOver)
{
pthread_exit(NULL);
}
}
}
int main(void)
{
pthread_t		create_thread;
pthread_t		write_thread;

ReadInitFile();

shareBuf  	= (UserBuf *)malloc(sizeof(UserBuf));
shareBuf->CreateItemNum	= 0;
shareBuf->WriteItemNum	= 0;
shareBuf->OccupySize		= 0;
shareBuf->NextIn				= 0;
shareBuf->NextOut				= 0;

pthread_mutex_init(&shareBuf->Mutex, NULL);

pthread_cond_init(&shareBuf->CreateCond, NULL);
pthread_cond_init(&shareBuf->WriteCond, NULL);

pthread_create(&create_thread, NULL, (void *)CreateUserInfo, NULL);
pthread_create(&write_thread, NULL, (void *)WriteUserInfo, NULL);

pthread_join(create_thread, NULL);
pthread_join(write_thread, NULL);

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: