死锁解决C语言程序

死锁解决C语言程序,第1张

#include <windows.h>

#include <iostream>

#include<time.h>

const unsigned short SIZE_OF_BUFFER = 1//缓冲区长度

int g_buffer[SIZE_OF_BUFFER]

bool g_continue = true//控制程序结束

HANDLE g_hMutex//用于线程间的互斥

DWORD WINAPI FatherProc(LPVOID)//父进程线程

DWORD WINAPI SonProc(LPVOID)//使用打印机的线程

int main()

{

//创建各个互斥信号

g_hMutex = CreateMutex(NULL,FALSE,NULL)

const unsigned short FATHERS_COUNTS = 1//父进程线程的个数

const unsigned short SONS_COUNT = 2//使用打印机的线程的个数

//总的线程数

const unsigned short THREADS_COUNT = FATHERS_COUNTS+SONS_COUNT

HANDLE hThreads[THREADS_COUNT]//各线程的handle

DWORD fatherID[FATHERS_COUNTS]//父进程线程的标识符

DWORD sonID[SONS_COUNT]//使用打印机的线程的标识符

//父进程线程

for (int i=0i<FATHERS_COUNTS++i){

hThreads[i]=CreateThread(NULL,0,FatherProc,NULL,0,&fatherID[i])

if (hThreads[i]==NULL) return -1

}

//使用打印机的线程

for (i=0i<SONS_COUNT++i){

hThreads[SONS_COUNT+i]=CreateThread(NULL,0,SonProc,NULL,0,&sonID[i])

if (hThreads[i]==NULL) return -1

}

while(g_continue){

if(getchar())

{ //按回车后终止程序运行

g_continue = false

}

}

return 0

}

//分配打印机

void Append()

{

srand((unsigned)time(0))

std::cerr <<"打印机空闲 ...\n"

if(rand()%2)

{

g_buffer[0]=1//给PA

}

else

{

g_buffer[0]=0//给PB

}

}

//son使用打印机

void Take()

{

if(g_buffer[0]==1)

{

std::cerr <<"PA使用打印机 ... "

std::cerr <<"成功" <<std::endl<<std::endl

}

if(g_buffer[0]==0)

{

std::cerr <<"PB使用打印机 ... "

std::cerr <<"成功" <<std::endl<<std::endl

}

g_buffer[0]=-1

}

//父进程

DWORD WINAPI FatherProc(LPVOID lpPara)

{

while(g_continue){

WaitForSingleObject(g_hMutex,INFINITE)

Append()

Sleep(1500)

ReleaseMutex(g_hMutex)

}

return 0

}

//子进程

DWORD WINAPI SonProc(LPVOID lpPara)

{

while(g_continue){

WaitForSingleObject(g_hMutex,INFINITE)

Take()

Sleep(1500)

ReleaseMutex(g_hMutex)

}

return 0

} 最后的要求自己添加

如果你将mutex_c换成mutex_p,则不会死锁,因为,你第一个线程锁上后,切换到第二个线程,因为mutex_p未释放,第二个线程无法获取mutex_p,进入等待状态,此时OS将再次调度第一个线程,直到第一个线程释放mutex_p之后,第二个线程才会被激活,然后调试第二线程,获取mutex_p.

使用OS提供的互斥量来保护公共资源还是比较安全的,但如果用二值信号量的话,就可能会有优先级反转的情况.

利用银行家算法避免死锁 . 银行家算法 设Requesti是进程Pi的请求向量,如果Requesti〔j〕=K,表示进程Pi需要K个Rj类型的资源。当Pi发出资源请求后,系统按下述步骤进行检查:� (1) 如果Requesti〔j〕≤Need〔i,j〕,便转向步骤2;否则认为出错,因为它所需要的资源数已超过它所宣布的最大值。 (2) 如果Requesti〔j〕≤Available〔j〕,便转向步骤(3);否则, 表示尚无足够资源,Pi须等待。 (3) 系统试探着把资源分配给进程Pi,并修改下面数据结构中的数值:� Available〔j〕∶=Available〔j〕-Requesti〔j〕� Allocation〔i,j〕∶=Allocation〔i,j〕+Requesti〔j〕� Need〔i,j〕∶=Need〔i,j〕-Requesti〔j〕� (4) 系统执行安全性算法,检查此次资源分配后,系统是否处于安全状态。若安全,才正式将资源分配给进程Pi,以完成本次分配;否则, 将本次的试探分配作废,恢复原来的资源分配状态,让进程Pi等待。 (3) 系统试探着把资源分配给进程Pi,并修改下面数据结构中的数值:� Available〔j〕∶=Available〔j〕-Requesti〔j〕� Allocation〔i,j〕∶=Allocation〔i,j〕+Requesti〔j〕� Need〔i,j〕∶=Need〔i,j〕-Requesti〔j〕� (4) 系统执行安全性算法,检查此次资源分配后,系统是否处于安全状态。若安全,才正式将资源分配给进程Pi,以完成本次分配;否则, 将本次的试探分配作废,恢复原来的资源分配状态,让进程Pi等待。 (3) 系统试探着把资源分配给进程Pi,并修改下面数据结构中的数值:� Available〔j〕∶=Available〔j〕-Requesti〔j〕� Allocation〔i,j〕∶=Allocation〔i,j〕+Requesti〔j〕� Need〔i,j〕∶=Need〔i,j〕-Requesti〔j〕� (4) 系统执行安全性算法,检查此次资源分配后,系统是否处于安全状态。若安全,才正式将资源分配给进程Pi,以完成本次分配;否则, 将本次的试探分配作废,恢复原来的资源分配状态,让进程Pi等待。


欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/yw/12164429.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-05-21
下一篇2023-05-21

发表评论

登录后才能评论

评论列表(0条)

    保存