有人可以解释一下(代码)的例子,死锁和活锁之间的区别是什么?
我有一个innoDB表记录在线用户.它会在用户每次刷新页面时更新,以跟踪他们所在的页面以及他们上次访问网站的日期.然后,我有一个每15分钟运行一次以删除旧记录的cron.
我得到了一个'试图锁定时发现的死锁; 尝试重新启动事务'昨晚约5分钟,似乎是在运行INSERT到此表时.有人可以建议如何避免这个错误?
===编辑===
以下是正在运行的查询:
首次访问网站:
INSERT INTO onlineusers SET
ip = 123.456.789.123,
datetime = now(),
userid = 321,
page = '/thispage',
area = 'thisarea',
type = 3
Run Code Online (Sandbox Code Playgroud)
在每个页面刷新:
UPDATE onlineusers SET
ips = 123.456.789.123,
datetime = now(),
userid = 321,
page = '/thispage',
area = 'thisarea',
type = 3
WHERE id = 888
Run Code Online (Sandbox Code Playgroud)
Cron每15分钟一次:
DELETE FROM onlineusers WHERE datetime <= now() - INTERVAL 900 SECOND
Run Code Online (Sandbox Code Playgroud)
然后它会记录一些统计数据(即:在线成员,在线访客).
POSIX允许互斥锁递归.这意味着同一个线程可以锁定相同的互斥锁两次并且不会死锁.当然它还需要解锁两次,否则没有其他线程可以获得互斥锁.并非所有支持pthread的系统都支持递归互斥锁,但如果它们想要符合POSIX,则必须使用.
其他API(更高级别的API)通常也提供互斥锁,通常称为锁定.一些系统/语言(例如Cocoa Objective-C)提供递归和非递归互斥体.有些语言也只提供一种或另一种语言.例如,在Java中,互斥锁总是递归的(同一个线程可能在同一个对象上"同步"两次).根据它们提供的其他线程功能,没有递归互斥体可能没有问题,因为它们可以很容易地自己编写(我已经在更简单的互斥/条件操作的基础上自己实现了递归互斥锁).
我真的不明白:什么是非递归互斥量有用?如果它锁定相同的互斥锁两次,为什么我想要一个线程死锁?即使是可以避免这种情况的高级语言(例如测试它是否会死锁并抛出异常)通常也不会这样做.他们会让线程陷入僵局.
这只适用于我意外锁定它两次并且只解锁一次的情况,并且在递归互斥锁的情况下,它会更难找到问题,所以相反我立即死锁以查看错误锁定出现在哪里?但是我不能在解锁时返回一个锁定计数器并且在某种情况下,我确定我释放了最后一个锁并且计数器不为零,我可以抛出异常或记录问题吗?或者是否有其他更有用的非递归互斥体用例我看不到?或者它可能只是性能,因为非递归互斥体可能比递归互斥体略快?但是,我对此进行了测试,差异确实不大.
我不太明白之间的差别Task.Wait和await.
我在ASP.NET WebAPI服务中有类似于以下函数:
public class TestController : ApiController
{
public static async Task<string> Foo()
{
await Task.Delay(1).ConfigureAwait(false);
return "";
}
public async static Task<string> Bar()
{
return await Foo();
}
public async static Task<string> Ros()
{
return await Bar();
}
// GET api/test
public IEnumerable<string> Get()
{
Task.WaitAll(Enumerable.Range(0, 10).Select(x => Ros()).ToArray());
return new string[] { "value1", "value2" }; // This will never execute
}
}
Run Code Online (Sandbox Code Playgroud)
哪里Get会僵局.
什么可能导致这个?当我使用阻塞等待而不是await Task.Delay?时,为什么这不会导致问题?
编写多线程应用程序时,遇到的最常见问题之一是死锁.
我对社区的问题是:
什么是僵局?
你怎么发现它们?
你处理它们吗?
最后,你如何防止它们发生?
我有以下四个测试,当我运行它时,最后一个测试挂起,我的问题是为什么会发生这种情况:
[Test]
public void CheckOnceResultTest()
{
Assert.IsTrue(CheckStatus().Result);
}
[Test]
public async void CheckOnceAwaitTest()
{
Assert.IsTrue(await CheckStatus());
}
[Test]
public async void CheckStatusTwiceAwaitTest()
{
Assert.IsTrue(await CheckStatus());
Assert.IsTrue(await CheckStatus());
}
[Test]
public async void CheckStatusTwiceResultTest()
{
Assert.IsTrue(CheckStatus().Result); // This hangs
Assert.IsTrue(await CheckStatus());
}
private async Task<bool> CheckStatus()
{
var restClient = new RestClient(@"https://api.test.nordnet.se/next/1");
Task<IRestResponse<DummyServiceStatus>> restResponse = restClient.ExecuteTaskAsync<DummyServiceStatus>(new RestRequest(Method.GET));
IRestResponse<DummyServiceStatus> response = await restResponse;
return response.Data.SystemRunning;
}
Run Code Online (Sandbox Code Playgroud)
我将此扩展方法用于restsharp RestClient:
public static class RestClientExt
{
public static Task<IRestResponse<T>> ExecuteTaskAsync<T>(this RestClient client, IRestRequest …Run Code Online (Sandbox Code Playgroud) 以下代码是否会在.NET上使用C#导致死锁?
class MyClass
{
private object lockObj = new object();
public void Foo()
{
lock(lockObj)
{
Bar();
}
}
public void Bar()
{
lock(lockObj)
{
// Do something
}
}
}
Run Code Online (Sandbox Code Playgroud) 我有一个选择的过程需要很长时间才能完成,大约需要5到10分钟.
我目前没有使用NOLOCK作为MS SQL数据库引擎的提示.
与此同时,我们有另一个进程在进行更新并插入到同一个数据库和相同的表中.
第一个过程已经开始,最近过早地结束了一条消息
SQLEXCEPTION:事务在锁资源上与另一个进程死锁,并被选为死锁牺牲品.
第一个进程在相同条件但在数据库较小的其他站点上运行,因此所讨论的select语句需要更短的时间(大约30秒左右).在这些其他站点中,我没有在这些其他站点中获得死锁消息.我也没有在最初遇到问题的网站上收到此消息,但是,我认为,随着数据库的增长,我相信我必须超过一些门槛.这是我的问题:
我想向新手解释线程死锁.我见过许多死锁的例子,有些使用代码,有些使用插图(比如着名的4辆汽车).还有像The Dining Philosophers这样经典的容易陷入僵局的问题,但这些问题可能过于复杂,无法让真正的新手完全掌握.
我正在寻找最简单的代码示例来说明死锁是什么.这个例子应该:
您有什么推荐的吗?
从.NET 3.5/C#应用程序,我想抓住,SqlException但只有它是由 SQL Server 2008实例上的死锁引起的.
典型的错误消息是 Transaction (Process ID 58) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction.
但是,对于此异常,它似乎不是一个记录错误代码.
针对其消息中存在死锁关键字而过滤异常似乎是实现此行为的一种非常难看的方式.有人知道这样做的正确方法吗?
deadlock ×10
c# ×3
locking ×3
.net ×2
async-await ×2
concurrency ×1
livelock ×1
mutex ×1
mysql ×1
nunit ×1
pthreads ×1
sql-server ×1
sqlexception ×1
task ×1
try-catch ×1