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