避免死锁的方法有哪些?

避免死锁的方法有哪些?,第1张

1、避免给一个锁嵌套上锁,在持有一个锁的时候,不要再给这个锁上锁。如果使用多个锁,使用std::lock。

2、在持有锁时,不要调用别人提供的函数,因为你不清楚别人的代码怎么实现的,不知道它是不是在使用锁。

3、给多个锁上锁时,固定顺序。如果在给多个所上锁,并且无法使用std::lock,最好的做法就是在每一个线程中,都按照同样的顺序。

4、分层次来使用锁,把程序分成几个层次。区分每个层次中使用的锁,当一个线程已经持有更低层次的锁时,不允许使用高层次的锁。可以在程序运行时给不同的锁加上层次号,记录每个线程持有的锁。

扩展资料:

解决方法

系统中已经出现死锁后,应该及时检测到死锁的发生,并采取适当的措施来解除死锁。

死锁预防。

这是一种较简单和直观的事先预防的方法。方法是通过设置某些限制条件,去破坏产生死锁的四个必要条件中的一个或者几个,来预防发生死锁。预防死锁是一种较易实现的方法,已被广泛使用。但是由于所施加的限制条件往往太严格,可能会导致系统资源利用率和系统吞吐量降低。

死锁避免。

系统对进程发出的每一个系统能够满足的资源申请进行动态检查,并根据检查结果决定是否分配资源;如果分配后系统可能发生死锁,则不予分配,否则予以分配。这是一种保证系统不进入死锁状态的动态策略。

死锁检测和解除。

先检测:这种方法并不须事先采取任何限制性措施,也不必检查系统是否已经进入不安全区,此方法允许系统在运行过程中发生死锁。但可通过系统所设置的检测机构,及时地检测出死锁的发生,并精确地确定与死锁有关的进程和资源。检测方法包括定时检测、效率低时检测、进程等待时检测等。

然后解除死锁:采取适当措施,从系统中将已发生的死锁清除掉。

这是与检测死锁相配套的一种措施。当检测到系统中已发生死锁时,须将进程从死锁状态中解脱出来。常用的实施方法是撤销或挂起一些进程,以便回收一些资源,再将这些资源分配给已处于阻塞状态的进程,使之转为就绪状态,以继续运行。死锁的检测和解除措施,有可能使系统获得较好的资源利用率和吞吐量,但在实现上难度也最大。

参考资料:死锁百度百科

1、要求每个事务一次就将所有要使用的数据全部加锁,否则不能执行。

2、采用按序加锁法.预先规定一个封锁顺序,所有的事务都必须按这个顺序对数据执行封锁。

3、不采取任何措施来预防死锁的发生,而是周期性地检查系统中是否有死锁.如果发现死锁就设法解除。

锁的问题(锁等待、死锁)大部分由于没有正确理解锁的管理、使用方式导致。要解决锁的问题,我们可以从如下几个方面进行尝试。

1.数据库锁资源的设置

ONCONFIG 参数 LOCKS 设置即为数据库配置数量合适的锁。通过搜索 online 日志是否有动态增加锁的情况:grep 'dynamically allocated' online.log为表设置合理的锁模式、行级锁或者页级锁。

2.应用程序锁使用模式设置

通过 onstat -g sql 查看 SESSION 使用的锁等待模式和隔离级别,要为不同的应用设置合理的隔离级别和锁等待模式。如在应用程序加入如下语句:

set isolation to dirty read

set lock mode to wait 5

3.应用程序避免使用不必要的锁

许多应用程序的 SQL 语句由于没有正确地使用索引 INDEX,导致对整个表进行了锁定,导致并发遇到锁的问题。需要通过 SQL 优化和创建合理的索引,避免顺序扫描带来的锁冲突问题。

由于顺序扫描导致的锁等待问题:创建表 test_lock,采用行级锁,并在 c1 字段上创建索引,插入 3 行测试数据。

create table test_lock (c1 int,c2 int,c3 char(10)) lock mode row

create index idx_test_lock on test_lock(c1)

insert into test_lock values(1,1,'abc')

insert into test_lock values(2,2,'abc')

insert into test_lock values(3,3,'abc')

Session 1 通过索引扫描来修改第 2 行记录:

Begin work

update test_lock set c3='new' where c1=2

此时,Session 1 将在第二行记录上加 X 锁。

Session 2 通过 c2 字段以顺序扫描的方式来修改第 3 行记录。

Begin work

update test_lock set c3='new' where c2=3

由于 Session 2 采用顺序扫描方式,在扫描过程中发现第 2 行记录加上了 X 锁,故提示锁冲突错误:

244: Could not do a physical-order read to fetch next row.

107: ISAM error: record is locked.

如果在 c2 字段上加上索引,或者通过 c1=3 修改第三行记录,那么就不会出现锁的问题。

4.应用程序优化避免过长占用锁

锁是一个公共资源,需要尽快释放锁资源,减少等待,如果每个事务都可以在微秒级别完成,那么锁就不会是我们关注的问题,减少锁占用的时间也是解决锁问题的关键。我们可以通过避免大事务,把大事务拆分多次提交,这样锁就能尽快释放。另外,优化应用的处理性能,如合理使用索引等,都可以加快事务的处理速度,可无形中解决锁冲突的可能性。

5.设置合理的隔离级别

不同的隔离级别对锁的使用不一样,设置合理的隔离级别,可以提高应用程序的并发性,提高系统的处理能力,减少锁的冲突情况,避免读 *** 作带来的锁问题。


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

原文地址: http://outofmemory.cn/sjk/9649091.html

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

发表评论

登录后才能评论

评论列表(0条)

保存