Hi!
Thought I'd share a small utility, I recently wrote. It loads all text-files from a given directory into memory and lets you search for text or regular expressions. Both loading and searching are multi-threaded. Takes around 30secs to load all qt src files on my machine. I took the code editor from the qt-examples. Added some highlighting rules.
CodeFinder-OptionTab.pngCodeFinder-SearchTab.png
For the multi-threading, I ended up using the following construct. Maybe that helps somebody else too.
class ThreadPoolTask
: public QObject,
public QRunnable
{ Q_OBJECT
signals:
void start();
public:
ThreadPoolTask(QThreadPool* tp) {threadPool = tp;}
protected:
void run() {
threadPool->tryStart(this);
emit start();
}
private:
QThreadPool* threadPool;
};
class ThreadPoolTask : public QObject, public QRunnable
{ Q_OBJECT
signals:
void start();
public:
ThreadPoolTask(QThreadPool* tp) {threadPool = tp;}
protected:
void run() {
threadPool->tryStart(this);
emit start();
}
private:
QThreadPool* threadPool;
};
To copy to clipboard, switch view to plain text mode
This tasks start signal is then to be directly connected to some member slot, which is executed in parallel as often as QThreadPool sees fit. This way you can easily and savely interrupt the process and use signals during the process. You just need to protect critical sections with mutexes or semaphores.
QThreadPool tp;
ThreadPoolTask* task = new ThreadPoolTask(&tp);
connect(task,SIGNAL(start()),this,SLOT(doLoadFile()),Qt::DirectConnection);
connect(task,SIGNAL(destroyed()),this,SLOT(doFinish()));
tp.start(task);
while(dir_walker.hasNext())
{
dir_walker.next();
...
if (found == true)
{
fileNames.append(dir_walker.filePath());
fileCount.release();
}
}
fileCount.release(tp.activeThreadCount());
void TextFileLoader::doLoadFile()
{
forever
{
fileCount.acquire();
{
if (fileNames.count() == 0) return;
fn = fileNames.takeFirst();
}
....
}
}
QThreadPool tp;
ThreadPoolTask* task = new ThreadPoolTask(&tp);
connect(task,SIGNAL(start()),this,SLOT(doLoadFile()),Qt::DirectConnection);
connect(task,SIGNAL(destroyed()),this,SLOT(doFinish()));
tp.start(task);
while(dir_walker.hasNext())
{
dir_walker.next();
...
if (found == true)
{
QMutexLocker ml(&fileNameMutex);
fileNames.append(dir_walker.filePath());
fileCount.release();
}
}
fileCount.release(tp.activeThreadCount());
void TextFileLoader::doLoadFile()
{
forever
{
fileCount.acquire();
QString fn;
{
QMutexLocker ml(&fileNameMutex);
if (fileNames.count() == 0) return;
fn = fileNames.takeFirst();
}
....
}
}
To copy to clipboard, switch view to plain text mode
I found no way of setting the threadpools thread priority other than creating an empty wrapper thread with lower priority. The threadpool then inherits its priority. Is there another way?
Any thoughts and criticism are greatly appreciated! And also let me know if you like the tool!
Johannes
Bookmarks