QStringListに追加するには、 QtConcurrent :: map?永遠にフォルダを監視し、マルチスレッド処理のために新しいファイルをキューに追加するアプリケーションを作成しようとしています。
mutexで保護された単純なスタックまたはキューのようなコンテナでタスクを実装できるため、QtConcurrent::map
も使用しません。
すべてのワーカー(コンシューマ)スレッドを自分の信号に接続します。たとえば、void MyClass:: newFileAvailable()
です。
移入しvoid QFileSystemWatcher::directoryChanged(const QString &path)
信号を作成し、キューのような構造(またはあなたはそれがスタックなどを行うことができます):だから
class FilePathQueue
{
void push(const QString& path)
{
QMutexLocker lock(&mutex);
list.push_back(path);
}
QString pop()
{
QMutexLocker lock(&mutex);
if (list.isEmpty())
return QString();
QString ret = list.front();
list.pop_front();
return ret;
}
private:
QMutex mutex;
QStringList list;
};
は、すべてのワーカースレッドがnewFileAvailable()
信号に加入しなければならないし、新しいファイルパスを消費しますFilePathQueue::pop()
を介して利用可能なアイテムが残っているかどうかを確認します。これはQtのシンプルで言う、と非常に管理して行われる
// the worker thread supposed to be running in own thread
// see QObject::moveToThread()
class MyWorker : public QObject
{
public:
MyWorker(QObject* parent, FilePathQueue& list) :
QObject(parent), fileList(list) {}
///
public slots:
void processNewFile()
{
QString path = fileList.pop();
if (path.isEmpty()) return;
process(path);
}
void process(const QString& path);
private:
FilePathQueue& fileList;
};
、いくつかの労働者あたり毎秒何千ものファイルの到着信号が、より多くの消費者以上と高い割合のため:
/* File path thread-safe container */
FilePathQueue fileList;
/* Monitor folder for new files to add to queue */
QFileSystemWatcher fsw(folders);
QObject::connect(&fsw, &QFileSystemWatcher::directoryChanged,
[&](const QString& path){
fileList.push(path); // push in new path
emit newFileAvailable(); // let workers know
// TODO: here we can have condition.notify_all() or notify_one()
// instead of signal emit for the higher performance
});
// launch new workers
for(int n=0; n<8; ++n)
{
Worker* worker = new Worker(this, fileList); // create worker and
worker->start(); // starts own thread etc.
connect(this, &MyClass::newFileAvailable, // connect it to new
worker, &MyWorker::processNewFile); // file signal
}
ワーカークラスリアルタイムパフォーマンスシステムQWaitCondition :: wait()は、ロジックに応じて、ワーカースレッド側でQWaitCondition::notify_one(
)またはnotify_all()
を実行する必要があります。そのロジックを実装するために、より精巧なワーカースレッドの例を提示する必要があります。