【发布时间】:2020-02-17 02:20:58
【问题描述】:
在我的场景中,我有一个复杂的 QObject* 和 QQuickItem* 层次结构,其中包含许多对应用程序都至关重要的子对象。
我希望完成的是:
从特定的 QObject 继承类型执行复杂的 CPU 密集型操作。此操作必须访问层次结构中许多不同 QObject 的属性,并且需要由单独的线程复制和解析大量内存(到了简单地阻塞主事件循环比复制所有内容更有效的地步)结束)。
有没有办法直接访问作为创建新线程的主 QObject 的子级的 QObject?
让我用一些代码澄清一下:
这个sn-p负责在块的网格中找到匹配某些条件的相邻块(这是我的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 线程移动到单独的线程中,Worker 线程就无法与 Blockgrid 对象中的对象进行交互。
就像我之前说的,将 Blockgrid 类中的所有数据复制到 Worker 线程中,实际上需要的 CPU 和处理时间比线程完成计算所需的时间要多,这就是我希望找到一种技术的原因这将允许跨线程访问对象。
谢谢。
【问题讨论】:
标签: qt thread-safety