简单的双线程数组循环队列缓冲区的实现
2010-02-10 10:52
786 查看
目的,随机生成一千万用户信息。
UserInfoGenerator.h文件:
UserInfoGenerator.c文件:
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; }
相关文章推荐
- 这里实现一个基于数组的线程安全的循环队列
- c语言用简单数组实现循环队列
- 队列--基于简单循环数组实现(Java)
- 数组实现的简单循环队列
- 简单队列和循环队列的实现--数组实现
- 数据结构学习之路(四)用数组简单实现循环队列
- 简单循环队列模版(数组实现)
- 静态数组实现循环队列
- Python 使用循环数组实现队列 (基于class, 包含迭代器)
- 数据结构与算法分析—循环队列的数组实现(C语言)
- C实现简单循环队列
- 队列_数组实现 [循环队列]
- 循环队列的数组实现
- 循环队列的数组实现
- 笔记七:基于数组的循环队列的实现
- Java循环队列简单实现
- 使用循环数组高效的实现队列类
- 无锁队列的实现-循环数组
- Java数组实现循环队列、Java链表实现队列
- 循环队列简单实现