- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
请告诉我,如果我觉得还好。
不同的线程不能进入相同的临界区使用同样的锁只是因为第一个线程调用了Monitor.Wait
,对吧? Wait
方法只允许不同的线程获取相同的监视器,即相同的同步锁,但仅用于不同的关键部分,而不是相同的关键部分节。
我的理解正确吗?
因为如果 Wait
方法意味着任何人现在都可以输入 this相同的关键部分使用相同的锁,那么这将失败同步的全部目的,对吗?
所以,在下面的代码中(用记事本写的,所以请原谅任何错别字),ThreadProc2
只能使用syncLock
进入代码ThreadProc2
而不是 ThreadProc1
而前一个线程持有并随后放弃锁的人正在执行ThreadProc1
,对吧?
两个或多个线程可以使用同一个同步锁来运行同时处理不同的代码,对吗?同样的问题以上,基本上,但只是为了对称而确认下面第 3 点。
两个或多个线程可以使用不同的同步锁来运行同一段代码,即进入同一临界区。
用于更正格式的样板文本。
class Foo
{
private static object syncLock = new object();
public void ThreadProc1()
{
try
{
Monitor.Enter(syncLock);
Monitor.Wait(syncLock);
Thread.Sleep(1000);
}
finally
{
if (Monitor.IsLocked(syncLock))
{
Monitor.Exit(syncLock);
}
}
}
public void ThreadProc2()
{
bool acquired = false;
try
{
// Calling TryEnter instead of
// Enter just for the sake of variety
Monitor.TryEnter(syncLock, ref acquired);
if (acquired)
{
Thread.Sleep(200);
Monitor.Pulse(syncLock);
}
}
finally
{
if (acquired)
{
Monitor.Exit(syncLock);
}
}
}
}
更新
下图证实了#3 是正确的,尽管我认为这不是一件好事。
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace DifferentSyncLockSameCriticalSection
{
class Program
{
static void Main(string[] args)
{
var sathyaish = new Person { Name = "Sathyaish Chakravarthy" };
var superman = new Person { Name = "Superman" };
var tasks = new List<Task>();
// Must not lock on string so I am using
// an object of the Person class as a lock
tasks.Add(Task.Run( () => { Proc1(sathyaish); } ));
tasks.Add(Task.Run(() => { Proc1(superman); }));
Task.WhenAll(tasks);
Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
static void Proc1(object state)
{
// Although this would be a very bad practice
lock(state)
{
try
{
Console.WriteLine((state.ToString()).Length);
}
catch(Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
}
class Person
{
public string Name { get; set; }
public override string ToString()
{
return Name;
}
}
}
最佳答案
当线程调用 Monitor.Wait
时,它会被挂起并释放锁。这将允许另一个线程获取锁、更新一些状态,然后调用 Monitor.Pulse
以便与其他线程通信发生了某些事情。您必须获得锁才能调用 Pulse
。在 Monitor.Wait
返回之前,框架将重新获取调用 Wait
的线程的锁。
为了让两个线程相互通信,它们需要使用相同的同步原语。在您的示例中,您使用了监视器,但您通常需要将其与 Wait
响应 Pulse
返回的某种测试相结合。这是因为即使未调用 Pulse
,技术上也可以Wait
返回(尽管这在实践中不会发生)。
还值得记住的是,对 Pulse
的调用不是“粘性”的,因此如果没有人在等待监视器,则 Pulse
什么都不做,随后调用Wait
将错过 Pulse
被调用的事实。这是您倾向于在调用 Pulse
之前记录已完成某事的另一个原因(请参见下面的示例)。
两个不同的线程使用同一个锁来运行不同的代码位是完全有效的——事实上这是典型的用例。例如,一个线程获取锁以写入一些数据,而另一个线程获取锁以读取数据。但是,重要的是要认识到它们不会同时运行。获取锁的行为会阻止另一个线程获取相同的锁,因此任何试图在它已经被锁定时获取锁的线程都将阻塞,直到另一个线程释放锁。
在第 3 点你问:
Two or more threads can use a different synchronization lock to run the same piece of code, i.e. to enter the same critical section.
但是,如果两个线程使用不同的锁,则它们不会进入同一临界区。关键部分由保护它的锁表示——如果它们是不同的锁,那么它们是不同的部分,只是碰巧访问该部分中的一些公共(public)数据。您应该避免这样做,因为它会导致一些难以调试的数据竞争条件。
您的代码对于您要实现的目标来说有点过于复杂。例如,假设我们有 2 个线程,当有数据可供另一个线程处理时,一个会发出信号:
class Foo
{
private readonly object syncLock = new object();
private bool dataAvailable = false;
public void ThreadProc1()
{
lock(syncLock)
{
while(!dataAvailable)
{
// Release the lock and suspend
Monitor.Wait(syncLock);
}
// Now process the data
}
}
public void ThreadProc2()
{
LoadData();
lock(syncLock)
{
dataAvailable = true;
Monitor.Pulse(syncLock);
}
}
private void LoadData()
{
// Gets some data
}
}
}
关于c# - 第二个线程是否可以仅仅因为第一个线程使用相同的同步锁调用 Monitor.Wait 而进入相同的临界区?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37394688/
如果我 mov, eax 12345 和之后的 mov var, eax (假设 var 是一个 32 位的 int 等..等等)并输出 var 稍后它会正确输出。 与 ax 相同。 mov ax,
我有这个代码: for($nrt=0; $nrt"; if($sidesIndexes[$nrt]==$nrt) { echo "am I in??? ".$sidesInde
我正在阅读The Go Programming Language的8.5章,并陷入一些代码。下面的代码列表。 func main() { naturals := make(chan int)
我写了一个 MySQL 查询用于将数据导出到文本文件。 查询运行成功,但结果与我的预期不符。 我想在列之间没有间距的结果。 select sample_export_record1_2013.
在普通的 Excel 窗口中,我可以打开 VBE 并通过触摸键序列插入一个新模块:ALT+F11、ALTim 全部不使用鼠标。有没有办法打开 VBE 并导航到 本工作手册 不使用鼠标的代码区域? 最佳
我正在使用 axios 发出 http 请求。在 .then() 内部,我正在使用另一个 axios 调用。最后,我有第三个 then(),它应该在第二个 then 之后运行,但实际上并没有这样做。
我需要在 cocos2d 项目中播放视频..我的问题是:如何将 MPMoviePlayerController 放入我的 View 中,如下所示:? UIView *theView = [[CCDir
我正在学习 Angular。以下代码有效: .controller('abc', function ($scope, $http) { $http.get("/Handlers/Authenticat
目前我正在使用 WPF 学习 C#。我的主要方法是尽我所能使用 MVVM 模式,但现在我有点困惑。 在我所有 View 的应用程序中,我有一个 View 模型: private DruckviewVi
关于将 G 邮件提取到 Google 电子表格,我该如何添加 IF 以按主题驳回特定电子邮件?例如:电子邮件回复(主题中带有“RE:”)。我不希望这些电子邮件出现在我的电子表格中。 我尝试过使用 LO
我正在尝试使用 Spotify API 并进入数组。 const App = () => { const [isLoading, setIsLoading] = useState(true);
我有一个 html 模板,并且有一个条件为 --> 的代码 --> window.jQuery || document.write(""+"");
我正在开发一个 Android 应用程序,该应用程序会暴力破解从 int 创建的 MD5 和。 暴力破解部分工作正常。 (我可以sysout最终值并且它是正确的。) 我在将输出值发送到警报对话框时遇到
我正在创建一个界面,用户可以通过该界面生成多系列折线图,并控制绘制哪些数据集。 要绘制哪些数据集由复选框控制。页面加载时,默认数据集以图表形式呈现,并且 $('input:checkbox.data-
我尝试将有向无环图绘制为力布局。 但是我注意到,尽管为每个组元素灌输了进入/退出条件,弹出的节点/链接并没有从 DOM 中删除它们自己。 相反,弹出的节点/链接在力布局中卡住;这意味着没有调用进入/退
这里是新手。我不知道它是怎么发生的,但我正在处理一个程序,当我去调试并进入时,黄色箭头走到了我代码的最后并跳过了整个 block 。有快速解决方法吗? 最佳答案 按 F11,或单击工具栏上的“Step
我的 Action 栏 sherlock 中有一个列表。我想在用户点击该列表时得到。我不想知道用户何时点击某个项目,我已经知道 (onNavigationItemSelected)。 在我的 onCr
** 你好 **我如何从 ci 中的 mysql 日期获取 eurodate 来工作......无法弄清楚 - 请帮忙 想要获取日期 YY-mm- dd -> dd-mm-yy提前致谢 最佳答案 $t
我有以下脚本: #!/bin/bash ls -1 | while read d do [[ -f "$d" ]] && continue echo $d cd $d done
TL;DR - 跳转到最后一段 背景 我正在执行一些数据驱动测试,并将日志文件用作测试输出之一。它的工作原理是这样的- 读取文件夹中的第一个文件 处理第一行并转换为测试 运行测试 执行验证 1 ...
我是一名优秀的程序员,十分优秀!