c++ - 从多个线程同步对共享对象的方法调用

标签 c++ multithreading winapi

我正在考虑如何实现一个包含私有(private)数据的类,这些私有(private)数据最终会被多个线程通过方法调用修改。对于同步(使用 Windows API),我计划使用 CRITICAL_SECTION 对象,因为所有线程都将从同一进程产生。

鉴于以下设计,我有几个问题。

template <typename T> class Shareable
{
private:
    const LPCRITICAL_SECTION sync; //Can be read and used by multiple threads
    T *data;
public:
    Shareable(LPCRITICAL_SECTION cs, unsigned elems) : sync{cs}, data{new T[elems]} { }
    ~Shareable() { delete[] data; }
    void sharedModify(unsigned index, T &datum) //<-- Can this be validly called
    //by multiple threads with synchronization being implicit?
    {
        EnterCriticalSection(sync);
        /*
            The critical section of code involving reads & writes to 'data'
        */
        LeaveCriticalSection(sync);
    }
};

// Somewhere else ...

DWORD WINAPI ThreadProc(LPVOID lpParameter)
{
    Shareable<ActualType> *ptr = static_cast<Shareable<ActualType>*>(lpParameter);
    T copyable = /* initialization */;
    ptr->sharedModify(validIndex, copyable); //<-- OK, synchronized?
    return 0;
}

在我看来,API 调用将在当前线程的上下文中进行。也就是说,我假设这与我从指针获取临界区对象并从 ThreadProc() 中调用 API 是一样的。但是,我担心如果创建对象并将其放置在主/初始线程中,API 调用会有些奇怪。

  1. sharedModify() 在同一对象上 同时被调用时, 来自多个线程,同步是否是隐式的,在 我上面描述的方式?
  2. 我应该得到一个指向 关键部分对象并改用它?
  3. 还有其他的吗 哪种同步机制更适合这种场景?

最佳答案

When sharedModify() is called on the same object concurrently, from multiple threads, will the synchronization be implicit, in the way I described it above?

这不是隐式的,而是显式的。只有 CRITICAL_SECTION,并且一次只能有一个线程持有它。

Should I instead get a pointer to the critical section object and use that instead?

没有。没有理由在这里使用指针。

Is there some other synchronization mechanism that is better suited to this scenario?

没有看到更多代码就很难说,但这绝对是“默认”解决方案。它就像一个单向链表——您先学习它,它总是有效,但它并不总是最佳选择。

关于c++ - 从多个线程同步对共享对象的方法调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40876856/

相关文章:

c++ - 在 OpenMP C++ 中使用并行 block 时没有看到任何显着改进

c++ - std::async 是如何实现的?

winapi - 如何弹出USB可移动磁盘/卷,类似于Windows资源管理器中的 "Eject"功能?

android - 在 Android NDK C++ 代码中捕获异常

c++ - 使用 boost::asio 时是否需要实现阻塞?

c++ - 不使用宏来减少函数定义的原因

java - 调用 notifyAll() 后线程未唤醒

c# - .Net 4 中的多线程 C# 队列

windows - 不同DPI、高度计算的CComboBoxEx问题

c - 为什么 ShellExecuteEx 不设置 SHELLEXECUTEINFO.hProcess 的值?