首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > VC/MFC >

Windows中互斥信号量有关问题出错

2012-03-15 
Windows中互斥信号量问题出错#includewindows.h#includecstdlib#includeiostream#includecstdio#d

Windows中互斥信号量问题出错
#include<windows.h>
#include<cstdlib>
#include<iostream>
#include<cstdio>
#define THREAD_NUMBER 10
#define RESOURCE_NUMBER 3

typedef struct{
  int ID;
  int Request[RESOURCE_NUMBER+1]; 
}INFOTABLE,*LPINFOTABLE;

int Judge[THREAD_NUMBER+1],visit[THREAD_NUMBER+1];
int TNumber,RNumber,n,s;
int Max[THREAD_NUMBER+1][RESOURCE_NUMBER+1];
int Need[THREAD_NUMBER+1][RESOURCE_NUMBER+1];
int Allocation[THREAD_NUMBER+1][RESOURCE_NUMBER+1];
int x[THREAD_NUMBER+1],Finish[THREAD_NUMBER+1];
int Available[RESOURCE_NUMBER+1],Work[RESOURCE_NUMBER+1];
HANDLE hMutex;
HANDLE hThread[THREAD_NUMBER];
INFOTABLE ITable[THREAD_NUMBER+1];

void Show();
void InfoLoad(); 
bool Test(LPINFOTABLE lpITable);
bool Compare(LPINFOTABLE lpITable);
void TryAlloc(LPINFOTABLE lpITable);
void RollBack(LPINFOTABLE lpITable);
bool SecurityCheck();
void WorkAdd(LPINFOTABLE lpITable);
void InfoPrint();
DWORD WINAPI ThreadProc(LPVOID lpParam); //线程函数 

int main(){
  Show(); //显示界面 
  InfoLoad(); //信息加载 
  for(int i=0;i<TNumber;i++){
  ITable[i+1].ID=i+1;
  hThread[i]=CreateThread(NULL, //默认安全属性 
  0, //线程堆栈大小 
  ThreadProc, //线程函数 
  (LPVOID)(&ITable[i+1]), //参数 
  0, //创建标志 
  NULL); //线程ID
  if(hThread[i]==NULL){
  printf("Create Thread error: %d\n",GetLastError());
  ExitProcess(1);
  } 
  }
  hMutex=CreateMutex(NULL, //默认安全属性 
  FALSE, //是否为创建线程所拥有 
  NULL); //互斥对象名
  if(hMutex==NULL){
  printf("CreateMutex error: %d\n",GetLastError());
  return 1;
  }
  DWORD dwResult=WaitForMultipleObjects(TNumber, //等待对象的数量 
  hThread, //等待对象的句柄 
  TRUE, //是否等待对象全部才返回 
  INFINITE); //无限等待
  if(dwResult!=WAIT_OBJECT_0){
  printf("Wait error2: %d\n",GetLastError());
  return 1;
  }
  system("PAUSE");
  return 0;
}

DWORD WINAPI ThreadProc(LPVOID lpParam){
  int i=0;
  bool flag;
  DWORD dwResult;
  LPINFOTABLE lpITable=(LPINFOTABLE)lpParam;
  dwResult=WaitForSingleObject(hMutex, //等待对象的句柄 
  INFINITE); //无限等待
  if(dwResult!=WAIT_OBJECT_0){
  printf("Thread= %d Wait error1: %d\n",lpITable->ID,GetLastError());
  //return 1; 
  }
  if(Compare(lpITable)){
  TryAlloc(lpITable); //试分配
  memset(Finish,0,sizeof(Finish));
  flag=SecurityCheck(); //安全检查
  if(!flag){
  printf("线程 %d 申请的资源大于系统现在可利用的资源!\n",lpITable->ID);
  RollBack(lpITable); //回滚操作 
  }else{
  Judge[lpITable->ID]=1;
  printf("*****进程ID= %d\n",lpITable->ID);
  printf("系统是安全的,安全序列为:P%d",x[1]);
  for(int j=2;j<=TNumber;j++)
  printf("->P%d",x[j]);


  printf("\n");
  InfoPrint();
  }
  }
  if(!ReleaseMutex(hMutex)){ //释放互斥对象 
  printf("ReleaseMutex error: %d\n",GetLastError());
  return 1;
  }
  return 1;
}

bool Compare(LPINFOTABLE lpITable){
  int i,id=lpITable->ID;
  for(i=1;i<=RNumber;i++)
  if(!(lpITable->Request[i]<=Need[id][i]))
  return false;
  for(i=1;i<=RNumber;i++)
  if(!(lpITable->Request[i]<=Available[i]))
  return false;
  return true;
}

void TryAlloc(LPINFOTABLE lpITable){
  int i,id=lpITable->ID;
  for(i=1;i<=RESOURCE_NUMBER;i++){
  Allocation[id][i]+=lpITable->Request[i];
  Need[id][i]-=lpITable->Request[i];
  Available[i]-=lpITable->Request[i];
  Work[i]=Available[i];
  }
}

bool SecurityCheck(){
  int i,k=0;
  bool boo=true;
  while(boo){
  boo=false;
  for(i=1;i<=TNumber;i++)
  if(!Finish[i]&&Test(&ITable[i])){
  WorkAdd(&ITable[i]);
  x[++k]=i;
  boo=true;
  Finish[i]=1;
  }
  }
  if(k==TNumber)return true;
  else return false;
}

bool Test(LPINFOTABLE lpITable){
  int i,id=lpITable->ID;
  for(i=1;i<=RNumber;i++)
  if(Need[id][i]>Work[i])return false;
  return true;
}

void WorkAdd(LPINFOTABLE lpITable){
  int i,id=lpITable->ID;
  for(i=1;i<=RNumber;i++)
  Work[i]+=Allocation[id][i];
}

void RollBack(LPINFOTABLE lpITable){
  int i,id=lpITable->ID;
  for(i=1;i<=RNumber;i++){
  Allocation[id][i]-=lpITable->Request[i];
  Need[id][i]+=lpITable->Request[i];
  Available[i]+=lpITable->Request[i];
  }
}

void InfoPrint(){
  int i,j;
  printf("**********************此时刻资源分配情况**********************\n");
  printf("Process Allocation Need Available\n");
  for(i=1;i<=TNumber;i++){
  printf(" P%d ",i);
  for(j=1;j<=RNumber;j++)
  printf("%d ",Allocation[i][j]);
  printf(" ");
  for(j=1;j<=RNumber;j++)
  printf("%d ",Need[i][j]);
  if(i==1){
  printf(" ");
  for(j=1;j<=RNumber;j++)
  printf("%d ",Available[j]);
  printf("\n");
  }else printf("\n");
  }  
}

void Show(){
  printf("\n");
  printf("\n");
  printf("\n");
  printf("\n");
  printf("\n");
  printf(" ┏━━━━━━━━━━━━━━━━━━━━━━━━━━┓\n");
  printf(" ┃ ☆★银行家算法模拟★☆ ┃\n");
  printf(" ┗━━━━━━━━━━━━━━━━━━━━━━━━━━┛\n");
  printf(" ┃ 1. ┃ ┃\n");
  printf(" ┃ 2. ┃ ┃\n");


  printf(" ┃ 3. ┃ ┃\n");
  printf(" ┃ 4. ┃ ┃\n");
  printf(" ┗━━━━━━━━━━━━━━━━━━━━━━━━━━┛\n");
  printf(" 请按对应的数字键进行选择:");
  scanf("%d",&s);
  system("CLS");
}

void InfoLoad(){
  int i,j;
  printf("请输入【线程的数量(1~10)】与【资源种类(1~3)】: ");
  scanf("%d %d",&TNumber,&RNumber);
  n=TNumber;
  printf("请输入每类可利用资源的数量:");
  for(i=1;i<=RNumber;i++)
  scanf("%d",&Available[i]); 
  memset(Allocation,0,sizeof(Allocation));
  for(i=1;i<=TNumber;i++){
  printf("进程 P%d 对 ",i);
  for(j=1;j<=RNumber;j++)
  printf(" R%d ",j);
  printf("类资源的最大需求为:");
  for(j=1;j<=RNumber;j++)
  scanf("%d",&Max[i][j]);
  }
  for(i=1;i<=TNumber;i++){
  printf("进程 P%d 的 ",i);
  for(j=1;j<=RNumber;j++)
  printf(" R%d ",j);
  printf("类资源的已分配数量:");
  for(j=1;j<=RNumber;j++){
  scanf("%d",&Allocation[i][j]);
  Need[i][j]=Max[i][j]-Allocation[i][j];
  }
  }
  for(i=1;i<=TNumber;i++){
  printf("进程 P%d 对 ",i);
  for(j=1;j<=RNumber;j++)
  printf(" R%d ",j);
  printf("类资源的请求为:");
  for(j=1;j<=RNumber;j++)
  scanf("%d",&ITable[i].Request[j]);
  }
}

在这个程序中,每次在线程函数中,互斥信号量WaitForSingleObject操作总会出现错误,为什么啊?

[解决办法]
代码太多,没时间看
12、互斥对象内核对象:象能够确保线程拥有对单个资源的互斥访问权。互斥对象包含一个使用数量,一个线程ID和一个递归计数器。互斥对象的行为特性与关键代码段相同,但是互斥对象属于内核对象,而关键代码段则属于用户方式对象,这意味着互斥对象的运行速度比关键代码段要慢,也意味着不同进程中的多个线程能够访问单个互斥对象,并且这意味着线程在等待访问资源时可以设定一个超时值。
13、互斥对象的使用规则如下:如果线程ID是0(这是个无效ID),互斥对象不被任何线程所拥有,并且发出该互斥对象的通知信号;如果ID是个非0数字,那么一个线程就拥有互斥对象,并且不发出该互斥对象的通知信号;与所有其他内核对象不同,互斥对象在操作系统中拥有特殊的代码,允许它们违反正常的规则。CreateMutex创建互斥对象,OpenMutex打开已有互斥对象,ReleaseMutex是否互斥对象。同一个线程可以多次等待互斥对象,只是循环计数增多,在ReleaseMutex时循环计数减1,直到计数为0,其他等待互斥对象的线程才能成为可调度的,因此等待多少次,必须释放多少次。
14、互斥对象释放问题:等待和释放时也会比较线程ID,如果线程在释放前终止运行,则互斥对象被放弃,系统自动将互斥对象的线程ID和计数置为0,其他等待线程将获得WAIT_ABANDONED返回值,该返回值只在互斥对象中使用。互斥对象与关键代码段的比较:前者运行速度慢,能跨进程和任意等待,后者运行速度快不能跨进程,不能任意等待。
[解决办法]
把CreateMutex函数的调用放到CreateThread创建线程的前面去。

[解决办法]
你的创建线程的时候,线程就以每小时180迈的速度运行,当运行到WaitForSingleObject时,互斥量还没有创建,所有总是错误
[解决办法]
或者将创建的对象线Suspend,等互斥量创建后再Resume

热点排行