Monitor.Enter和Monitor.Exit的概念问题 [英] Conceptual Problem with Monitor.Enter and Monitor.Exit

查看:148
本文介绍了Monitor.Enter和Monitor.Exit的概念问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

亲爱的会员,

我在Monit.Enter和Monitor.Exit概念中遇到问题。退出

(在我应该说的一切之前我知道如何解决这个问题问题




使用Monitor.Wait,我不需要解决方案。但这个问题

坚持


我的脑袋是一个概念问题)

假设有两个线程T1,T2同时运行:


T1()

{

while(true){

Monit.Enter(MyObjec);

{

....

}

Monitor.Exit(MyObjec);

}

}


T2()

{

虽然(真){

Monit.Enter(MyObjec) );

{

....

}

Monitor.Exit(MyObjec);

}

}

假设T1在T2之前稍早运行。


T1获得锁定后MyObjec,T2进来并试图获得

访问


MyObjec。由于T1称为Monitor.Enter(MyObjec),之前的T2将会被阻止(但正如MSDN所说,它仍然处于准备好的队列中)。<在
之后,T1调用了Monitor.Exit(MyObjec)。所以T2可以获得访问

MyObjec。


但令人惊讶的是它不能。因为T1再次快速获得对MyObjec

的访问权限。


似乎循环周期太快而不能让T2获得锁定

MyObjec。我不知道这是速度问题,但我确信没有

需要


调用Monitor.Pulse(MyObjec)通知T2,因为T2仍在

就绪队列


(和Monitor.Pulse(MyObjec)只影响等待队列)。


有什么问题?这是速度问题吗?我错了吗

监控方法的概念是什么?


提前致谢。

Dear Members,
I have a problem in the concepts of Monit.Enter and Monitor.Exit
(Before everything I should say that I know how to solve this problem
by

using Monitor.Wait and I do not need a solution. But this question
sticks to

my head as a conceptual problem)
Suppose there are two threads T1, T2 running concurrently:

T1()
{
While(true){
Monit.Enter(MyObjec);
{
....
}
Monitor.Exit(MyObjec);
}
}

T2()
{
While(true){
Monit.Enter(MyObjec);
{
....
}
Monitor.Exit(MyObjec);
}
}
Suppose T1 runs before T2 a little sooner.

After T1 gains the lock on MyObjec, T2 comes in and tries to get
access to

MyObjec too. Since T1 called Monitor.Enter(MyObjec) previously T2 will
be

blocked ( but as what MSDN says, it still remains in ready queue).
After a

while, T1 calls Monitor.Exit(MyObjec). So T2 can gain access to
MyObjec.

But surprisingly it cannot. Because T1 rapidly gains access to MyObjec
again.

It seems that while loop cycles too fast to let T2 gain the lock on
MyObjec. I

am not sure this is the matter of speed but I am sure that there is no
need

to call Monitor.Pulse(MyObjec) to notify T2 because T2 is still in
ready queue

(and Monitor.Pulse(MyObjec) just affects waiting queue).

What is the problem? Is this the matter of speed? Am I wrong about
the

concepts of Monitor methods?

Thanks in advance.

推荐答案

你确定你的考试吗?在下面,T2每次都赢(在我的

机器上,至少......)。


注意setupReady用于保证我们的初始状态 - 即

T1获得锁定并释放T2(然后进行短暂睡眠以让T2

赶上),然后尝试输入(块),T1释放锁(退出)

并立即重新获得它(回车)。


Marc


使用System.Threading;

使用System;

使用System.Diagnostics;

静态类程序

{

static void Main()

{

int t1 = 0,t2 = 0;

for (int i = 0; i< 1000; i ++)

{

switch(RunTest())

{

案例1:t1 ++;休息;

案例2:t2 ++;休息;

}

}

Console.WriteLine(" {0} vs {1}",t1,t2);

Console.ReadKey();

}

类WinnerStub

{

public volatile int Winner = 0;

}

static int RunTest()

{

WinnerStub sync = new WinnerStub ();

ManualResetEvent setupReady = new ManualResetEvent(false),

haveAnswer = new ManualResetEvent(false);

ThreadPool.QueueUserWorkItem(delegate

{

Monitor.Enter(同步);

setupReady.Set();

Thread.Sleep(100 );

//掉锁......

Monitor.Exit(同步);

Monitor.Enter(sync);

if(sync.Winner == 0)

{

sync.Winner = 1;

haveAnswer.Set() ;

}

Monitor.Exit(同步);

});

ThreadPool.QueueUserWorkItem(委托

{

setupReady.WaitOne();

Monitor.Enter(sync);

if(syn c.Winner == 0)

{

sync.Winner = 2;

haveAnswer.Set();

}

Monitor.Exit(同步);

});

haveAnswer.WaitOne();

Console.WriteLine(" Winner:{0}",sync.Winner);

返回sync.Winner;

}


}
Are you sure of your test? In the following, T2 wins every time (on my
machine, at least...).

Note that "setupReady" is used to guarantee our initial state - i.e.
T1 gets the lock and releases T2 (then does a short sleep to let T2
catch up), then tries to Enter (blocks), T1 releases the lock (Exit)
and immediately re-obtains it (Enter).

Marc

using System.Threading;
using System;
using System.Diagnostics;
static class Program
{
static void Main()
{
int t1 = 0, t2 = 0;
for (int i = 0; i < 1000; i++)
{
switch (RunTest())
{
case 1: t1++; break;
case 2: t2++; break;
}
}
Console.WriteLine("{0} vs {1}", t1, t2);
Console.ReadKey();
}
class WinnerStub
{
public volatile int Winner = 0;
}
static int RunTest()
{
WinnerStub sync = new WinnerStub();
ManualResetEvent setupReady = new ManualResetEvent(false),
haveAnswer = new ManualResetEvent(false);
ThreadPool.QueueUserWorkItem(delegate
{
Monitor.Enter(sync);
setupReady.Set();
Thread.Sleep(100);
// drop lock...
Monitor.Exit(sync);
Monitor.Enter(sync);
if (sync.Winner == 0)
{
sync.Winner = 1;
haveAnswer.Set();
}
Monitor.Exit(sync);
});
ThreadPool.QueueUserWorkItem(delegate
{
setupReady.WaitOne();
Monitor.Enter(sync);
if (sync.Winner == 0)
{
sync.Winner = 2;
haveAnswer.Set();
}
Monitor.Exit(sync);
});
haveAnswer.WaitOne();
Console.WriteLine("Winner: {0}", sync.Winner);
return sync.Winner;
}

}


(顺便说一句,我也试过了while和像你的设置,但结果是线程之间甚至是
;所以,如果你能发布一个简短而完整的例子来说明这个?)
(btw, I also tried a "while" setup like yours, but the results were
very even between the threads; so if you can post a short and complete
example that illustrates this?)


6月16日,下午1:14,Marc Gravell< ; marc.grav ... @ gmail.comwrote:
On Jun 16, 1:14 pm, Marc Gravell <marc.grav...@gmail.comwrote:

(顺便说一句,我也尝试了像你一样的while设置,但结果是

非常均匀的线程之间;所以如果你可以发布一个简短且完整的

例子来说明这个?)
(btw, I also tried a "while" setup like yours, but the results were
very even between the threads; so if you can post a short and complete
example that illustrates this?)



感谢您的关注。但你重复了我所说的话。我的问题

正是你提到的:T2总是赢。但是当你和我在

中看到我的示例代码(类似地在你的代码中)时,一个线程获得访问权并且

然后释放它。

但是:

为什么第二个线程在第一个

线程发布之后无法获得访问权限?正如我们所知,第二个线程处于就绪队列状态,并且急需等待第一个线程释放!

Thank you for your attention. But you repeated what I told. My problem
is exactly what you mentioned: T2 always wins. But as you and I see in
my sample code (similarly in your code) one thread get the access and
then release it.
BUT:
Why the second thread can not get the access after that the first
thread released? As we know the second thread is on ready queue and
waiting eagerly for thread one to release!


这篇关于Monitor.Enter和Monitor.Exit的概念问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆