测试

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;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值