如何避免死锁?

时间:2009-06-29 07:52:18

标签: multithreading language-agnostic concurrency

使用多个线程时,共享内存需要被关键部分锁定。但是,使用关键部分会导致潜在的死锁。如何避免它们?

8 个答案:

答案 0 :(得分:10)

一种方法是使用关键部分的层次结构。如果您确保永远不会在其中一个子项中输入父关键部分,则不会发生死锁。困难在于强制执行此层次结构。

答案 1 :(得分:5)

此页面右侧的相关列表包含一些链接,提供有关该主题的有趣信息。

除了该列表之外,还有许多讨论该主题的其他SO问题,例如

... and many more

答案 2 :(得分:2)

当我使用C ++时,以下内容适用于我:

  1. 线程安全类锁的所有公共方法(不包括ctor和dtor)

  2. 私有方法无法调用公共方法

  3. 这不是一般的死锁避免方法。

答案 3 :(得分:1)

您必须非常仔细地编写多线程程序。没有捷径,你必须了解你的程序流程,否则你将注定失败。

答案 4 :(得分:1)

您可以通过消息传递(同步和异步调用)来避免关键部分。当使用同步调用时,您仍然必须确保不进行循环调用,其中线程A向线程B询问问题,并且B需要问A问题是否能够响应。 / p>

另一个选择是改为异步调用。但是,获取返回值更加困难。

注意:实际上,消息传递系统是使用锁定调用队列的关键部分实现的,但它被抽象出来。

答案 5 :(得分:1)

在进入关键部分的各种方法中 - 信号量和互斥量是最受欢迎的。

  • 信号量是一种等待机制,而互斥锁是一种锁定机制,这个概念最让人困惑,但简而言之,激活互斥锁的线程只能停用它。考虑到这一点......

  • 如果进程需要5个资源,请不要让任何进程锁定部分资源,等待所有资源都可用。

  • 如果你在这里使用信号量,你可以解锁/取消等待其他线程占用的资源。我的意思是先发制人是另一个原因。

这两个根据我的基本条件,其余2个共同的4个注意事项可以与这些相关。

如果你不同意ps添加评论。我已经迟到了,我稍后会添加一个更清晰,更清晰的解释。

答案 6 :(得分:0)

使用以下算法来避免死锁:

银行家的算法

- 为了获得更好的资源利用率,在防止死锁方面实施不那么严格的条件

- 安全状态

•操作系统可以保证所有当前流程都能在有限的时间内完成工作

- 不安全状态

•并不意味着系统已陷入僵局,但操作系统无法保证所有当前流程都能在有限的时间内完成工作

- 仅在分配导致安全状态时才要求将资源分配给进程。 - 它有许多弱点(例如需要固定数量的进程和资源)阻止它在实际系统中实现

答案 7 :(得分:0)

一种方法是使用非阻塞锁定功能。例如,在锈病中,您可以使用public static AuthenticationBuilder AddAzureAD( this AuthenticationBuilder builder, string scheme, string openIdConnectScheme, string cookieScheme, string displayName, Action<AzureADOptions> configureOptions) { AddAdditionalMvcApplicationParts(builder.Services); builder.AddPolicyScheme(scheme, displayName, o => { o.ForwardDefault = cookieScheme; o.ForwardChallenge = openIdConnectScheme; }); builder.Services.Configure( TryAddOpenIDCookieSchemeMappings(scheme, openIdConnectScheme, cookieScheme)); builder.Services.TryAddSingleton<IConfigureOptions<AzureADOptions>, AzureADOptionsConfiguration>(); // They put in their custom OpenIdConnect configuration, but I can't see how to get at the events. builder.Services.TryAddSingleton<IConfigureOptions<OpenIdConnectOptions>, OpenIdConnectOptionsConfiguration>(); builder.Services.TryAddSingleton<IConfigureOptions<CookieAuthenticationOptions>, CookieOptionsConfiguration>(); builder.Services.Configure(scheme, configureOptions); builder.AddOpenIdConnect(openIdConnectScheme, null, o => { }); builder.AddCookie(cookieScheme, null, o => { }); return builder; } 代替std::sync::Mutex::try_lock

因此,如果您有以下示例代码:

std::sync::Mutex::lock

您可以改成这样:

fn transfer(tx: &Mutex<i32>, rx: &Mutex<i32>, amount: i32) -> () {
    let mut tx = tx.lock().unwrap();
    let mut rx = rx.lock().unwrap();

    *tx -= amount;
    *rx += amount;
}