问题描述
#include<stdio.h>//c语言标准输入输出头文件#include<malloc.h>//动态存储分配函数头文件#include<stdlib.h>//标准库头文件(malloc(),rand(),srand()等等)#include<process.h>//包含用于和宏指令的作用声明与螺纹和过程一起使用的C标头文件(线程的创建和终结等等)#include<windows.h>//win32头文件#include<time.h>//日期和时间头文件#definerandom(x)(rand()%x)//产生随机数#definecr1//1标识为插入#definesc0//0标识为删除volatileintreadcount=0;//读者数目constintlsarea=10000;//链表大小随机数constintearea=10000;//元素范围随机数constintsum=100000;//线程运行总次数intth=0;//初始化当前线程总数intth_cz=1;//初始化当前查找线程总数intth_cr=1;//初始化当前插入线程总数intth_sc=1;//初始化当前删除线程总数HANDLEh_Mutex;//控制读者数量readcount的互斥访问量HANDLEmutex;//控制读写互斥,写写互斥的信号量typedefintElemType;//定义ElemType为int类型的别名typedefstructDuLNode*PNode;//结点指针//定义结点结构体typedefstructDuLNode{ElemTypedata;//定义数据域PNodeprior;//定义前驱指针PNodenext;//定义后继指针}DuLNode,*DLN;//定义双向链表结构体typedefstructDuLinkList{DLNhead;//定义头结点intLength;//定义链表长度}DuLinkList,*DLL;//定义读者传参结构体structReadarg{DLLList;//定义链表ElemTypee;//定义查找元素};//定义写者传参结构体structWritearg{DLLList;//定义链表intadd;//定义插入或删除的位置ElemTypee;//定义插入元素intFlag;//定义传入标示符(cr执行插入操作,sc执行删除操作)};//初始化一个空的双向链表并创建链表voidInitList(DLLL){intc,i,e;//定义三个整型变量c,i,eDLNp;//定义结点p//初始化操作L->head=0;//链表头结点置零L->Length=0;//链表长度置零//创建操作printf("双向链表初始化完毕n");srand((int)time(0));//随机数时间种子设置c=random(lsarea);//变量c取范围0~Lsarea内的随机整数if(!c){printf("链表创建失败!n");exit(0);//异常处理,如果用户未输入结点个数则跳出该段代码。}else{p=(DuLNode*)malloc(sizeof(DuLNode));//p动态分配存储空间if(!p){printf("结点p动态分配内存失败!n");exit(0);//异常处理,如果节点p动态分配内存失败则跳出该段代码。}e=random(earea);//变量e取范围0~earea内的随机整数p->data=e;//将变量e的值送入结点p的数据域p->next=p->prior=p;//将结点p的前驱和后继指针指向它自己L->head=p;//将p结点作为链表头结点L->Length++;//链表长度加1//下面循环插入后续结点操作for(i=1;i<c;i++){p=(DuLNode*)malloc(sizeof(DuLNode));//p动态分配存储空间if(!p){printf("结点p动态分配内存失败!n");exit(0);//异常处理,如果用户未输入结点个数则跳出该段代码。}e=random(earea);//变量e取范围0~earea内的随机整数p->data=e;//将变量e的值送入结点p的数据域p->next=L->head;//将结点p的后继指针指向当前链表的头结点p->prior=L->head->prior;//结点p的前驱指针指向当前链表的尾结点L->head->prior->next=p;//将当前链表尾结点的后继指针指向结点pL->head->prior=p;//将当前链表头节点的前驱指针指向结点pL->Length++;//链表长度加1}}}//在链表指定位置插入一个结点voidInsert(DLLL,inti,ElemTypee){DLNp,q;//定义结点p,qintj;//定义整型变量j//下面判断插入位置是否合法if(i<1||i>L->Length+1){printf("对不起,您插入的位置超过了链表范围!nn");}else{printf("恭喜你,插入成功!nn");p=(DuLNode*)malloc(sizeof(DuLNode));//p动态分配存储空间if(!p){printf("结点p动态分配内存失败!n");exit(0);//异常处理,如果用户未输入结点个数则跳出该段代码。}q=L->head;//q指向当前链表头结点p->data=e;//将变量e的值送入结点p的数据域if(!L&&i==1){//判断链表为空并且插入第一个元素的情况p->next=p->prior=p;//将结点p的前驱和后继指针指向它自己L->head=p;//将p结点作为链表头结点L->Length++;//链表长度加1}else{if(i==1||i==(L->Length+1)){//判断链表不为空在当前表头或表尾插入结点q=q->prior;//将q指向当前链表尾结点p->next=q->next;//将p的后继指针指向当前链表头结点p->prior=q;//将p的前驱指针指向当前链表的尾结点q->next->prior=p;//将当前链表头结点的前驱指针指向结点pq->next=p;//将当前链表尾结点的后继指针指向结点pL->Length++;//链表长度加1if(i==1)//判断插入位置是否是头结点L->head=p;//将结点p置为链表头结点}else{for(j=1;j<i;j++){//循环定位插入位置q=q->next;}q->prior->next=p;//将当前链表尾结点的后继指针指向结点pp->prior=q->prior;//将结点p的前驱指针指向当前链表的尾结点q->prior=p;//将当前链表头结点的前驱指针指向结点pp->next=q;//将结点p的后继指针指向当前链表头结点L->Length++;//链表长度加1}}}}//删除指定位置的结点voidErase(DLLL,inti){DLNq;//定义结点qintj;//定义整型变量jq=L->head;//q指向当前链表头结点if(i<1||i>(L->Length)||L->head==NULL){printf("对不起,您删除的位置超过了链表范围或者链表为空!nn");}else{printf("恭喜你,删除成功!nn");for(j=1;j<i;j++){//循环定位删除位置q=q->next;}q->prior->next=q->next;//将结点q前一个结点的后继指针指向q的后一个结点q->next->prior=q->prior;//将结点q后一个结点的前驱指针指向q的前一个结点if(i==1){//判断删除的位置是否是链表头结点L->head=q->next;//将当前链表的头结点指向第二个结点}L->Length--;//链表长度减1if(L->Length==0){//判断当前链表是否为空L->head=NULL;//将当前链表头结点置空}free(q);//释放结点q的物理内存}}//删除链表中所有结点voidClear(DLLL){DLNq,temp;//定义结点q,tempinti,j;//定义整型变量i,ji=L->Length;//将链表长度赋给itemp=q=L->head;//结点q和temp指向当前链表头结点for(j=0;j<i;j++){//循环释放每一个结点q=q->next;free(temp);temp=q;L->Length--;}L->head=NULL;//链表头结点置空printf("链表已清空!");}//查找链表中是否有指定的元素,若有,返回能够访问该结点的指针;若无,返回NULLDLNFind(DLLL,ElemTypee);//打印当前链表中的所有元素voidPrint(DLLL){DLNp;//定义结点pif(L->head==NULL){printf("链表为空!");}else{p=L->head;printf("%d",p->data);p=p->next;//当p重新指到链表头节点的时候跳出循环while(p!=L->head){printf("%4d",p->data);p=p->next;}}printf("n");printf("长度为:%dn",L->Length);printf("打印完毕!nn");//读者线程(查找)unsigned__stdcallReaderThread(void*arg){Readarg*RA;RA=(Readarg*)arg;inte;WaitForSingleObject(h_Mutex,-1);//等待互斥量信号readcount++;if(readcount==1){WaitForSingleObject(mutex,INFINITE);//等待信号量信号}ReleaseMutex(h_Mutex);//释放互斥量信号e=RA->e;printf("查找操作:读者%d开始查找%dn",th_cz,e);Find(RA->List,e);th_cz++;//执行完一遍查找读者数加1WaitForSingleObject(h_Mutex,-1);readcount--;if(readcount==0){ReleaseSemaphore(mutex,1,NULL);//释放信号量信号}ReleaseMutex(h_Mutex);return0;}//写者线程(包括插入和删除)unsigned__stdcallWriterThread(void*arg){Writearg*WA;WA=(Writearg*)arg;intf,add,e;f=WA->Flag;add=WA->add;e=WA->e;if(f){WaitForSingleObject(mutex,INFINITE);printf("插入操作:写者%d开始在第%d位置插入元素%dn",th_cr,add,e);Insert(WA->List,add,e);th_cr++;//执行完一遍插入写者数加1Print(WA->List);ReleaseSemaphore(mutex,1,NULL);}else{WaitForSingleObject(mutex,INFINITE);printf("删除操作:写者%d开始删除第%d个位置n",th_sc,add);Erase(WA->List,add);th_sc++;//执行完一遍删除写者数加1Print(WA->List);ReleaseSemaphore(mutex,1,NULL);}return0;}intmain(){charsr;printf("**************************n");printf("1.读者优先n");printf("2.退出窗口n");printf("**************************n");printf("请输入你的选择(1或者2):");do{sr=(char)getchar();}while(sr!='1'&&sr!='2');//system("cls");if(sr=='2')return0;else{HANDLEhThread[sum];unsignedthreadID[sum];inti,j,k,m;DLLL;L=(DuLinkList*)malloc(sizeof(DuLinkList));InitList(L);Print(L);h_Mutex=CreateMutex(NULL,FALSE,NULL);//创建互斥量h_Mutexmutex=CreateSemaphore(NULL,1,1,NULL);//创建信号量mutexsrand((int)time(0));for(i=0;i<sum;i++){j=random(3);//在0,1,2这三个数内随机取一个值决定该次循环执行哪一个操作(0为查找,1为插入,2为删除)if(j==0){Readarg*RA=newReadarg[1];RA[0].List=L;RA[0].e=random(earea);//创建读者线程hThread[i]=(HANDLE)_beginthreadex(NULL,0,ReaderThread,(void*)&RA[0],0,&threadID[i]);}else{Writearg*WA=newWritearg[2];WA[0].List=L;WA[0].add=random(lsarea);WA[0].e=random(earea);WA[0].Flag=cr;WA[1].List=L;WA[1].add=random(lsarea);WA[1].e=0;WA[1].Flag=sc;//k=i;//m=k%4;if(j==1){//创建写者线程(插入)hThread[i]=(HANDLE)_beginthreadex(NULL,0,WriterThread,(void*)&WA[0],0,&threadID[i]);}else//创建写者线程(删除)hThread[i]=(HANDLE)_beginthreadex(NULL,0,WriterThread,(void*)&WA[1],0,&threadID[i]);}WaitForSingleObject(hThread[i],INFINITE);//循环内wait操作,及时收回线程}for(i=0;i<sum;i++){CloseHandle(hThread[i]);}CloseHandle(h_Mutex);CloseHandle(mutex);th=(th_cz+th_cr+th_sc)-3;//统计总线程数printf("当前查找读者人数为:%d;当前插入写者人数为:%d;当前删除写者人数为:%d;当前总人数为:%dn",th_cz-1,th_cr-1,th_sc-1,th);Clear(L);Print(L);printf("所有线程都执行完毕了。n");}return0;}cuo'qu
解决方案
解决方案二:
错误
解决方案三:
有人吗?求指点!!!