有人如何从另一个线程访问在主事件循环中创建的QObject而不阻塞主事件循环?

迈克510a

在我的场景中,我有一个复杂的QObject *和QQuickItem *层次结构,其中设置了许多对应用程序至关重要的子对象。

我希望完成的是:

从特定的QObject插入类型执行复杂的,占用大量CPU的操作。此操作必须访问层次结构中许多不同QObject的属性,并且需要通过单独的线程复制和解析大量内存(以至于简单地阻塞主事件循环比复制所有内容更有效)过度)。

有没有一种方法可以直接访问作为创建新线程的主QObject的子级的QObject?

让我用一些代码澄清一下:

此代码段负责在符合特定条件的块网格中查找相邻的块(这是我的CPU密集型操作,因为需要在短时间内执行多次)

QList<QQuickItem *> Blockgrid::find_neighbors(QQuickItem *startItem, QList<QQuickItem *> currentNeighbors, QQuickItem *currentItem)
{
  QList<QQuickItem*> neighbors;
  QList<QQuickItem*> new_neighbors;
  Blockrow* startRow = this->get_item_row(startItem);
  int startCell = startRow->get_cell_number(startItem);
  int startColor = startItem->property("blockColor").toInt();
  Blockrow* currentRow = this->get_item_row(currentItem);
  int currentCell = currentRow->get_cell_number(currentItem);
  QList<QQuickItem*> potential_neighbors;
  QQuickItem* topNeighbor = this->find_block(currentRow->rowNumber() - 1, currentCell);
  QQuickItem* bottomNeighbor = this->find_block(currentRow->rowNumber() + 1, currentCell);
  QQuickItem* leftNeighbor = this->find_block(currentRow->rowNumber(), currentCell - 1);
  QQuickItem* rightNeighbor = this->find_block(currentRow->rowNumber(), currentCell + 1);
  if (topNeighbor != nullptr) {
      potential_neighbors << topNeighbor;
    }
  if (bottomNeighbor != nullptr) {
      potential_neighbors << bottomNeighbor;
    }
  if (leftNeighbor != nullptr) {
      potential_neighbors << leftNeighbor;
    }
  if (rightNeighbor != nullptr) {
      potential_neighbors << rightNeighbor;
    }
  foreach (QQuickItem* potentialItem, potential_neighbors) {
      if (potentialItem->property("blockColor") == startColor) {
          if (potentialItem != currentItem) {
              if (!neighbors.contains(potentialItem)) {
                  new_neighbors << potentialItem;


                }
            }
        }
    }

  QList<QQuickItem*> final_neighbors;


  if (new_neighbors.count() > 0) {
      final_neighbors << currentNeighbors;
      foreach (QQuickItem* neighborItem, new_neighbors) {

          if (!final_neighbors.contains(neighborItem)) {
              QList<QQuickItem*> send_neighbors;
              send_neighbors << currentNeighbors << neighborItem << this->find_neighbors(startItem, send_neighbors, neighborItem);
              foreach (QQuickItem* sendItem, send_neighbors) {
                  if (!final_neighbors.contains(sendItem)) {
                     final_neighbors << sendItem;
                    }
                }
            }
        }
    }

  return final_neighbors;
}

重要的不是CPU密集型代码,它只是用来提供有关操作复杂性的上下文。

我要完成的工作是detect_matches在单独的线程中运行该方法


 class Worker : public QObject
  {
      Q_OBJECT

  public slots:
      void detect_matches(Blockgrid* i_grid)
       {
        for (int row=0; row<i_grid->numberOfRows; row++) {
            for (int col=0; col<i_grid->numberOfRows; col++) {
                i_grid->find_block(row, col)->setProperty("opacity", 1.0);
              }
          }
        for (int row=0; row<i_grid->numberOfRows; row++) {
            for (int col=0; col<i_grid->numberOfRows; col++) {
                QList<QQuickItem*> currentNeighbors;

                QList<QQuickItem*> matches;
                matches <<  i_grid->find_neighbors(i_grid->find_block(row,       col), currentNeighbors, i_grid->find_block(row, col));
                if (matches.count() >= 3) {
                    foreach (QQuickItem* matchItem, matches) {
                       matchItem->setProperty("launched", true);
                       i_grid->find_block(row, col)->setProperty("launched",true);


                      }

                  }

              }
          }

      }

   }


};

该线程使用以下moveTothread技术启动


 void Blockgrid::find_matches() {

      Worker *worker = new Worker;
      worker->moveToThread(&workerThread);

      worker->detect_matches(this);

 }

有没有办法使这项工作?当前,Worker线程一旦移动到单独的线程中,便无法与Blockgrid对象中存在的对象进行交互。

就像我之前说过的那样,将所有数据从Blockgrid类复制到Worker线程中本质上将需要比该线程完成计算所需的时间更多的CPU和处理时间,这就是为什么我希望找到一种技术来允许用于跨线程访问对象。

谢谢。

哲敏

您的Worker类的构造函数应使用指向共享库的指针。然后,Worker类应该使用此注入的共享库执行活动。

这样,您可以控制哪个工作线程将使用哪个共享库。另外,需要注意通过互斥锁进行数据同步。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

在主事件循环之前如何创建一些对象?

在单独的线程中等待而不阻塞主事件循环,异步 python

Tkinter:如何使用线程防止主事件循环“冻结”

Tkinter:如何使用线程防止主事件循环“冻结”

停止NSApplication主事件循环

如何将任务添加到在另一个线程上运行的Tokio事件循环中?

本地 QEventLoop - 等待来自线程的信号 - 防止处理来自主事件循环的事件

在插槽中调用QDialog :: exec是否会阻塞主事件循环?

实现while循环而不会中断bot的主事件循环

主事件循环可以中断代码执行吗?

如何获取基于系列主事件的所有重复事件

传统 Java 应用程序中的“主事件循环”看起来如何 [JCIP 9.1]

如何让一个函数访问另一个函数内部的for循环中的变量?

asyncio :: 访问在另一个循环中创建的 websocket

Python - 如何在另一个具有范围的循环中运行循环?

在 SQL 中的另一个循环中创建一个循环?

使用另一个循环中的子项在 foreach 循环中创建数组

调用在Java的另一个循环中创建的变量,以及如何在do ... while循环中具有多个条件

如何在另一个循环中循环线程句柄并在完成后加入?

如何从循环中的另一个数据帧创建多个数据帧

如何在另一个循环中循环两个循环

Qt主事件队列被阻塞时的QTimer超时处理

创建一个订阅来自阻塞线程的事件的表单

如何创建一个事件,将触发没有jQuery的另一个事件?

在另一个for循环中使用for循环

如何将主事件中的函数调用到另一种方法中?

在 for 循环中的另一个列表项之后创建一个列表名称

如何访问 *ngFor 循环中的一个按钮并在单击事件时为其分配公共删除方法

Javascript for循环没有在另一个for循环中获得长度