我试图通过使用Monitor同步将数据写入类中的文本文件的线程,但是在我的代码中似乎从不评估else语句,这是否正确使用了监视器进行线程同步?
EventHubSender
}
答案 0 :(得分:0)
您正在将对象传递给Monitor::TryEnter
,该对象特定于其执行的线程(即Thread^ current = Thread::CurrentThread;
)。没有其他线程使用相同的对象(他们使用自己的线程)。所以永远不会发生碰撞或锁定冲突。
尝试创建一些在线程之间共享的通用对象,这些对象位于Bank
类的更高层。然后将其用于TryEnter
来电。
答案 1 :(得分:0)
您对Monitor
的使用部分正确无误。您用于锁定的对象不正确。
Monitor
Monitor::Pulse
。只需Exit
监视器,下一个线程就可以获取锁定。
Monitor::Wait
在这里不正确:当线程的对象已经锁定时,应该使用Wait
。在这里,您还没有锁定对象。
通常,Pulse
和Wait
很少使用。要锁定对共享资源的独占访问权限,您只需Enter
,TryEnter
和Exit
。
以下是您应该如何使用Monitor
:
Object^ lockObj = ...;
bool done = false;
while(!done)
{
if(Monitor::TryEnter(lockObj, 500)) // wait 500 millis for the lock.
{
try
{
// do work
done = true;
}
finally
{
Monitor::Exit(lockObj);
}
}
else
{
// Check some other exit condition?
}
}
或如果else
为空,您可以将其简化为:
Object^ lockObj = ...;
Monitor::Enter(lockObj); // Wait forever for the lock.
try
{
// do work
}
finally
{
Monitor::Exit(lockObj);
}
Microsoft提供了一个类,使这一切变得更加容易:msclr::lock
。这个类在没有^
的情况下使用,使用析构函数来释放锁,而不使用try-finally块。
#include <msclr\lock.h>
bool done = false;
while(!done)
{
msclr::lock lock(lockObj, lock_later);
if (lock.try_acquire(500)) // wait 500 millis for the lock to be available.
{
// Do work
done = true;
}
} // <-- Monitor::Exit is called by lock class when it goes out of scope.
{
msclr::lock lock(lockObj); // wait forever for the lock to be available.
// Do work
} // <-- Monitor::Exit is called by lock class when it goes out of scope.
Thread::CurrentThread
将在每个线程上返回一个不同的对象。因此,每个线程都会尝试锁定不同的对象,这就是为什么所有这些都成功的原因。相反,在生成线程之前创建一个用于锁定的对象。
此外,而不是打开&amp;关闭每个线程上的文件,在生成线程之前打开它一次会更有效,然后只使用每个线程中的那个StreamWriter
。这也为您提供了一个明显的锁定对象:您可以将StreamWriter
本身传递给Monitor::Enter
或msclr::lock
。