热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

由“Qt程序运行一段时间后崩溃”引发的“opancv库中Mat::clone()函数”在多线程下的注意事项

问题描述过程1:从相机中获取图像数据,然后存放到一个cv::Mat对象中(该对象是全局变量,用来交换数据)。由相机的回调函数自动调用。过程2:将上述的全局变量拷贝并转换qimg,放
  • 问题描述
    • 过程1:从相机中获取图像数据,然后存放到一个cv::Mat对象中(该对象是全局变量,用来交换数据)。由相机的回调函数自动调用。
    • 过程2:将上述的全局变量拷贝并转换qimg,放到Qt界面上显示。该过程由定时器调用。
    • 然后程序会在运行一段时间后,出现“程序异常结束。The process was ended forcefully.”。运行的时间长短不一。

技术图片

  • 问题解决与分析
    • 由于QtCreator的编译器选的是MSVC,而调试器选只有GDB(查了下好像需要CDB)。所以无法debug,只能一点点排查。
    • 测试定时器时间越短,出现问题越快。猜测是多线程下访问冲突。
      • 输出线程id查看,使用std::this_thread::get_id()获取当前线程的ID,发现相机写入Mat对象的过程的线程号 和 定时器调用的读取Mat对象的线程号不一样。这说明相机的SDK在获取图像数据的部分是创建了新的线程进行的。
      • 可是读写应该不冲突,所以看看opencv的Mat::clone()方法。
      inline
      Mat Mat::clone() const
      {
        Mat m;
        copyTo(m);
        return m;
      }
      // 噢 原来是调用的cv::copyTo方法,等等,上面有个const,这下明白了,在拷贝的时候是不允许修改值的,如果正在拷贝,此时相机写入线程正好获取了相机数据,准备写入,这时就发生了冲突。总之读写不能同时进行。
      //那么就是用互斥量将两者互斥,
      #include 
      std::mutex mtx;
      //在读(Mat::clone()) / 写  之前使用mtx.lock();,之后使用mtx.unlock(); 问题解决啦。
  • 最后测试是否真的是这个原因。声明一个槽函数,连接上某按钮的click动作。调用.clone()并且没有加锁。
void QtGuiApplication1::on_btnThread_clicked()
{
 auto myThread = [] {
  while (1) {
   if (!temp_forSave.empty()) {
    Mat lalala = temp_forSave.clone();
    std::cout <<"在创建线程中复制\n";
   }
   std::cout <<"创建线程" <
  • 正常运行时,点击按钮程序立即崩溃(毕竟该线程时while(1)地拷贝)。验证成功。

由“Qt程序运行一段时间后崩溃”引发的“opancv库中Mat::clone()函数”在多线程下的注意事项


推荐阅读
  • 本文深入探讨了Java多线程环境下的同步机制及其应用,重点介绍了`synchronized`关键字的使用方法和原理。`synchronized`关键字主要用于确保多个线程在访问共享资源时的互斥性和原子性。通过具体示例,如在一个类中使用`synchronized`修饰方法,展示了如何实现线程安全的代码块。此外,文章还讨论了`ReentrantLock`等其他同步工具的优缺点,并提供了实际应用场景中的最佳实践。 ... [详细]
  • 解决Bootstrap DataTable Ajax请求重复问题
    在最近的一个项目中,我们使用了JQuery DataTable进行数据展示,虽然使用起来非常方便,但在测试过程中发现了一个问题:当查询条件改变时,有时查询结果的数据不正确。通过FireBug调试发现,点击搜索按钮时,会发送两次Ajax请求,一次是原条件的请求,一次是新条件的请求。 ... [详细]
  • 在 Linux 环境下,多线程编程是实现高效并发处理的重要技术。本文通过具体的实战案例,详细分析了多线程编程的关键技术和常见问题。文章首先介绍了多线程的基本概念和创建方法,然后通过实例代码展示了如何使用 pthreads 库进行线程同步和通信。此外,还探讨了多线程程序中的性能优化技巧和调试方法,为开发者提供了宝贵的实践经验。 ... [详细]
  • 本文详细介绍了 PHP 中对象的生命周期、内存管理和魔术方法的使用,包括对象的自动销毁、析构函数的作用以及各种魔术方法的具体应用场景。 ... [详细]
  • 第二十五天接口、多态
    1.java是面向对象的语言。设计模式:接口接口类是从java里衍生出来的,不是python原生支持的主要用于继承里多继承抽象类是python原生支持的主要用于继承里的单继承但是接 ... [详细]
  • 深入解析:Synchronized 关键字在 Java 中对 int 和 Integer 对象的作用与影响
    深入探讨了 `Synchronized` 关键字在 Java 中对 `int` 和 `Integer` 对象的影响。尽管初看此题似乎简单,但其实质在于理解对象的概念。根据《Java编程思想》第二章的观点,一切皆为对象。本文详细分析了 `Synchronized` 关键字在不同数据类型上的作用机制,特别是对基本数据类型 `int` 和包装类 `Integer` 的区别处理,帮助读者深入理解 Java 中的同步机制及其在多线程环境中的应用。 ... [详细]
  • Android 构建基础流程详解
    Android 构建基础流程详解 ... [详细]
  • PHP预处理常量详解:如何定义与使用常量 ... [详细]
  • Python 数据可视化实战指南
    本文详细介绍如何使用 Python 进行数据可视化,涵盖从环境搭建到具体实例的全过程。 ... [详细]
  • 微软推出Windows Terminal Preview v0.10
    微软近期发布了Windows Terminal Preview v0.10,用户可以在微软商店或GitHub上获取这一更新。该版本在2月份发布的v0.9基础上,新增了鼠标输入和复制Pane等功能。 ... [详细]
  • 本文介绍了如何使用 CMD 批处理脚本进行文件操作,包括将指定目录下的 PHP 文件重命名为 HTML 文件,并将这些文件复制到另一个目录。 ... [详细]
  • Spark中使用map或flatMap将DataSet[A]转换为DataSet[B]时Schema变为Binary的问题及解决方案
    本文探讨了在使用Spark的map或flatMap算子将一个数据集转换为另一个数据集时,遇到的Schema变为Binary的问题,并提供了详细的解决方案。 ... [详细]
  • 深入剖析Java中SimpleDateFormat在多线程环境下的潜在风险与解决方案
    深入剖析Java中SimpleDateFormat在多线程环境下的潜在风险与解决方案 ... [详细]
  • 本文介绍了如何利用 Delphi 中的 IdTCPServer 和 IdTCPClient 控件实现高效的文件传输。这些控件在默认情况下采用阻塞模式,并且服务器端已经集成了多线程处理,能够支持任意大小的文件传输,无需担心数据包大小的限制。与传统的 ClientSocket 相比,Indy 控件提供了更为简洁和可靠的解决方案,特别适用于开发高性能的网络文件传输应用程序。 ... [详细]
  • 如何利用Java 5 Executor框架高效构建和管理线程池
    Java 5 引入了 Executor 框架,为开发人员提供了一种高效管理和构建线程池的方法。该框架通过将任务提交与任务执行分离,简化了多线程编程的复杂性。利用 Executor 框架,开发人员可以更灵活地控制线程的创建、分配和管理,从而提高服务器端应用的性能和响应能力。此外,该框架还提供了多种线程池实现,如固定线程池、缓存线程池和单线程池,以适应不同的应用场景和需求。 ... [详细]
author-avatar
uw65ayk
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有