- 线程锁:当多个线程几乎同时修改一个共享数据的时候,需要进行同步控制,线程同步能够保证多个线程安全的访问竞争资源(全局内容),最简单的同步机制就是使用互斥锁。
某个线程要更改共享数据时,先将其锁定,此时资源的状态为锁定状态,其他线程就能更改,直到该线程将资源状态改为非锁定状态,也就是释放资源,其他的线程才能再次锁定资源。互斥锁保证了每一次只有一个线程进入写入操作。从而保证了多线程下数据的安全性。
- 进程锁:也是为了控制同一操作系统中多个进程访问一个共享资源,只是因为程序的独立性,各个进程是无法控制其他进程对资源的访问的,但是可以使用本地系统的信号量控制。
- 死锁:在一组进程中的各个进程均占有不会释放的资源,但因互相申请被其他进程所站用不会释放的资源而处于的一种永久等待状态。 当线程进入对象的synchronized代码块时,便占有了资源,直到它退出该代码块或者调用wait方法,才释放资源,在此期间,其他线程将不能进入该代码块。当线程互相持有对方所需要的资源时,会互相等待对方释放资源,如果线程都不主动释放所占有的资源,将产生死锁。
产生死锁的四个必要条件
(1) 互斥条件:一个资源每次只能被一个进程使用。
(2) 请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。
(3) 不剥夺条件:进程已获得的资源,在末使用完之前,不能强行剥夺。
(4) 循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。
解决死锁的方法
-
按同一顺序访问对象。(注:避免出现循环)
-
避免事务中的用户交互。(注:减少持有资源的时间,较少锁竞争)
-
保持事务简短并处于一个批处理中。(减少持有资源的时间)
-
使用较低的隔离级别。(注:使用较低的隔离级别(例如已提交读)比使用较高的隔离级别(例如可序列化)持有共享锁的时间更短,减少锁竞争)
-
尽量减少资源占用的时间,可以降低死锁的发生的概率
-
银行家算法。银行家算法----安全序列
Available = [] #各可用资源数目 Used ={} #某进程目前占有各资源数 Need = {} #某进程目前需求资源数 zhan = [] #临时存储列表 order = [] #进程安全顺序列表 pandaun = [] def compare(a = [],b = []): for x in range(0,item): #进行列表对应元素的比较 if (int(a[x]) < int(b[x])): #一旦出现供不应求的情况即返回False return False break #且跳出循环 return True #如果符合条件即返回True def AddUsed(a = [],b = []): #可用资源某进程当前占用资源对应位置相加 for x in range(0,item): a[x] = int(a[x]) + int(b[x]) item = int(input("请输入资源种类数: ")) SP = int(input("请输入进程数: ")) jinchengshu = SP #设置临时变量表示进程数量,在后面的判断中用 #输入各类资源的可用数目并存储到列表Available中 for x in range(1,item+1): Available.append(input("请输入第"+str(x)+"种资源的可用数目: ")) #输入各进程名称,占有资源数及所需,键值对存储 for x in range(1,SP+1): name = input("请输入第"+str(x)+"个进程名称: ") print("该进程占有的"+str(item)+"类资源数为:") for y in range(1,item+1): zhan.append(int(input())) Used[name] = zhan zhan = [] #清空临时列表 print("该进程需要的"+str(item)+"类资源数为:") for z in range(1,item+1): zhan.append(int(input())) Need[name] = zhan zhan = [] #清空临时列表 #安全性算法开始 while Need: #如果进程表Need不为空 for key in Need: #获取Need中的key zhan = Need[key] #将对应的value赋值给临时列表zhan if compare(Available,zhan):#调用比较函数比较列表中个元素与Avilable中个元素的大小并返回真值 AddUsed(Available,Used[key]) #如果返回True则调用相加函数 order.append(key) #将key值放入order列表中以便显示 a = key #设置a令它等于key,删除字典元素时使用 break if compare(Available,zhan): #如果符合大小条件就删除对应的键值对 del Need[a] jinchengshu -= 1 if SP == jinchengshu: print("不存在安全序列!h!!") break if jinchengshu == 0: for x in range(0,len(order)): print(order[x]+'-->',end='') print("END!")