test
第一次 写博客 试验
HWC2020 初赛代码
队名 正在加载…
#include <iostream>
#include <unistd.h>
#include<string.h>
#include<sys/stat.h>
#include<fcntl.h>
#include <sys/mman.h>
#include<sys/wait.h>
#include <algorithm>
#include<unordered_map>
#include<vector>
#include <unordered_set>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
//#include <fstream>
//#include <cmath>
//#include <sys/time.h>
//#include <arm_neon.h>
#define RECORD_NUMBER 280010//预计转账记录条数
#define ID_NUMBER 50010//预计ID个数//TODO:预测id数目前小点更快
#define OUT_NUMBER 3000010//预计输出条数//TODO:参数有重要作用,必须够大
#define PROCESS_NUMBER 10//进程数
#define CPU_NUMBER 4//cpu核数
#define SAVE_SIZE_RATE 3/4 //每个储存块大小=理论最大值*SAVE_SIZE_RATE
//#define TEST
//#define TESTB
using namespace std;
/**
* 输入:一次处理一行
* 储存:用int 数组
* 输出:预存21W//失败,顺序输出很快,但随机输出更慢,因为缓存命中率低
* 微调转字符串函数
* 从环转字符串到共享内存//失败,命中率低负优化
* 使用多进程mmap输出文件
* 信号量多进程协调,原进程不关闭输出文件
*/
#ifdef TEST
int proIdo;
struct ring8{
int node[8];
};
struct ring4{
int node[4];
};
#endif
struct dian{
int id,nxt;
};
/*信号量*/
union semun{
int val;
struct semid_ds *buf;
unsigned short *arry;
};
char* createShmSave(int idNumber);
int mulitProcess(int processNumber);
void recoveryResults(int proId, const char* re_file,int **huan,
const int *index2p,int outFd,char *outFile,int sem_id);
int writeChar(char* outCs,int *huan,int hcnt,int lz,const int *index2p);
int writeCharO(char* outCs,int *huan,int hcnt,int lz,const int *index2p);
int writeCharC(char* outCs,int *huan,int hcnt,int lz);
void initI2C();
pair<int*,int*> bfs(const int *P,const int *V,const int idNumber);
int** dfs(const int *P,const int *NP,const int *V,const int *NV,
const int *NP2,const int *NV2,const int & idNumber,const int & end,const int & start);
pair<int,char*> createFileSave(const char* re_file,int size);
static int create_sem(int number);
static int semaphore_pv(int sem_id,int num,int v);
int hcnt[5];
int index2p[ID_NUMBER];
bool isIdContinuity=false;
int maxIdDigitP;//最大id的位数+1
pid_t proH[PROCESS_NUMBER];
char *shmSave;
int startAdr[PROCESS_NUMBER+1]={0,2,4,6,8,11,18,25,35,45,100};//前面密度大,相同节点数工作量大,保障分配工作量尽量平衡
//int startAdr[PROCESS_NUMBER+1]={0,3,7,12,20,40,100};//前面密度大,相同节点数工作量大,保障分配工作量尽量平衡
/*输出模块分支*/
struct int2CE{
char cs[4];//对齐
};
int2CE int2Cs2[100];//只能在头部,不能在中间
int2CE int2Cs3[1000];//只能用于<1000的数
int2CE int2Cs4[10000];
bool ;
//TODO:+=4组合到6:5里,cl可少赋值一次
#define putCIntO(x,outCs,cl) \
if(x<10000){ \
if(x>999){*(int2CE*)(cl+outCs)=int2Cs4[x]; cl+=4;} \
else{*(int2CE*)(cl+outCs)=int2Cs3[x]; cl+=int2Cs3[x].cs[3];} \
}else if(x<1000000){ \
b=x/10000; \
c=x%10000; \
*(int2CE*)(cl+outCs)=int2Cs2[b]; \
cl+= x>99999? 2:1; \
*(int2CE*)(cl+outCs)=int2Cs4[c]; \
cl+=4; \
}else if(x<100000000){ \
b=x/10000; \
c=x%10000; \
if(x>9999999){outCs[cl]=int2Cs4[b].cs[0];++cl;} \
outCs[cl]=int2Cs4[b].cs[1];++cl; \
outCs[cl]=int2Cs4[b].cs[2];++cl; \
outCs[cl]=int2Cs4[b].cs[3];++cl; \
*(int2CE*)(cl+outCs)=int2Cs4[c]; \
cl+=4; \
}else{ \
a=x/100000000; \
b=x%100000000/10000; \
c=x%100000000%10000; \
*(int2CE*)(cl+outCs)=int2Cs2[a]; \
cl+= x>999999999? 2:1; \
*(int2CE*)(cl+outCs)=int2Cs4[b]; \
*(int2CE*)(cl+4+outCs)=int2Cs4[c]; \
cl+=8; \
}
/***加载数据模块***/
/**
* 读文件
* 过滤自环
* @return <dataIds大小,节点数>
*/
pair<int,int> read(const char* file,int *dataIds,int *index2p){
char *datas;
int length,jid=-1,index=-1,last_x;
int x=0,q=-1;
//有点难已理解,实验表明,不预设大小速度最快!可能是自动增加大小使用就近的内存片更好
unordered_set<int> pset;
int *tempIndex2p=(int*)malloc(ID_NUMBER* sizeof(int));
int fd=open(file,O_RDONLY);//O_RDONLY只读
if(fd==-1) {printf("%s\n", strerror(errno));return pair<int,int>(-1,-1);}
else{
struct stat statbuf{};
fstat(fd, &statbuf);
length=statbuf.st_size;
void *addr2=mmap(NULL,length, PROT_READ, MAP_PRIVATE, fd, 0); //mmap映射系统内存池到进程内存
if (MAP_FAILED == addr2) {
printf("mmap: %s\n", strerror(errno));
}
datas=(char *)addr2;
}
for(int jd=0;jd<length;){//一次处理一行
#define inInt(x) \
if(datas[jd+1]==','){ \
x=datas[jd]-'0'; \
jd+=2; \
}else if(datas[jd+2]==','){ \
x=(datas[jd]-'0')*10+(datas[jd+1]-'0'); \
jd+=3; \
}else if(datas[jd+3]==','){ \
x=(datas[jd]-'0')*100+(datas[jd+1]-'0')*10+(datas[jd+2]-'0'); \
jd+=4; \
}else if(datas[jd+4]==','){ \
x=(datas[jd]-'0')*1000+(datas[jd+1]-'0')*100+(datas[jd+2]-'0')*10+(datas[jd+3]-'0'); \
jd+=5; \
}else if(datas[jd+5]==','){ \
x=(datas[jd]-'0')*10000+(datas[jd+1]-'0')*1000+(datas[jd+2]-'0')*100+(datas[jd+3]-'0')*10+(datas[jd+4]-'0'); \
jd+=6; \
}else if(datas[jd+6]==','){ \
x=(datas[jd]-'0')*100000+(datas[jd+1]-'0')*10000+(datas[jd+2]-'0')*1000+(datas[jd+3]-'0')*100 \
+(datas[jd+4]-'0')*10+(datas[jd+5]-'0');jd+=7; \
}else if(datas[jd+7]==','){ \
x=(datas[jd]-'0')*1000000+(datas[jd+1]-'0')*100000+(datas[jd+2]-'0')*10000+(datas[jd+3]-'0')*1000 \
+(datas[jd+4]-'0')*100+(datas[jd+5]-'0')*10+(datas[jd+6]-'0');jd+=8; \
}else if(datas[jd+8]==','){ \
x=(datas[jd]-'0')*10000000+(datas[jd+1]-'0')*1000000+(datas[jd+2]-'0')*100000+(datas[jd+3]-'0')*10000 \
+(datas[jd+4]-'0')*1000+(datas[jd+5]-'0')*100+(datas[jd+6]-'0')*10+(datas[jd+7]-'0');jd+=9; \
}else if(datas[jd+9]==','){ \
x=(datas[jd]-'0')*100000000+(datas[jd+1]-'0')*10000000+(datas[jd+2]-'0')*1000000+(datas[jd+3]-'0')*100000 \
+(datas[jd+4]-'0')*10000+(datas[jd+5]-'0')*1000+(datas[jd+6]-'0')*100+(datas[jd+7]-'0')*10+(datas[jd+8]-'0'); \
jd+=10; \
}else{ \
x=(datas[jd]-'0')*1000000000+(datas[jd+1]-'0')*100000000+(datas[jd+2]-'0')*10000000+(datas[jd+3]-'0')*1000000+(datas[jd+4]-'0')*100000 \
+(datas[jd+5]-'0')*10000+(datas[jd+6]-'0')*1000+(datas[jd+7]-'0')*100+(datas[jd+8]-'0')*10+(datas[jd+9]-'0'); \
jd+=11; \
}
inInt(last_x);
inInt(x);
if(pset.find(last_x)==pset.end()){
pset.insert(last_x);
tempIndex2p[++index]=last_x;
}
if(pset.find(x)==pset.end()){
pset.insert(x);
tempIndex2p[++index]=x;
}
dataIds[jid+1]=last_x;
dataIds[jid+=2]=x;
if(datas[jd+1]=='\n'){jd+=2;}
else if(datas[jd+2]=='\n'){jd+=3;}
else if(datas[jd+3]=='\n'){jd+=4;}
else if(datas[jd+4]=='\n'){jd+=5;}
else if(datas[jd+5]=='\n'){jd+=6;}
else if(datas[jd+6]=='\n'){jd+=7;}
else if(datas[jd+7]=='\n'){jd+=8;}
else if(datas[jd+8]=='\n'){jd+=9;}
else if(datas[jd+9]=='\n'){jd+=10;}
else{jd+=11;}
}
jid+=1;index+=1;
int max=tempIndex2p[0];
for(int i=1;i<index;++i){if(tempIndex2p[i]>max) max=tempIndex2p[i];}
maxIdDigitP=2;
for(int tempMax=max;tempMax>9;tempMax/=10,++maxIdDigitP);
if(max==index-1){//无需映射
isIdContinuity=true;
for(int i=0;i<index;++i){
index2p[i]=i;
}
}else{
unordered_map<int,int> pmap;
sort(tempIndex2p,tempIndex2p+index);
for(int newindex=0;newindex<index;++newindex){
pmap.insert(pair<int,int>(tempIndex2p[newindex],newindex));
index2p[newindex]=tempIndex2p[newindex];
}
for(int i=0;i<jid;i+=2){
dataIds[i]=pmap.find(dataIds[i])->second;
dataIds[i+1]=pmap.find(dataIds[i+1])->second;
}
}
munmap((void *)datas,length);
return pair<int,int>(jid,index);
}
void loadDatas(const char* file,const char* re_file){
int idNumber=0,length,l=0;//不同id个数,文件长度,输入条数*2
int *P,*V,*NP,*NV;
int *dataIds=new int[RECORD_NUMBER<<1];//int版数据
#ifdef TEST
clockid_t startT=clock();
#endif
pair<int,int> rep=read(file,dataIds,index2p);
#ifdef TEST
printf("读入数据耗时%d\n",clock()-startT);
startT=clock();
#endif
l=rep.first;
idNumber=rep.second;
P=new int[idNumber+1];
NP=new int[idNumber+1];
//出度数
memset(P,0,sizeof(int)*idNumber);
memset(NP,0,sizeof(int)*idNumber);
int jid=0;
while(jid<l){
++P[dataIds[jid]];
++NP[dataIds[jid+1]];
jid+=2;
}
//将指向节点存入V中
jid=0;
while(jid<idNumber){
P[jid+1]+=P[jid];
NP[jid+1]+=NP[jid];
++jid;
}
P[idNumber]=P[idNumber-1];//多记一个下标,不用判断v结束的位置
NP[idNumber]=NP[idNumber-1];
V=new int[P[idNumber]];
NV=new int[NP[idNumber]];
jid=0;
while(jid<l){
V[--P[dataIds[jid]]]=dataIds[jid+1];
NV[--NP[dataIds[jid+1]]]=dataIds[jid];
jid+=2;
}
jid=0;
while(jid<idNumber){
sort(V+P[jid],V+P[jid+1],greater<int>());
sort(NV+NP[jid],NV+NP[jid+1],greater<int>());
//反向边无需排序,但排序能让节点小的先被访问,如果数据集按节点从小到大输入,更容易访问连续,提高缓存命中率
++jid;
}
delete [] dataIds;
// pair<int*,int*> npv2=bfs(NP,NV,idNumber);//
#ifdef TEST
printf("生成V、NV边耗时%d\n",clock()-startT);
#endif
shmSave=createShmSave(512);
pair<int,char*>writefile=createFileSave(re_file,OUT_NUMBER*7*maxIdDigitP);
int sem_id=create_sem(2);
int proId=mulitProcess(PROCESS_NUMBER);
int start=startAdr[proId]*idNumber/100,end;
if(proId<PROCESS_NUMBER-1){
end=startAdr[proId+1]*idNumber/100;
}else{
end=idNumber-2;
}
#ifdef TEST
proIdo=proId;
startT=clock();
#endif
int** rings=dfs(P,NP,V,NV,NULL,NULL,idNumber,end,start);
#ifdef TEST
printf("进程%d搜环耗时%d\n",proIdo,clock()-startT);
#endif
recoveryResults(proId,re_file,rings,index2p,writefile.first,writefile.second,sem_id);
#ifdef TEST
printf("进程%d收集耗时%d\n",proIdo,clock()-startT);
#endif
/*
// delete [] NP;
// delete [] NV;
// delete [] P;
// delete [] V;
// delete [] index2p;
// delete [] inputCs;
// for(int ti=0;ti<5;++ti){
// delete [] huan[ti];
// }
// printf("进程::%d结束\n",hcnt[0]+hcnt[1]+hcnt[2]+hcnt[3]+hcnt[4]);
*/
}
/***搜环***/
/*求正或反向间隔到达点集*/
pair<int*,int*> bfs(const int *P,const int *V,const int idNumber){
clock_t start=clock();
int *P2,*V2,*st;
char *bj;
register int q,l,q2,l2,i2,i3,sti=-1,js;
P2=(int*)malloc((idNumber+1)*sizeof(int));
st=(int*)malloc(idNumber*sizeof(int));
bj=(char*)malloc((idNumber>>3));//32位标记32个
memset(bj,0,idNumber>>3);
for(int i=0;i<idNumber;++i){
for(;sti>-1;--sti){bj[st[sti]]=0;}
js=0;
q=P[i];l=P[i+1];
for(;q<l;++q){
q2=P[V[q]];l2=P[V[q]+1];
for(;q2<l2;++q2) {
i3=V[q2];
if(i3!=i){
if(bj[i3>>3]==0){
st[++sti]=i3>>3;
bj[i3>>3]|=(1<<(i3&7));
++js;
}else if(!(bj[i3>>3]&(1<<(i3&7)))){
bj[i3>>3]|=(1<<(i3&7));
++js;
}
}
}
}
P2[i]=js;
}
for(int i=1;i<idNumber;++i){
P2[i]+=P2[i-1];
}
P2[idNumber]=P2[idNumber-1];
V2=(int*)malloc((P2[idNumber]+1)*sizeof(int));
// printf("耗时1:%d\n",clock()-start);
start=clock();
for(int i=0;i<idNumber;++i){
for(;sti>-1;--sti){bj[st[sti]]=0;}
q=P[i];l=P[i+1];
for(;q<l;++q){
i2=V[q];
q2=P[i2+1]-1;l2=P[i2]-1;
for(;q2>l2;--q2) {
i3=V[q2];
if(i3!=i){
if(bj[i3>>3]==0){
st[++sti]=i3>>3;
bj[i3>>3]|=(1<<(i3&7));
V2[--P2[i]] = i3;
}else if(!(bj[i3>>3]&(1<<(i3&7)))){
bj[i3>>3]|=(1<<(i3&7));
V2[--P2[i]] = i3;
}
}
}
}
}
delete bj;
delete st;
// printf("耗时2:%d\n",clock()-start);
// printf("总数%d\n",P2[idNumber]);
return pair<int*,int*>(P2,V2);
}
int** dfs(const int *P,const int *NP,const int *V,const int *NV,
const int *NP2,const int *NV2,const int & idNumber,const int & end,const int & start){
int *thuan0=(int*)malloc((OUT_NUMBER/7)*3*sizeof(int));
int *thuan1=(int*)malloc((OUT_NUMBER/6)*4*sizeof(int));
int *thuan2=(int*)malloc((OUT_NUMBER/5)*5*sizeof(int));
int *thuan3=(int*)malloc((OUT_NUMBER/4)*6*sizeof(int));
int *thuan4=(int*)malloc((OUT_NUMBER/2)*7*sizeof(int));
int *jxu=(int*)malloc(idNumber*sizeof(int));
int hi0=0,hi1=0,hi2=0,hi3=0,hi4=0;
char *fl=(char*)malloc(idNumber);//00011全部1、2重一定可达,10100全5、3重可能达
int *stf=(int *)malloc(idNumber* sizeof(int));
register int q,l,i1,q2,l2,i2,q3,l3,i3,q4,l4,i4,q5,l5,i5,q6,l6,i6,sti=-1;
memset(fl,0,idNumber);
memset(jxu,-1,sizeof(int)*idNumber);
#ifdef TEST
// clockid_t startT=clock();
#endif
// dian2 f1={-1,-1};
//TODO: (i1=NV[q])>jid;向量寄存器赋值环,重排判断规则
for(int jid=end-1;jid>=start;--jid){
for(;sti>-1;--sti){fl[(i3=stf[sti])]=0;jxu[i3]=-1;}
//反向边可达标记
q=NP[jid];l=NP[jid+1];
for(;q<l && NV[q]>jid;++q) {
i1 = NV[q];
if(fl[i1]==0){stf[++sti]=i1;}
fl[i1] |= 1;
q2 = NP[i1];l2 = NP[i1 + 1];
for (;q2<l2 && NV[q2] > jid;++q2) {
i2 = NV[q2];
jxu[i2]=(jxu[i2]==-1)? i1:-2;
if (fl[i2] == 0) { stf[++sti] = i2; }
fl[i2] |= 2;
q3 = NP[i2];l3=NP[i2+1];
for (; q3 < l3 && NV[q3]>jid; ++q3) {
i3=NV[q3];
if (i3!=i1) {
if (fl[i3] == 0) { stf[++sti] = i3; }
fl[i3] |= 4;
}
}
}
}
//正向搜索环
q=P[jid],l=P[jid+1];
for(;q<l && V[q]>jid;++q){
i1=V[q];
q2=P[i1],l2=P[i1+1];
for(;q2<l2 && V[q2]>jid;++q2) {
i2 = V[q2];
q3=P[i2];l3=P[i2+1];
for(;q3<l3 && V[q3]>jid;++q3) {
i3=V[q3];
if(i3!=i1){
q4=P[i3];l4=P[i3+1];
for(;q4<l4 && V[q4]>jid;++q4) {
i4=V[q4];
if(i4==i2||i4==i1) continue;
if ((fl[i4]&6)){
q5=P[i4];l5=P[i4+1];
for(;q5<l5 && V[q5]>jid;++q5) {
i5=V[q5];
if(i5==i3||i5==i2||i5==i1) continue;
if (fl[i5]&2){
if((i6=jxu[i5])!=-2){
if(i6!=i4&&i6!=i3&&i6!=i2&&i6!=i1){
thuan4[hi4]=jid;thuan4[hi4+1]=i1;thuan4[hi4+2]=i2;
thuan4[hi4+3]=i3;thuan4[hi4+4]=i4;thuan4[hi4+5]=i5;
thuan4[hi4+6]=i6;hi4+=7;
}
}else{
q6=P[i5];l6=P[i5+1];
for(;q6<l6 && V[q6]>jid;++q6) {
i6=V[q6];
if ((fl[i6]&1)&&i6!=i4&&i6!=i3&&i6!=i2&&i6!=i1){
thuan4[hi4]=jid;thuan4[hi4+1]=i1;thuan4[hi4+2]=i2;
thuan4[hi4+3]=i3;thuan4[hi4+4]=i4;thuan4[hi4+5]=i5;
thuan4[hi4+6]=i6;hi4+=7;
}
}
}
}
if ((fl[i5]&1)){
thuan3[hi3]=jid;thuan3[hi3+1]=i1;thuan3[hi3+2]=i2;
thuan3[hi3+3]=i3;thuan3[hi3+4]=i4;thuan3[hi3+5]=i5;
hi3+=6;
}
}
}
if (fl[i4]&1){
thuan2[hi2]=jid;thuan2[hi2+1]=i1;thuan2[hi2+2]=i2;
thuan2[hi2+3]=i3;thuan2[hi2+4]=i4;hi2+=5;
}
}
if (fl[i3]&1){
thuan1[hi1]=jid;thuan1[hi1+1]=i1;thuan1[hi1+2]=i2;
thuan1[hi1+3]=i3;hi1+=4;
}
}
}
if(fl[i2]&1){//3环
thuan0[hi0]=jid;thuan0[hi0+1]=i1;thuan0[hi0+2]=i2;
hi0+=3;
}
}
}
}
hcnt[0]=hi0/3;hcnt[1]=hi1/4;hcnt[2]=hi2/5;hcnt[3]=hi3/6;hcnt[4]=hi4/7;
int **huans=new int*[5];
huans[0]=thuan0;huans[1]=thuan1;huans[2]=thuan2;huans[3]=thuan3;huans[4]=thuan4;
#ifdef TEST
// printf("进程%d耗时%d\n",proIdo,clock()-startT);
// printf("进程%d:原搜索:%d,%d,%d,%d,%d\n",proIdo,hi0/3,hi1/4,hi2/5,hi3/6,hi4/7);
// for(int i=0;i<hi0;++i){
// if(thuan0[i]!=huan4[0][i/3].node[i%3]){
// printf("%d!=%d\n",thuan0[i],huan4[0][i/3].node[i%3]);
// }
// }
// for(int i=0;i<hcnt[0];i+=3){
// if(thuan0[i*3]==169&&thuan0[i*3+1]==223){
// printf(">>>>%d,%d,%d\n",thuan0[i*3],thuan0[i*3+1],thuan0[i*3+2]);
// }
// }
#endif
delete stf;
delete fl;
return huans;
}
/***多进程模块***/
/*信号量*/
static int create_sem(int number){
int sem_id = semget((key_t)1234, number, 0666 | IPC_CREAT);
if(sem_id==-1) printf("信号量创建失败\n");
//用于初始化信号量值,在使用信号量前必须这样做
union semun sem_union;
sem_union.val = 0;
while (number--){
if(semctl(sem_id, number, SETVAL,sem_union) == -1){
printf("信号量初始化失败\n");return 0;
}
}
return sem_id;
}
//警告:SEM_UNDO网上称操作系统跟踪,并进程结束时"自动释放",
//实际测验就是让它之前的操作全部撤回,不知道是什么智障设定,不排除-O3"优化"删除了进程结束前的信号量操作语句可能性
//逻辑上需注意进程结束后之前的操作相当于没有
static int semaphore_pv(int sem_id,int num,int v){
//这是一个释放操作,它使信号量变为可用,即发送信号V(sv)
struct sembuf sem_b;
sem_b.sem_num = num;
sem_b.sem_op = v;//V()
sem_b.sem_flg = SEM_UNDO;
if(semop(sem_id, &sem_b, 1) == -1){
fprintf(stderr, "semaphore_pv failed\n");
return 0;
}
return 1;
}
/*创建共享内存*/
char* createShmSave(int size){
void *addr=mmap(NULL,size,PROT_READ | PROT_WRITE,MAP_SHARED | MAP_ANON,-1,0);
if (MAP_FAILED == addr) {
printf("mmap: %s\n", strerror(errno));
}
return (char *)addr;
}
pair<int,char*> createFileSave(const char *re_file,int size){
//创建写文件
int outFd = open(re_file, O_RDWR | O_CREAT, 0666);
if (outFd < 0) {
printf("open <%d> failed: %s\n", outFd, strerror(errno));
}
void *addr=mmap(NULL, size , PROT_READ | PROT_WRITE, MAP_SHARED, outFd, 0); //mmap映射系统内存池到进程内存
if (MAP_FAILED == addr) {
printf("mmap: %s\n", strerror(errno));
}
return pair<int,char*>(outFd,(char *)addr);
}
/*开启多进程*/
int mulitProcess(int processNumber){
int proId=1;
while(proId<processNumber){
pid_t fpid=fork();//进程号
if (fpid < 0)
printf("error in fork!");
else if (fpid == 0) {//子进程
return proId;
}else {//父进程
}
proH[proId]=fpid;
++proId;
}
return 0;//父进程
}
//TODO:输出文件按字符串长度重排输出 50重新划分为10组
void recoveryResults(int proId, const char* re_file,int **huan,const int *index2p
,int outFd,char *outFile,int sem_id){
int basel=sizeof(int)*6;
int baselC=min(OUT_NUMBER*7*11*SAVE_SIZE_RATE,OUT_NUMBER*7*maxIdDigitP);
char *outC=(char*)malloc(baselC);
int cls[5];
int lsize=0;
for(int i=0;i<5;++i){
cls[i]=writeChar(outC+lsize,huan[i],hcnt[i]*(i+3),i+3,index2p);
lsize+=cls[i];
}
int offsetShm[5];
for(int i=0,temp=0;i<5;temp+=cls[i],++i){
offsetShm[i]=temp;
}
if(proId>0){
//传递文件文件长度信息
memcpy(shmSave+proId*basel,cls,5*sizeof(int));
*(int*)(shmSave+proId*basel+sizeof(int)*5)=hcnt[0]+hcnt[1]+hcnt[2]+hcnt[3]+hcnt[4];
semaphore_pv(sem_id,0,1);
//写文件
semaphore_pv(sem_id,1,-1);
int *outOffset=(int*)(shmSave+proId*5*sizeof(int));
for(int i=0;i<5;++i){
memcpy(outFile+outOffset[i],outC+offsetShm[i],cls[i]);
}
return;
}
//父进程
//搜集信息
semaphore_pv(sem_id,0,1-PROCESS_NUMBER);
// for(int i=1;i<PROCESS_NUMBER;++i){
// printf("进程%d读信号量%d\n",proId,i);
// semaphore_pv(sem_id,0,-1);
// }
#ifdef TESTB
clockid_t startT=clock();
#endif
int shml[PROCESS_NUMBER][5];
for(int i=0;i<5;++i){
shml[0][i]=cls[i];
}
int sumOut=hcnt[0]+hcnt[1]+hcnt[2]+hcnt[3]+hcnt[4];
int *tempC=(int*)shmSave;
for(int ti=1;ti<PROCESS_NUMBER;++ti){
for(int i=0;i<5;++i){
shml[ti][i]=tempC[ti*6+i];
}
sumOut+=tempC[ti*6+5];
}
/*写入输出文件*/
//条数占位
char cfirst[12];
int outOffset=0,a,b,c;
putCIntO(sumOut,cfirst,outOffset);
cfirst[outOffset]='\n';
++outOffset;
//计算映射shm位置
int filelength=outOffset;
int nfs=6* sizeof(int);
for(int i=0;i<PROCESS_NUMBER;++i){
for(int j=0;j<5;++j){
filelength+=shml[i][j];
}
}
//写文件
ftruncate(outFd, filelength);
int outOffsets[PROCESS_NUMBER*5];
int tempOF=outOffset;
for(int i=0;i<5;++i){
for(int j=0;j<PROCESS_NUMBER;++j){
outOffsets[j*5+i]=tempOF;
tempOF+=shml[j][i];
}
}
memcpy(shmSave,outOffsets, sizeof(int)*PROCESS_NUMBER*5);
#ifdef TESTB
printf("信息搜集耗时%d\n",clock()-startT);
#endif
semaphore_pv(sem_id,1,PROCESS_NUMBER-1);
memcpy(outFile,cfirst,outOffset);
for(int i=0;i<5;++i){
memcpy(outFile+outOffsets[i],outC+offsetShm[i],cls[i]);
}
#ifdef TESTB
for(int ti=1;ti<PROCESS_NUMBER;++ti) {
//本地测试时在父进程结束时就调用对比结果文件,子进程还没有输出完,结果文件不全无法正确对比
wait(NULL);
}
#endif
// munmap(addr,filelength);
// munmap((void*)shmSave,PROCESS_NUMBER*basel+10);
// printf("总环数:%d",sumOut);///
}
/***输出模块***/
#define putCInt(h) x=h;putCIntO(x,outCs,cl);
inline void initI2C(){
int i,j,z,p;
for(j=0;j<10;++j){
int2Cs2[j]={static_cast<char>(j+'0'),0,0,0};
int2Cs3[j]={static_cast<char>(j+'0'),0,0,1};
for(z=0;z<10;++z){
for(p=0;p<10;++p){
int2Cs4[j*100+z*10+p]={'0',static_cast<char>(j+'0')
,static_cast<char>(z+'0'),static_cast<char>(p+'0')};
}
}
}
for(i=1;i<10;++i){
for(j=0;j<10;++j){
int2Cs2[i*10+j]={static_cast<char>(i+'0'),static_cast<char>(j+'0'),0,0};
int2Cs3[i*10+j]={static_cast<char>(i+'0'),static_cast<char>(j+'0'),0,2};
for(z=0;z<10;++z){
int2Cs3[i*100+j*10+z]={static_cast<char>(i+'0'),static_cast<char>(j+'0'),
static_cast<char>(z+'0'),3};
for(p=0;p<10;++p){
int2Cs4[i*1000+j*100+z*10+p]={static_cast<char>(i+'0'),static_cast<char>(j+'0')
,static_cast<char>(z+'0'),static_cast<char>(p+'0')};
}
}
}
}
}
/**
* 写入char*
* @return 写入长度
*/
int writeChar(char* outCs,int *huan,int hcnt,int lz,const int *index2p){
return isIdContinuity?writeCharC(outCs,huan,hcnt,lz):writeCharO(outCs,huan,hcnt,lz,index2p);
}
int writeCharO(char* outCs,int *huan,int hcnt,int lz,const int *index2p){
int cl=0,j;
int a,b,c,x;//x=0aaabbbccc
switch(lz){
case 3:
for(j=hcnt-3;j>-1;j-=3){
putCInt(index2p[huan[j]]);
outCs[cl]=',';++cl;
putCInt(index2p[huan[j+1]]);
outCs[cl]=',';++cl;
putCInt(index2p[huan[j+2]]);
outCs[cl]='\n';++cl;
}
break;
case 4:
for(j=hcnt-4;j>-1;j-=4){
putCInt(index2p[huan[j]]);
outCs[cl]=',';++cl;
putCInt(index2p[huan[j+1]]);
outCs[cl]=',';++cl;
putCInt(index2p[huan[j+2]]);
outCs[cl]=',';++cl;
putCInt(index2p[huan[j+3]]);
outCs[cl]='\n';++cl;
}
break;
case 5:
for(j=hcnt-5;j>-1;j-=5){
putCInt(index2p[huan[j]]);
outCs[cl]=',';++cl;
putCInt(index2p[huan[j+1]]);
outCs[cl]=',';++cl;
putCInt(index2p[huan[j+2]]);
outCs[cl]=',';++cl;
putCInt(index2p[huan[j+3]]);
outCs[cl]=',';++cl;
putCInt(index2p[huan[j+4]]);
outCs[cl]='\n';++cl;
}
break;
case 6:
for(j=hcnt-6;j>-1;j-=6){
putCInt(index2p[huan[j]]);
outCs[cl]=',';++cl;
putCInt(index2p[huan[j+1]]);
outCs[cl]=',';++cl;
putCInt(index2p[huan[j+2]]);
outCs[cl]=',';++cl;
putCInt(index2p[huan[j+3]]);
outCs[cl]=',';++cl;
putCInt(index2p[huan[j+4]]);
outCs[cl]=',';++cl;
putCInt(index2p[huan[j+5]]);
outCs[cl]='\n';++cl;
}
break;
case 7:
for(j=hcnt-7;j>-1;j-=7){
putCInt(index2p[huan[j]]);
outCs[cl]=',';++cl;
putCInt(index2p[huan[j+1]]);
outCs[cl]=',';++cl;
putCInt(index2p[huan[j+2]]);
outCs[cl]=',';++cl;
putCInt(index2p[huan[j+3]]);
outCs[cl]=',';++cl;
putCInt(index2p[huan[j+4]]);
outCs[cl]=',';++cl;
putCInt(index2p[huan[j+5]]);
outCs[cl]=',';++cl;
putCInt(index2p[huan[j+6]]);
outCs[cl]='\n';++cl;
}
break;
}
return cl;
}
/*无映射版*/
int writeCharC(char* outCs,int *huan,int hcnt,int lz){
int cl=0,j;
int a,b,c,x;//x=0aaabbbccc
switch(lz){
case 3:
for(j=hcnt-3;j>-1;j-=3){
putCInt(huan[j]);
outCs[cl]=',';++cl;
putCInt(huan[j+1]);
outCs[cl]=',';++cl;
putCInt(huan[j+2]);
outCs[cl]='\n';++cl;
}
break;
case 4:
for(j=hcnt-4;j>-1;j-=4){
putCInt(huan[j]);
outCs[cl]=',';++cl;
putCInt(huan[j+1]);
outCs[cl]=',';++cl;
putCInt(huan[j+2]);
outCs[cl]=',';++cl;
putCInt(huan[j+3]);
outCs[cl]='\n';++cl;
}
break;
case 5:
for(j=hcnt-5;j>-1;j-=5){
putCInt(huan[j]);
outCs[cl]=',';++cl;
putCInt(huan[j+1]);
outCs[cl]=',';++cl;
putCInt(huan[j+2]);
outCs[cl]=',';++cl;
putCInt(huan[j+3]);
outCs[cl]=',';++cl;
putCInt(huan[j+4]);
outCs[cl]='\n';++cl;
}
break;
case 6:
for(j=hcnt-6;j>-1;j-=6){
putCInt(huan[j]);
outCs[cl]=',';++cl;
putCInt(huan[j+1]);
outCs[cl]=',';++cl;
putCInt(huan[j+2]);
outCs[cl]=',';++cl;
putCInt(huan[j+3]);
outCs[cl]=',';++cl;
putCInt(huan[j+4]);
outCs[cl]=',';++cl;
putCInt(huan[j+5]);
outCs[cl]='\n';++cl;
}
break;
case 7:
for(j=hcnt-7;j>-1;j-=7){
putCInt(huan[j]);
outCs[cl]=',';++cl;
putCInt(huan[j+1]);
outCs[cl]=',';++cl;
putCInt(huan[j+2]);
outCs[cl]=',';++cl;
putCInt(huan[j+3]);
outCs[cl]=',';++cl;
putCInt(huan[j+4]);
outCs[cl]=',';++cl;
putCInt(huan[j+5]);
outCs[cl]=',';++cl;
putCInt(huan[j+6]);
outCs[cl]='\n';++cl;
}
break;
}
return cl;
}
void inline init(){
initI2C();
}
int main(){
init();
loadDatas("/data/test_data.txt","/projects/student/result.txt");
return 0;
}