Criticsection 可用于生产吗?

发布于 2024-10-06 05:44:58 字数 353 浏览 1 评论 0原文

我们是 MFC 的几个新手,我们正在构建一个多线程应用程序。我们在 URL 中发现了一篇文章,警告我们不要使用 CCriticalSection,因为它的实现已被破坏。我们有兴趣知道是否有人有使用 CCriticalSection 的经验,您是否遇到过任何问题或错误?如果我们使用 VC++ 2008 构建应用程序,CCriticalSection 是否可用且已准备好投入生产?

http://www.flounder.com/avoid_mfc_syncrhonization.htm

谢谢

We are a couple of newbies in MFC and we are building a multi-threded application. We come across the article in the URL that warns us not to use CCriticalSection since its implementation is broken. We are interested to know if anyone has any experience in using CCriticalSection and do you come across any problems or bugs? Is CCriticalSection usable and production ready if we use VC++ 2008 to build our application?

http://www.flounder.com/avoid_mfc_syncrhonization.htm

thx

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

对不⑦ 2024-10-13 05:44:58

我认为这篇文章是基于对 CSingleLock 的用途以及如何使用它的根本误解。

您不能多次锁定同一个 CSingleLock,但您不应该这样做。 CSingleLock,顾名思义,用于锁定某项内容一次。

每个CSingleLock 仅管理某个其他对象(例如您在构造过程中传递的CCriticalSection)上的一个锁,目的是当CSingleLock 超出范围时自动释放该锁。

如果你想多次锁定底层对象,你可以使用多个 CSingleLock;您不会使用单个 CSingleLock 并尝试多次锁定它。

错误(他的例子):

CCriticalSection crit;
CSingleLock lock(&crit);
lock.Lock();
lock.Lock();
lock.Unlock();
lock.Unlock();

正确:

CCriticalSection crit;
CSingleLock lock1(&crit);
CSingleLock lock2(&crit);
lock1.Lock();
lock2.Lock();
lock2.Unlock();
lock1.Unlock();

甚至更好(这样你就得到了 RAII):(

CCriticalSection crit;
// Scope the objects
{
    CSingleLock lock1(&crit, TRUE); // TRUE means it (tries to) locks immediately.
    // Do stuff which needs the lock (if IsLocked returns success)
    CSingleLock lock2(&crit, TRUE);
    // Do stuff which needs the lock (if IsLocked returns success)
}
// crit is unlocked now.

当然,你永远不会像这样故意在单个块中的同一个底层关键部分上获得两个锁。这通常只会发生在结果中调用在已经有自己的锁的其他东西内部获得锁的函数。)

(此外,您应该检查 CSingleLock.IsLocked 以查看锁定是否成功。为了简洁起见,我将这些检查保留在外面,因为它们是原始示例中省略了。)

如果 CCriticalSection 本身也遇到同样的问题,那么这肯定是一个问题,但他没有提供我可以看到的任何证据。 (也许我错过了一些东西。我也无法在 MFC 安装中找到 CCriticalSection 的源代码来验证这种方式。)

I think that article is based on a fundamental misunderstanding of what CSingleLock is for and how to use it.

You cannot lock the same CSingleLock multiple times, but you are not supposed to. CSingleLock, as its name suggests, is for locking something ONCE.

Each CSingleLock just manages one lock on some other object (e.g. a CCriticalSection which you pass it during construction), with the aim of automatically releasing that lock when the CSingleLock goes out of scope.

If you want to lock the underlying object multiple times you would use multiple CSingleLocks; you would not use a single CSingleLock and try to lock it multiple times.

Wrong (his example):

CCriticalSection crit;
CSingleLock lock(&crit);
lock.Lock();
lock.Lock();
lock.Unlock();
lock.Unlock();

Right:

CCriticalSection crit;
CSingleLock lock1(&crit);
CSingleLock lock2(&crit);
lock1.Lock();
lock2.Lock();
lock2.Unlock();
lock1.Unlock();

Even better (so you get RAII):

CCriticalSection crit;
// Scope the objects
{
    CSingleLock lock1(&crit, TRUE); // TRUE means it (tries to) locks immediately.
    // Do stuff which needs the lock (if IsLocked returns success)
    CSingleLock lock2(&crit, TRUE);
    // Do stuff which needs the lock (if IsLocked returns success)
}
// crit is unlocked now.

(Of course, you would never intentionally get two locks on the same underlying critical section in a single block like that. That'd usually only happen as a result of calling functions which get a lock while inside something else that already has its own lock.)

(Also, you should check CSingleLock.IsLocked to see if the lock was successful. I've left those checks out for brevity, and because they were left out of the original example.)

If CCriticalSection itself suffers from the same problem then that certainly is a problem, but he's presented no evidence of that that I can see. (Maybe I missed something. I can't find the source to CCriticalSection in my MFC install to verify that way, either.)

狠疯拽 2024-10-13 05:44:58

该文章表明,使用这些原语的简单情况是可以的,只是它们的实现违反了它们应有的语义。

基本上,它建议如果您将其用作非递归锁,并且始终确保锁有效(即不被放弃),那么您应该没问题。

然而,这篇文章确实抱怨说这些限制是不可原谅的。

That article suggests that a simple situation of using those primitives are fine, except that the implementation of them violates the semantics that should be expected of them.

basically, it suggests that if you use it as a non-recursive lock, where you take care to always ensure that the lock is valid (ie, not abandoned), then you should be fine.

The article does complain, however, that the limitations are inexcusable.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文