C++ 无法理解为啥这段代码不是线程安全的

Posted

技术标签:

【中文标题】C++ 无法理解为啥这段代码不是线程安全的【英文标题】:C++ cannot understand why this code is not thread safeC++ 无法理解为什么这段代码不是线程安全的 【发布时间】:2015-10-08 09:35:35 【问题描述】:

已经在一些 OpenCV 函数上创建了 C++ 包装器并将其导出到 PInvoke,可以并行调用它。

说实话:

void execute(Document& d) 

            ScriptConfig conf(d);
            Context c(conf);
            OperationManager m;
            while (c.next()) 
                unique_ptr<OperationBase> op = m.create(*c.getCurrentOp()); 
// m.create inside ALWAYS creates unique_ptr<OperationBase>(NEW  ConcreteOperationBase());
//nothing cached
                op->prepare(&c);
                op->execute();  
                op->afterExecute();
            

        

内部操作使用它的上下文并在 OpenCV 中执行一些操作。 Context 保存 Mat 的操作实例。

此代码不是线程安全的。如果我尝试使用几个执行 emmidiatly 调用,它们会以随机方式破坏彼此的工作。看起来操作的输入->输出垫无效。

我在操作中检查了与 opencv 相关的代码是否是线程安全的 - 没关系。

当我通过以下方式修复它时:

mutex _locker;

无效执行(文档& d)

            ScriptConfig conf(d);
            Context c(conf);
            OperationManager m;
            while (c.next()) 
                _locker.lock();
                unique_ptr<OperationBase> op = m.create(*c.getCurrentOp()); 
// m.create inside ALWAYS creates unique_ptr<OperationBase>(NEW  ConcreteOperationBase());
//nothing cached
                op->prepare(&c);
                op->execute();  
                op->afterExecute();
                _locker.unlock();
            

        

不,多线程没有问题。但这不是我想要的——我必须并行调用操作!

【问题讨论】:

你能找出不同的线程是否同时使用相同的输入/输出吗?每个输入/输出使用一个互斥锁或确保线程不共享它们。 【参考方案1】:

您的所有“OperationBase”实例不是都在并行使用相同的“上下文”吗?

【讨论】:

此错误仅在发布 (/MD) 中不会出现在调试配置 (/MDd) 中【参考方案2】:

一些问题是存储在 OperationBase 中并使用 .prepare() 方法设置的 Mat&。我是 C# 人,所以对我来说“参考”是“共享指针”而不是更多。我已经重写了 OperationBase 的所有代码,而不是存储引用或指向存储在 Context 中的 mats 的指针,并且总是在 Operation 的方法中将它们作为 Mat* 获取。这样的组合变成了线程安全的。 )

【讨论】:

以上是关于C++ 无法理解为啥这段代码不是线程安全的的主要内容,如果未能解决你的问题,请参考以下文章

+= 运算符在 Python 中是线程安全的吗?

1.2 线程安全的理解

为啥 Java 的 SimpleDateFormat 不是线程安全的? [复制]

以下 C++ 代码中实现的 DCL(双重检查锁定)是不是是线程安全的?

为啥 C++ STL 不提供一组线程安全的容器? [复制]

为啥 Servlet 不是线程安全的? [复制]