3

で始まるいくつかのタスクがありQtConcurrent::run()ます。タスクにはQFutureWatcher. 1 つの Future しかQFutureWatcher監視できないことはわかっていますが、UI から同じタスクを開始した場合、各タスクで QFutureWatcher* を作成するにはどうすればよいでしょうか? それは...ですか :

QFutureWatcher<void> *watcher = new QFutureWatcher;
watcher->setFuture(future);
QVector<QFutureWatcher<void>*> watchers;
watchers.push_back(watcher); // vector with pointers to each tasks watchers

または、他の何か? * 問題は、各タスクを自分のコードから開始することですが、タスクは外部 DLL 関数で実行されます。そして、タスクを停止するための API がありません。QFutureWatcher完了信号を受信した後、タスクが終了するのを待ち、関連するすべてのデータを解放してタスクを閉じることしかできません。

現時点では、2 つの QFutureWatcher を使用します。1 つは最初に実行されたタスクを監視し、もう 1 つは最初のタスクが終了していない場合に開始し、一時ウォッチャーと一時スロットを使用して 2 番目のタスクを監視します (コードは同じです。別のウォッチャーを受け取るためだけに作成します)。最初のタスクが終了するまで、関連するデータを含む信号)。そして、同じコードを監視しましたが、最初のタスクが終了するのを待つために複製する必要があります。これQFutureWatcherは、終了したシグナルと関連する watcher.result()`s を持つキューがないためです

1) Qt には Queued task メカニズムがありますか? または、どうすれば複数のタスクの先物をキャッチできますか?

2) QtConcurrent::runcancel() スロットがありません。1 つのシーケンス アイテムで map/mapped 関数を使用できますか? マップされた API には、タスク/終了シグナルのキュー処理がありますか? どうすればそれを理解できますか?どうも!

4

2 に答える 2

3

1)次のようなものを使用できます(コードドラフトのみ):

class MultiWatcher
  : public QThread
{
  Q_OBJECT

signals:
  void allDone();

public:
  void run() override;
  QFutureSynchronizer _sync;
};

void MultiWatcher::run()
{
  _sync.waitForFinished();
  emit allDone();
}


class Test
  : public QObject
{
  Q_OBJECT
public:
  //...
  void do();
  void onDone();
};

void Test::do()
{
  // fill some futures
  auto w = new MultiWatcher();
  w->_sync.addFuture( f1 ); // Not thread-safe
  w->_sync.addFuture( f2 );
  w->_sync.addFuture( f3 );
  // ...
  connect( w, &MultiWatcher::allDone, this, &Test::onDone );
  w->start();
}

void Test::onDone()
{
  sender()->deleteLater();
  qDebug() << "All futures are done";
}

//...
test->do();

2)QFuture::cancel()マッピングされた計算方法があります。あなたの質問からは、どのようにして先物を取得するのかが明確ではないので、これ以上は言いにくいです。Qt の並行性について読んで、さらに質問がある場合は、質問してください。

QFuture::cancelでは動作しませんQtConcurrent::run。スレッド コード内に別の割り込みメカニズムを設計する必要があります。例えば:

std::atomic_bool _isRunning = true; // somewhere in code

void MyWorker::doWork()
{
  while (_isRunning)
  {
    // Do next step of computation
  }
}

// Use _isRunning = false; to interrupt. It's thread-safe.

ただし、管理していないコードを (外部の .dll から) 中断するのは危険です。大量のリークが発生する可能性があるためです。そのため、QtConcurrent には「終了」API がありません。

PSお願いします、私が QThread で間違っていると書かないでください。良いものはすべてあります。私は自分が何をしているのか知っています。これは、継承QThreadがOKな良いサンプルです。

于 2016-07-13T08:52:54.243 に答える