确保仅从对象的创建线程中调用方法

时间:2018-12-06 10:16:52

标签: c++ multithreading c++14

问题:如何确保代码中没有从创建对象的线程之外的任何其他线程调用类的方法?

一个过于简单的例子:

class A {
public:
    void execute() {
        // gets executed from the main loop
        ++i;
    }

    void increment() {
        // gets executed as a callback
        // how to ensure this is called only from main/creation thread?
        ++i;
    }
private:
    int i = 0;
};

一个想法是让一个类似chreationThreadID的成员在构造函数中设置为std::this_thread::get_id(),并在执行该方法时断言get_id()与在存储过程中存储的那个相同。施工。

还有更优雅的方式吗?

故事的背景:class A提供了对class B的回调。 class A在主线程循环中执行,并且主执行路径和回调都访问公共数据。 class B当前在同一线程中执行(并且希望保持这种状态)。但是class B在外部库中,该库经常更改,因此当回调的处理移到另一个线程时,如何避免令人讨厌的意外?

2 个答案:

答案 0 :(得分:0)

并没有真正回答问题,但这部分是由于问题的最初明确性。当我们优化问题上下文时,请暂时留在这里。

也许通过在“共享”和“主线程”方法中声明不同的接口,并使该“主线程”接口仅可从原始构造对象中请求,便可以在编译时获得所需的保护?其他线程仅被赋予指向共享接口的指针,而主线程则知道整个对象或附加接口。

当然,您仍然要确保其他线程不被授予对主线程接口的访问权限,并且可以使用dynamic_cast来访问其他线程,但这始终应表明您在错误使用它

答案 1 :(得分:0)

更优雅的方式是:

  1. 不要混用编程模型-闭包(回调,处理程序等)和线程不能很好地融合在一起。之所以可以创建摩擦,是因为各种回调可能是响应于特定于线程的同步原语(例如互斥体?muti?),如果您尝试将其从与获取它们不同的线程中释放出来,则可能会变得有些麻烦。 p>

  2. 如果必须混合使用;分层混合-任何y线程操作都完全发生在回调中,或者任何y回调操作都发生在封闭的同步集中(即A.lock(); B.callback(); A.unlock();)< / p>

您可以使用线程ID对其进行破解,您可能会保留自己的工作,或者可能被迫保留自己的工作...无论哪种方式,没人会感谢您。