|
[探究]【街机模拟器格斗游戏联网对战,是如何同步的?】
Lockstep |
|
[注意]证明我还活着
去她面前摇 |
|
[注意]比CC,DD更为强大的姿势
换掉3389,用自己的远程工具这招就没用了。 |
|
[原创]代码保护之网
做个记号..支持一下. |
|
[原创]一种多线程基于计数无锁实现
这样吗?? /* Interlocked SList queue using keyed event signaling */ struct queue { SLIST_HEADER slist; // Note: Multiple queues can (and should) share a keyed event handle HANDLE keyed_event; // Initial value: 0 // Prior to blocking, the queue_pop function increments this to 1, then // rechecks the queue. If it finds an item, it attempts to compxchg back to // 0; if this fails, then it's racing with a push, and has to block LONG block_flag; }; void init_queue(queue *qPtr) { NtCreateKeyedEvent(&qPtr->keyed_event, -1, NULL, 0); InitializeSListHead(&qPtr->slist); qPtr->blocking = 0; } void queue_push(queue *qPtr, SLIST_ENTRY *entry) { InterlockedPushEntrySList(&qPtr->slist, entry); // Transition block flag 1 -> 0. If this succeeds (block flag was 1), we // have committed to a keyed-event handshake LONG oldv = InterlockedCompareExchange(&qPtr->block_flag, 0, 1); if (oldv) { NtReleaseKeyedEvent(qPtr->keyed_event, (PVOID)qPtr, FALSE, NULL); } } SLIST_ENTRY *queue_pop(queue *qPtr) { SLIST_ENTRY *entry = InterlockedPopEntrySList(&qPtr->slist); if (entry) return entry; // fast path // Transition block flag 0 -> 1. We must recheck the queue after this point // in case we race with queue_push; however since ReleaseKeyedEvent // blocks until it is matched up with a wait, we must perform the wait if // queue_push sees us LONG oldv = InterlockedCompareExchange(&qPtr->block_flag, 1, 0); assert(oldv == 0); entry = InterlockedPopEntrySList(&qPtr->slist); if (entry) { // Try to abort oldv = InterlockedCompareExchange(&qPtr->block_flag, 0, 1); if (oldv == 1) return entry; // nobody saw us, we can just exit with the value } // Either we don't have an entry, or we are forced to wait because // queue_push saw our block flag. So do the wait NtWaitForKeyedEvent(qPtr->keyed_event, (PVOID)qPtr, FALSE, NULL); // block_flag has been reset by queue_push if (!entry) entry = InterlockedPopEntrySList(&qPtr->slist); assert(entry); return entry; } |
|
[分享]根据国外的开源B树写了一份C++版本。
//状态宏定义 #define TRUE 1 #define FALSE 0 #define OK 1 #define ERROR 0 #define INFEASIBLE -1 #define OVERFLOW -2 typedef int Status; #include "iostream.h" #include "Define.h" #define M 3 typedef class BNode //B-树节点结构体 { public: int Ext; //节点中包含有效关键字的数目,初始化的时候为0,取值1或2 int Elem[M-1]; //关键字数组,2个关键字 BNode *Ptr[M]; //下一级指针,3个指针 BNode *Parent; //指向双亲的指针 int ParentPosition; //指向该节点的指针在双亲节点下级指针数组中的位置 BNode(); //构造函数 }BNode,*BTree; BNode::BNode() { Ext=0; //初始化元素个数为0 int i=0; for(i=0;i<M;i++) //初始化所有指向下级的指针为空 Ptr[i]=NULL; Parent=NULL; //初始化指向双亲指针为空 ParentPosition=-1; //初始化指向该节点的指针在双亲节点下级指针数组中的位置为-1 } class ElemInfo //需要加入的节点的信息结构体 { public: int Elem; //需要加入的关键字 BNode *EL; //该关键字对应的左边的指向下级的指针 BNode *ER; //该关键字对应的右边的指向下级的指针 ElemInfo(int x=0){Elem=x;EL=ER=NULL;};//构造函数以x初始化关键字,左右指向下级的指针初始化为空 }; #include "Queue.h"//包含队列头文件 BNode *FindPosition(int Elem,BTree T) //该函数返回关键字Elem在B-树中应该插入的位置,前提,Elem不在树中 { if(!T) return NULL; else { int i=0; while(i<T->Ext&&T->Elem[i]<Elem) i++; BNode *p=FindPosition(Elem,T->Ptr[i]); if(p==NULL) return T; else return p; } } BNode *InsertElem(ElemInfo EI,BNode * &p) //该函数完成将节点信息结构体EI插入到p指向的节点当中,用递归完成了分裂和上升 { if(!p||p->Ext==0)//插入到空的p中或者p不存在,主要用于处理树的分裂时需要申请新节点和删除时节点的移位 { if(!p) p=new BNode; p->Elem[0]=EI.Elem; if(EI.ER!=NULL&&EI.EL!=NULL)//插入的同时调整了下级的Parent指针和ParentPosition { p->Ptr[0]=EI.EL; p->Ptr[0]->ParentPosition=0; p->Ptr[0]->Parent=p; p->Ptr[1]=EI.ER; p->Ptr[1]->ParentPosition=1; p->Ptr[1]->Parent=p; } p->Ext++; return p; } else if(p->Ext<M-1)//p中有一个元素 { if(EI.Elem>p->Elem[0])//要插入的关键字大于存在的关键字,插入的同时调整了下级的Parent指针和ParentPosition { if(EI.ER) { p->Ptr[2]=EI.ER; p->Ptr[2]->ParentPosition=2; p->Ptr[2]->Parent=p; p->Ptr[1]=EI.EL; p->Ptr[1]->ParentPosition=1; p->Ptr[1]->Parent=p; } p->Elem[1]=EI.Elem; p->Ext++; return p; } else//要插入的关键字小于存在的关键字,插入的同时调整了下级的Parent指针和ParentPosition { p->Elem[1]=p->Elem[0]; if(p->Ptr[1]) { p->Ptr[2]=p->Ptr[1]; p->Ptr[2]->ParentPosition=2; p->Ptr[1]=EI.ER; p->Ptr[1]->ParentPosition=1; p->Ptr[1]->Parent=p; p->Ptr[0]=EI.EL; p->Ptr[0]->ParentPosition=0; p->Ptr[0]->Parent=p; } p->Elem[0]=EI.Elem; p->Ext++; return p; } } //以下是待插入的节点已经存在两个关键字的情况 else if(EI.Elem>p->Elem[1])//待插入关键字大于已存在的两个关键字 { BNode *newp=new BNode;//分裂 if(EI.ER)//将待插入的关键字及其信息放入新节点 { newp->Ptr[1]=EI.ER; newp->Ptr[1]->ParentPosition=1; newp->Ptr[0]=EI.EL; } newp->Elem[0]=EI.Elem; newp->Ext++; p->Ptr[2]=NULL; p->Ext--; EI.Elem=p->Elem[1];//将已存在的两个关键字中大的一个封装成下一步的待插入节点 EI.EL=p; EI.ER=newp; newp->Parent=InsertElem(EI,p->Parent);//将新的待插入节点插入到现有节点的父亲中,及上升 if(p->Parent==NULL) { p->Parent=newp->Parent; } else if(p->Parent->Ptr[p->ParentPosition]==NULL) { p->Parent=newp->Parent; p->ParentPosition=newp->ParentPosition-1; } return newp;//调用前的新节点的父亲是这里的新节点 } else if(EI.Elem>p->Elem[0])//待插入的关键字位于已存在的两个关键字中间 { BNode *newp=new BNode; if(p->Ptr[2])//将已存在关键字较大的一个放入新生成的节点 { newp->Ptr[1]=p->Ptr[2]; newp->Ptr[1]->ParentPosition=1; newp->Ptr[1]->Parent=newp; newp->Ptr[0]=EI.ER; newp->Ptr[0]->ParentPosition=0; } newp->Elem[0]=p->Elem[1]; newp->Ext++; p->Ptr[2]=NULL; if(EI.EL) { p->Ptr[1]=EI.EL; p->Ptr[1]->ParentPosition=1; p->Ptr[1]->Parent=p; } p->Ext--; EI.EL=p;//更新待插入节点的指针信息 EI.ER=newp; newp->Parent=InsertElem(EI,p->Parent);//将待插入节点插入到父亲节点中 if(p->Parent==NULL)//顶层分裂,产生了新的树根 { p->Parent=newp->Parent; } else if(p->Parent->Ptr[p->ParentPosition]==NULL)//校正p的ParentPosition信息 { p->Parent=newp->Parent; p->ParentPosition=newp->ParentPosition-1; } return newp;//调用前的新节点的父亲是这里的新节点 } else//待插入的关键字比与存在的两个关键字都要小 { BNode *newp=new BNode; if(p->Ptr[2])//将最大的一个放入新的节点,同时调整其子节点的父亲指针和位置标记 { newp->Ptr[1]=p->Ptr[2]; newp->Ptr[1]->ParentPosition=1; newp->Ptr[1]->Parent=newp; newp->Ptr[0]=p->Ptr[1]; newp->Ptr[0]->ParentPosition=0; newp->Ptr[0]->Parent=newp; } newp->Elem[0]=p->Elem[1]; newp->Ext++; newp->Elem[1]=p->Elem[0];//利用新节点后一个关键字的空间暂存中间的关键字 if(EI.EL) { p->Ptr[0]=EI.EL; p->Ptr[0]->ParentPosition=0; p->Ptr[0]->Parent=p; p->Ptr[1]=EI.ER; p->Ptr[1]->ParentPosition=1; } p->Elem[0]=EI.Elem;//将待插入的节点放入0号位置 p->Ext--; EI.Elem=newp->Elem[1];//将中间节点及其信息封装成新的待插入节点 EI.EL=p; EI.ER=newp; newp->Parent=InsertElem(EI,p->Parent);//将型的待插入节点插入其父亲节点 if(p->Parent==NULL)//顶层分裂,产生了新的树根 { p->Parent=newp->Parent; } else if(p->Parent->Ptr[p->ParentPosition]==NULL)//校正p的ParentPosition信息 { p->Parent=newp->Parent; p->ParentPosition=newp->ParentPosition-1; } return p;//调用前的新节点的父亲是这里的旧节点 } } Status Search(int x,BTree T) //该函数在B-树中查找关键字x,若存在返回TRUE,不存在返回FALSE { if(!T) return FALSE; int i=0; while(i<T->Ext&&T->Elem[i]<x) i++; if(i<T->Ext&&T->Elem[i]==x) return TRUE; if(Search(x,T->Ptr[i])) return TRUE; else return FALSE; } Status Insert(int Elem,BTree &T) //该函数完成将关键字Elem插入到B-树T中 { if(Search(Elem,T)) //若关键字已经存在,则插入失败 { cout<<"该关键字已经存在!插入失败!"<<endl; return ERROR; } ElemInfo temp(Elem); //构造带插入节点结构体 BNode *p=FindPosition(Elem,T); //找到带插入的位置 if(p) InsertElem(temp,p); //若找到,则调用函数插入 else InsertElem(temp,T); //若树为空,插入到根节点 while(T->Parent) T=T->Parent; //重新定位根节点位置 return OK; } BNode *FindDePosition(int x,BTree T)//该函数在B-树中查找关键字x所在的节点,若x不在树中,返回NULL { if(!T) return NULL; int i=0; while(i<T->Ext&&T->Elem[i]<x) i++; if(i<T->Ext&&T->Elem[i]==x) return T; else return FindDePosition(x,T->Ptr[i]); } void DeleteElem(BNode *p,int Elem,BTree &T)//在B-树T中删除p指向的节点中的关键字Elem,通过递归完成对B-树的调整l { if(p->Ext==2)//待删除关键字所在节点中有两个关键字的情况 { if(p->Elem[0]==Elem) { p->Elem[0]=p->Elem[1]; if(p->Ptr[2]!=NULL) { p->Ptr[0]=p->Ptr[1]; p->Ptr[0]->ParentPosition=0; p->Ptr[1]=p->Ptr[2]; p->Ptr[1]->ParentPosition=1; } } p->Ptr[2]=NULL; p->Ext--; return; } else//p->Ext==1 待删除关键字所在节点只有一个关键字的情况 { BNode *pPare=p->Parent; BNode *pLeftInfo=NULL; ElemInfo EI; if((pLeftInfo=p->Ptr[0])!=NULL||(pLeftInfo=p->Ptr[1])!=NULL)//一下七行将p的剩余信息存到pLfetInfo ; if(pLeftInfo==NULL&&pPare==NULL)//删除根节点并且只剩下根节点的情况 { delete p; T=NULL; return ; } if(pPare==NULL)//删除根节点的情况 { delete p; T=pLeftInfo; T->Parent=NULL; T->ParentPosition=-1; return; } if(pPare->Ext==2) { if(p->ParentPosition==0) { if(pPare->Ptr[1]->Ext==1) { if(pPare->Ptr[2]->Ext==1)//case 1 { delete p; EI.EL=pLeftInfo; EI.ER=pPare->Ptr[1]->Ptr[0]; EI.Elem=pPare->Elem[0]; DeleteElem(pPare,pPare->Elem[0],T); InsertElem(EI,pPare->Ptr[0]); return; } else//pPare->Ptr[2]->Ext==2 case 3 { EI.EL=pPare->Ptr[1]->Ptr[1]; EI.Elem=pPare->Elem[1]; EI.ER=pPare->Ptr[2]->Ptr[0]; InsertElem(EI,pPare->Ptr[1]); pPare->Elem[1]=pPare->Ptr[2]->Elem[0]; DeleteElem(pPare->Ptr[2],pPare->Ptr[2]->Elem[0],T); DeleteElem(p,p->Elem[0],T); return; } } else//pPare->Ptr[1]->Ext==2 case 2 { p->Ext--; EI.EL=pLeftInfo; EI.ER=pPare->Ptr[1]->Ptr[0]; EI.Elem=pPare->Elem[0]; InsertElem(EI,p); pPare->Elem[0]=pPare->Ptr[1]->Elem[0]; DeleteElem(pPare->Ptr[1],pPare->Ptr[1]->Elem[0],T); return ; } } else if(p->ParentPosition==1) { if(pPare->Ptr[2]->Ext==1) { if(pPare->Ptr[0]->Ext==1)//case 6 { delete p; EI.EL=pLeftInfo; EI.ER=pPare->Ptr[2]->Ptr[0]; EI.Elem=pPare->Elem[1]; pPare->Ptr[1]=pPare->Ptr[2]; pPare->Ptr[1]->ParentPosition=1; InsertElem(EI,pPare->Ptr[1]); DeleteElem(pPare,pPare->Elem[1],T); return ; } else//pPare->Ptr[0]->Ext==2 case 5 { p->Ext--; EI.EL=pPare->Ptr[0]->Ptr[2]; EI.ER=pLeftInfo; EI.Elem=pPare->Elem[0]; InsertElem(EI,p); pPare->Elem[0]=pPare->Ptr[0]->Elem[1]; DeleteElem(pPare->Ptr[0],pPare->Ptr[0]->Elem[1],T); return ; } } else//pPare->Ptr[2]->Ext==2 case 4 { p->Ext--; EI.EL=pLeftInfo; EI.ER=pPare->Ptr[2]->Ptr[0]; EI.Elem=pPare->Elem[1]; InsertElem(EI,p); pPare->Elem[1]=pPare->Ptr[2]->Elem[0]; DeleteElem(pPare->Ptr[2],pPare->Ptr[2]->Elem[0],T); return ; } } else//p->ParentPosition==2 { if(pPare->Ptr[1]->Ext==2)//case 7 { p->Ext--; EI.EL=pPare->Ptr[1]->Ptr[2]; EI.ER=pLeftInfo; EI.Elem=pPare->Elem[1]; InsertElem(EI,p); pPare->Elem[1]=pPare->Ptr[1]->Elem[1]; DeleteElem(pPare->Ptr[1],pPare->Ptr[1]->Elem[1],T); return ; } else//pPare->Ptr[1]->Ext==1 { if(pPare->Ptr[0]->Ext==1)//case 9 { delete p; EI.EL=pPare->Ptr[1]->Ptr[1]; EI.ER=pLeftInfo; EI.Elem=pPare->Elem[1]; InsertElem(EI,pPare->Ptr[1]); DeleteElem(pPare,pPare->Elem[1],T); return; } else//pPare->Ptr[0]->Ext==2 case 8 { EI.EL=pPare->Ptr[0]->Ptr[2]; EI.Elem=pPare->Elem[0]; EI.ER=pPare->Ptr[1]->Ptr[0]; InsertElem(EI,pPare->Ptr[1]); pPare->Elem[0]=pPare->Ptr[0]->Elem[1]; DeleteElem(pPare->Ptr[0],pPare->Ptr[0]->Elem[1],T); DeleteElem(p,p->Elem[0],T); return; } } } } else//pPare->Ext==1 { if(p->ParentPosition==0) { if(pPare->Ptr[1]->Ext==1)//case 11 { delete p; EI.EL=pLeftInfo; EI.ER=pPare->Ptr[1]->Ptr[0]; EI.Elem=pPare->Elem[0]; InsertElem(EI,pPare->Ptr[1]); pPare->Ptr[0]=NULL; DeleteElem(pPare,pPare->Elem[0],T); return ; } else//pPare->Ptr[1]->Ext==2 case 10 { p->Ext--; EI.EL=pLeftInfo; EI.ER=pPare->Ptr[1]->Ptr[0]; EI.Elem=pPare->Elem[0]; InsertElem(EI,p); pPare->Elem[0]=pPare->Ptr[1]->Elem[0]; DeleteElem(pPare->Ptr[1],pPare->Ptr[1]->Elem[0],T); return ; } } else//p->ParentPosition==1 { if(pPare->Ptr[0]->Ext==1)//case 13 { delete p; EI.EL=pPare->Ptr[0]->Ptr[1]; EI.ER=pLeftInfo; EI.Elem=pPare->Elem[0]; InsertElem(EI,pPare->Ptr[0]); pPare->Ptr[1]=NULL; DeleteElem(pPare,pPare->Elem[0],T); return ; } else//pPare->Ptr[0]==2 case 12 { p->Ext--; EI.EL=pPare->Ptr[0]->Ptr[2]; EI.ER=pLeftInfo; EI.Elem=pPare->Elem[0]; InsertElem(EI,p); pPare->Elem[0]=pPare->Ptr[0]->Elem[1]; DeleteElem(pPare->Ptr[0],pPare->Ptr[0]->Elem[1],T); return ; } } } } } Status Delete(int Elem,BTree &T)//该函数完成在B-树中删除关键字Elem { BNode *p=FindDePosition(Elem,T);//指向待删除的关键字所在节点的指针 if(p==NULL) { cout<<"关键字:"<<Elem<<"不在树中,无法进行删除操作"<<endl; return FALSE; } int ElemPos=(p->Elem[0]==Elem)?0:1;//待删除关键字在其所在节点的位置 if(p->Ptr[0]!=NULL) //若待删除的关键字不在叶子节点中,找到其右边的最左边替换,转换成删除叶子节点 { BNode *q=p->Ptr[ElemPos+1]; while(q->Ptr[0]!=NULL) q=q->Ptr[0]; Elem=p->Elem[ElemPos]=q->Elem[0]; p=q; ElemPos=0; } //至此已经将问题转化成删除值为Elem的关键字,该关键字在p所指向的叶子节点中 DeleteElem(p,Elem,T); return OK; } void Print(BTree T) //以层次遍历输出树 { if(!T) { cout<<"空树!"<<endl; return; } LinkQueue a,b; //用到2个队列以完成分层输出 InitQueue(a); InitQueue(b); BNode *temp; int n; EnQueue(a,T); while(!QueueEmpty(a)||!QueueEmpty(b))//两个队列都为空时,输出结束 { if(!QueueEmpty(a)) { while(!QueueEmpty(a)) { DeQueue(a,temp); for(n=0;n<temp->Ext;n++) { cout<<temp->Elem[n]<<"+"; if(temp->Ptr[n]) EnQueue(b,temp->Ptr[n]); } if(temp->Ptr[n]) EnQueue(b,temp->Ptr[n]); cout<<"\b "; } cout<<endl; } else { while(!QueueEmpty(b)) { DeQueue(b,temp); for(n=0;n<temp->Ext;n++) { cout<<temp->Elem[n]<<"+"; if(temp->Ptr[n]) EnQueue(a,temp->Ptr[n]); } if(temp->Ptr[n]) EnQueue(a,temp->Ptr[n]); cout<<"\b "; } cout<<endl; } } } void PrintDetails(BTree T)//用层次遍历输出每一个节点的详细信息,调试用函数 { if(!T) { cout<<"树为空树!"<<endl; return; } LinkQueue a; //以一个队列层次遍历 InitQueue(a); BNode *temp; int n,m=1; EnQueue(a,T); while(!QueueEmpty(a)) { DeQueue(a,temp); cout<<"节点序号:"<<m<<endl; cout<<"所含关键字个数:"<<temp->Ext<<endl; cout<<"所含关键字为:"; for(n=0;n<temp->Ext;n++) { cout<<temp->Elem[n]<<" "; } cout<<endl; cout<<endl; for(n=0;n<3;n++) { if(temp->Ptr[n]) { EnQueue(a,temp->Ptr[n]); cout<<"孩子"<<n<<"的第一个关键字:"<<temp->Ptr[n]->Elem[0]<<endl; } else { cout<<"孩子"<<n<<"不存在"<<endl; } } cout<<endl; if(temp->Parent) { cout<<"父亲的第一个关键字:"<<temp->Ptr[n]->Elem[0]<<endl; cout<<"该节点在父亲中的位置"<<temp->ParentPosition<<endl; } else { cout<<"父亲不存在"<<endl; } system("pause"); system("cls"); m++; } cout<<"输出结束!"<<endl; system("pause"); } void Destroy(BTree &T)//销毁B-树T,算法思想就是不算的删除根关键字直到树空 { while(T) { Delete(T->Elem[0],T); } } #include "iostream.h" typedef BTree QElemType; typedef struct QNode //队列的节点类型 { QElemType data; struct QNode *next; }QNode,*QueuePtr; typedef struct //队列类型声明 { QueuePtr front; QueuePtr rear; }LinkQueue; Status InitQueue(LinkQueue &Q) //初始化队列,申请专用的对头节点 { Q.front=Q.rear=new QNode; if(!Q.front) return OVERFLOW; Q.front->next=NULL; return OK; } Status ClearQueue(LinkQueue &Q) //清空队列,只剩下专用的头节点 { if(Q.front==Q.rear) return OK; QNode *p=Q.front->next; while(p) { Q.front->next=p->next; delete p; p=Q.front->next; } Q.rear=Q.front; return OK; } Status DestroyQueue(LinkQueue &Q) //销毁队列,在清空的基础上删除专用头结点 { ClearQueue(Q); delete Q.front; Q.front=Q.rear=NULL; return OK; } Status QueueEmpty(LinkQueue Q) //队列判空,如果是空队列返回TRUE,否则返回FALSE { if(Q.rear==Q.front) return TRUE; else return FALSE; } int QueueLength(LinkQueue Q) //求队列长度 { int cout=0; QNode *p=Q.front->next; while(p) { cout++; p=p->next; } return cout; } Status QueueTraverse(LinkQueue &Q) //遍历队列,输出队列中的元素 { if(Q.front==Q.rear) { cout<<"空队"<<endl; return OK; } QNode *p=Q.front->next; while(p) { cout<<p->data<<endl; p=p->next; } return OK; } Status GetHead(LinkQueue Q,QElemType &e) //取头结点,将其数据放到e中 { if(QueueEmpty(Q)) return ERROR; else { e=Q.front->next->data; return OK; } } Status EnQueue(LinkQueue &Q,QElemType &e) //将e入队 { Q.rear->next=new QNode; if(!Q.rear->next) return OVERFLOW; Q.rear=Q.rear->next; Q.rear->data=e; Q.rear->next=NULL; return OK; } Status DeQueue(LinkQueue &Q,QElemType &e) //出队,将出对的元素放入e中 { if(!GetHead(Q,e)) return ERROR; if(Q.rear==Q.front->next) Q.rear=Q.front; QNode *p=Q.front->next; Q.front->next=p->next; delete p; return OK; } #include "Testmode.h" void Frist() //开始界面 { cout <<"************************************************" <<endl; cout <<"课程设计:B-Trees 的实现及分析" <<endl; cout <<"班级:09计算机1班" <<endl; cout <<"学号:0900303128" <<endl; cout <<"姓名:胡远璇" <<endl; cout <<"************************************************" <<endl; cout <<endl; cout <<endl; cout <<"介绍:" <<endl; cout <<endl; cout <<"该程序是M=3的的B-树" <<endl; cout <<endl; cout <<"该程序包含:" <<endl; cout <<"1.实现在B-树上的查找" <<endl; cout <<"2.实现B-树的ADT,包括其上的基本操作:结点的加入和删除" <<endl; cout <<endl; cout <<endl; system("pause"); } void systemmenu() //顶级的系统菜单 { char choose=0; while(1) { system("cls"); cout <<"测试模式选择" <<endl; cout <<"A.指定关键字插入删除测试" <<endl; cout <<"E.退出系统" <<endl; choose=getch(); if(toupper(choose)=='A') { BTree T=NULL; InputIDTest(T); } if(toupper(choose)=='E') break; } } void End() //结束界面 { system("cls"); cout <<"************************************************" <<endl; cout <<"程序结束" <<endl; cout <<"2011-1-15" <<endl; cout <<"************************************************" <<endl; system("pause"); } void main() { Frist(); systemmenu(); End(); } |
|
[建议]关于建立WIN64 板块
那开个LINUX版块吧 |
|
[讨论]这像是机器人说的话么?
这肯定是机器人.不错的机器人. |
|
[分享]无数年轻的菜鸟们在看雪成为老鸟!
03年开始每天起床睡前必须要做的事,打开看雪,点开今日新贴看一看。虽然很少发贴。 |
|
[求助]如何加双层壳以后让正常运行
VMP有注册呀。。用SDK 加VM 再整个自己的算法,然后再加SE 或 TEP。。每种壳的SDK要分开函数调用。然后SE再根据通用方法写个检测 PL。。 |
|
[求助]如何加双层壳以后让正常运行
先VMP 只VM 然后再 WL |
|
[原创]linuxvws服务器0.01版本
韬哥看你贴子还是有技术的呀,怎么可能身无分文。。。 求联系方法。 |
|
应用层反外挂技术实践
#pragma once typedef LONG NTSTATUS; typedef NTSTATUS (WINAPI *NTQUERYINFORMATIONTHREAD)( HANDLE ThreadHandle, ULONG ThreadInformationClass, PVOID ThreadInformation, ULONG ThreadInformationLength, PULONG ReturnLength); typedef enum _THREADINFOCLASS { ThreadBasicInformation, ThreadTimes, ThreadPriority, ThreadBasePriority, ThreadAffinityMask, ThreadImpersonationToken, ThreadDescriptorTableEntry, ThreadEnableAlignmentFaultFixup, ThreadEventPair_Reusable, ThreadQuerySetWin32StartAddress, ThreadZeroTlsCell, ThreadPerformanceCount, ThreadAmILastThread, ThreadIdealProcessor, ThreadPriorityBoost, ThreadSetTlsArrayAddress, // Obsolete ThreadIsIoPending, ThreadHideFromDebugger, ThreadBreakOnTermination, ThreadSwitchLegacyState, ThreadIsTerminated, ThreadLastSystemCall, ThreadIoPriority, ThreadCycleTime, ThreadPagePriority, ThreadActualBasePriority, ThreadTebInformation, ThreadCSwitchMon, // Obsolete ThreadCSwitchPmu, ThreadWow64Context, ThreadGroupInformation, ThreadUmsInformation, // UMS ThreadCounterProfiling, ThreadIdealProcessorEx, MaxThreadInfoClass } THREADINFOCLASS; class FindThreadStaAddr { public: FindThreadStaAddr(void); ~FindThreadStaAddr(void); DWORD GetThreadStartAddr1(DWORD dwThreadId); }; #include "StdAfx.h" #include "FindThreadStaAddr.h" FindThreadStaAddr::FindThreadStaAddr(void) { } FindThreadStaAddr::~FindThreadStaAddr(void) { } DWORD FindThreadStaAddr::GetThreadStartAddr1(DWORD dwThreadId) { HMODULE hNtdll = LoadLibrary(_T("ntdll.dll")); if (!hNtdll) { return 0; } NTQUERYINFORMATIONTHREAD NtQueryInformationThread = NULL; NtQueryInformationThread = (NTQUERYINFORMATIONTHREAD) GetProcAddress(hNtdll, "NtQueryInformationThread"); if (!NtQueryInformationThread) { return 0; } HANDLE ThreadHandle = NULL; ThreadHandle = OpenThread(THREAD_QUERY_INFORMATION, FALSE, dwThreadId); if (!ThreadHandle) { return 0; } DWORD dwStaAddr = NULL; DWORD dwReturnLength = 0; if(NtQueryInformationThreadtion(ThreadHandle, ThreadQuerySetWin32StartAddress, &dwStaAddr, sizeof(dwStaAddr), &dwReturnLength)) { return 0; } return dwStaAddr; } 得到线程入口。 |
|
[求助]求一段delphi思路
使用异步处理。有一现成的单元你可以学习一下。 AniIndicator1.Visible := True; Run(THttpAsyncTaskBitmap.Create('http://www.google.com/images/nav_logo129.png'), // Finish procedure (ATask: IAsyncTask) begin Image1.Bitmap := (ATask as IHttpBitmapResponse).Bitmap; AniIndicator1.Visible := False; end ); 下载地址:https://github.com/dkstar88/AsyncTask |
|
[求助][求助]写了一个很艰难的程序,多线程同步延迟导致线程无法正常退出(delphi 线程错误5)
这里有一文,你看看。 http://andy.jgknet.de/blog/bugfix-units/asynccalls-29-asynchronous-function-calls/ |
|
[求助][求助]写了一个很艰难的程序,多线程同步延迟导致线程无法正常退出(delphi 线程错误5)
线程中不能直接访问VCL |
|
[求助][求助]写了一个很艰难的程序,多线程同步延迟导致线程无法正常退出(delphi 线程错误5)
线程中为什么不用sleep 确用Application.ProcessMessages? |
|
[求助][求助]写了一个很艰难的程序,多线程同步延迟导致线程无法正常退出(delphi 线程错误5)
你这表达的没看懂,码贴上来。 |
|
[原创]整数溢出
你这是memcpy溢出………… |
|
[求助]悲催的delphi xe3 中文变量定义中的一个BUG
是的。我确定只是改了进程名和基址。其它完全没有改的。 并切我的系统是 win7 64位。 32 位VM XP中也正常。 我这是官方直接下载的。 |
操作理由
RANk
{{ user_info.golds == '' ? 0 : user_info.golds }}
雪币
{{ experience }}
课程经验
{{ score }}
学习收益
{{study_duration_fmt}}
学习时长
基本信息
荣誉称号:
{{ honorary_title }}
能力排名:
No.{{ rank_num }}
等 级:
LV{{ rank_lv-100 }}
活跃值:
在线值:
浏览人数:{{ visits }}
最近活跃:{{ last_active_time }}
注册时间:{{ user_info.create_date_jsonfmt }}
勋章
兑换勋章
证书
证书查询 >
能力值