Указатели C ++ на невозвращаемые типы данных Qt являются реентерабельными и безопасными для передачи из основного потока GUI в рабочий поток? - PullRequest
0 голосов
/ 30 апреля 2020

Привет! У меня есть объект c ++ (BackupJob), в котором хранятся данные для заданий резервного копирования, которые передаются между основным потоком GUI и рабочим потоком с использованием сигналов и слотов Qt. Он содержит множество реентерабельных типов данных Qt, таких как QVectors QStringLists QDateTimes et c, которые, как я знаю, безопасны для передачи между потоками ... Я рассматриваю хранение указателей на QThread, QObject и Win API HANDLE в объектах backupjob. QThread не является реентерабельным.

Безопасно ли это делать, если указатели передаются по значению через сигналы и слоты в объекте резервного копирования, а базовые данные, на которые указывают, не изменяются? Указатели являются реентерабельными и могут передаваться между потоками, даже если указанный базовый тип данных не реентерабелен? Я использую определение повторного входа как здесь .

Ситуация может быть дополнительно осложнена тем фактом, что поток, указанный в объекте backupjob, отделен от основного потока GUI и рабочий поток, отслеживающий изменения каталогов самостоятельно. Объект watchDirObject находится в dirMonThread, с отдельными потоками наблюдения за dir для каждого резервного копирования. Рабочий поток выполняет резервное копирование по требованию, а потоки, отслеживающие каталог, обнаруживают изменения каталога в режиме реального времени. Я предполагаю, что один и тот же базовый принцип остается единственно важным, чтобы рассмотреть вопрос о том, безопасны ли эти указатели для передачи между потоками.

Спасибо!

Вот некоторый код:

//executed in main thread
workerThread = new QThread(this);
workerThread->start();
worker = new Worker;
worker->moveToThread(workerThread);
connect(this, SIGNAL(backup(QList<BackupJob>,QList<BackupJob>)), worker, SLOT(backup(QList<BackupJob>,QList<BackupJob>)));

class BackupJob
{
...
QList<std::pair<BBFileInfo, BBFileInfo> > fileList;
QMap<QString,qint64> requiredSize, peakSize;
...
QThread *dirMonThread;
//WatchDirectory QObject moved to dirMonThread
WatchDirectory *watchDirObject;
HANDLE dirMonThreadObjectHandle;
}

//executed in main thread to set up directory watching thread
void Replicator::setupJobContinuousThread(BackupJob &job)
{
if (!CreateEvent(NULL,TRUE,FALSE,job.getName().toStdWString().c_str()))
    win32Error(TEXT("CreateEvent"));
job.setupContinuousThread(this);
connect(job.getContinuousThread(),&QThread::finished,job.getContinuousObject(),&QObject::deleteLater);
connect(job.getContinuousObject(),&WatchDirectory::sendRealTimeOperationJob,this,&Replicator::commitRealTimeOperations);
//connect(replicator,&Replicator::dirMon,job.getContinuousObject(),&WatchDirectory::startWatch);
QMetaObject::invokeMethod(job.getContinuousObject(),"startWatch",Qt::QueuedConnection);
}

void BackupJob::setupContinuousThread(Replicator *replicator)
{
dirMonThread = new QThread(replicator);
dirMonThread->start();
watchDirObject = new WatchDirectory;
watchDirObject->moveToThread(dirMonThread);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...