"Qt는 프로그램이 충돌하는 몇 시간 동안 실행"에서 멀티 스레드에서 "opancv 라이브러리 매트 : 클론 () 함수"노트를 트리거

  • 문제 설명
    • 공정 1 : 카메라로부터 영상 데이터를 획득 한 후, CV : 매트 오브젝트 (오브젝트 데이터를 교환하기 위해, 글로벌 변수 임)에 저장된다. 카메라가 자동으로 콜백 함수에 의해 호출됩니다.
    • 공정 2 : 전술 전역 변수 사본 및 qimg 변환은 Qt는 디스플레이 화면에 배치. 이 과정은 타이머에 의해 호출됩니다.
    • 그런 프로그램이 몇 시간 동안 실행하는 "프로그램이 비정상적으로 국지적 인 프로세스가 강제로 종료되었습니다 종료됩니다.". 시간 변화의 실행됩니다.

  • 문제 해결 및 분석
    • QtCreator 컴파일러 옵션은 MSVC하지만, 선택된 디버거 GDB가 있기 때문에 (체크 다음은 CDB를 요구하는 것 같다). 그것은 디버그, 조사의 조금에 불가능하다.
    • 테스트 타이머 짧은 시간, 빠른 문제. 액세스 위반 추측은 멀티 스레드입니다.
      • 스레드 ID가 볼 수있는 출력, 사용 표준 : this_thread :: get_id () 현재 스레드의 ID를 가져옵니다, 객체 매트 매트 스레드 번호 작성 절차 객체 카메라 스레드 번호를 읽고 타이머가 동일하지 않습니다 전화를 발견했다. 이 화상 데이터에 대한 SDK 부에 카메라가 새로운 쓰레드를 생성하는 것을 나타낸다.
      • 그러나 독자는하지 충돌 때문에 OpenCV의 매트 : 클론 () 메소드를 살펴 보셔야합니다.
      inline
      Mat Mat::clone() const
      {
        Mat m;
        copyTo(m);
        return m;
      }
      // 噢 原来是调用的cv::copyTo方法,等等,上面有个const,这下明白了,在拷贝的时候是不允许修改值的,如果正在拷贝,此时相机写入线程正好获取了相机数据,准备写入,这时就发生了冲突。总之读写不能同时进行。
      //那么就是用互斥量将两者互斥,
      #include <mutex>
      std::mutex mtx;
      //在读(Mat::clone()) / 写  之前使用mtx.lock();,之后使用mtx.unlock(); 问题解决啦。
  • 마지막으로,이 정말 이유가 있는지 여부를 테스트합니다. 슬롯 기능 클릭 버튼의 접속 작업을 선언. .clone ()를 호출하고 잠겨 있지.
void QtGuiApplication1::on_btnThread_clicked()
{
 auto myThread = [] {
  while (1) {
   if (!temp_forSave.empty()) {
    Mat lalala = temp_forSave.clone();
    std::cout << "在创建线程中复制\n";
   }
   std::cout << "创建线程" << std::this_thread::get_id() << "运行" << endl;
  }
 };
 std::thread a(myThread);
 a.join();
}
  • (스레드 (1) 복사 할 때 동안, 결국) 정상 작동하는 동안, 버튼을 클릭, 프로그램이 즉시 충돌합니다. 검증은 성공적이다.

추천

출처www.cnblogs.com/neoLin/p/11577345.html