C ++ / Cli同步线程写入文件

时间:2016-04-25 16:35:10

标签: multithreading c++-cli

我试图通过使用Monitor同步将数据写入类中的文本文件的线程,但是在我的代码中似乎从不评估else语句,这是否正确使用了监视器进行线程同步?

EventHubSender

}

2 个答案:

答案 0 :(得分:0)

您正在将对象传递给Monitor::TryEnter,该对象特定于其执行的线程(即Thread^ current = Thread::CurrentThread;)。没有其他线程使用相同的对象(他们使用自己的线程)。所以永远不会发生碰撞或锁定冲突。

尝试创建一些在线程之间共享的通用对象,这些对象位于Bank类的更高层。然后将其用于TryEnter来电。

答案 1 :(得分:0)

您对Monitor的使用部分正确无误。您用于锁定的对象不正确。

Monitor

这里不需要

Monitor::Pulse。只需Exit监视器,下一个线程就可以获取锁定。

Monitor::Wait在这里不正确:当线程的对象已经锁定时,应该使用Wait。在这里,您还没有锁定对象。

通常,PulseWait很少使用。要锁定对共享资源的独占访问权限,您只需EnterTryEnterExit

以下是您应该如何使用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::Entermsclr::lock