Answer the question
In order to leave comments, you need to log in
How to sequentially show the results of changing one variable by many threads?
Hello. I'm working on an application that needs to output a random game to a specific platform. In order to make the application seem not quite "dry" and boring, I decided to add the effect of turning over the games so that the user would catch a glimpse of a couple of dozen more games on this platform. Although I know about multithreading only from theory and hearsay, I immediately thought about it, but since my model class (Model class) is synchronous, and asynchrony is needed only for one method, I decided to create another class, which I inherited from QThread (AsyncRoller class) . It takes a model pointer and platform name in the constructor and simply calls the method from the model passed to the constructor. Accordingly, I create a dozen or two such threads in the view (I feel in my gut that this is a shit solution). Well, since I don't know much about multithreading, stuck a mutex on the roll method so that threads do not climb out of turn. The result is a quick flipping of a pair of games (1-2). How to sync it?
//model.h
class Model: public QObject
{
Q_OBJECT
Q_PROPERTY(QString rggGame READ game WRITE setGame NOTIFY gameSet)
private:
QString currentGame;
public:
Model(QStringList _platform, QObject* _parent = nullptr);
QString game();
public slots:
Q_INVOKABLE void rollGame(QString _platform);
Q_INVOKABLE void asyncRollGame(QString _platform);
Q_INVOKABLE void setGame(QString _game);
signals:
void gameRolled(QString _game);
void gameSet(QString _game);
};
//model.cpp
//...
void Model::rollGame(QString _platform)
{
static QMutex mute;
mute.lock();
QVector<QString> gms;
QFile games(platformAssignment.value(_platform));
if(!games.open(QIODevice::ReadOnly))
qDebug() << "Error opening platform file!";
while(!games.atEnd())
gms.append(QString::fromStdString(games.readLine().toStdString()));
srand(time(0));
QString gameName = gms[rand() % gms.size()];
emit gameRolled(gameName);
setGame(gameName);
mute.unlock();
}
void Model::asyncRollGame(QString _platform)
{
AsyncRoller* roller = new AsyncRoller(this, _platform);
roller->start();
}
void Model::setGame(QString _game)
{
this->currentGame = _game;
emit gameSet(this->currentGame);
}
//AsyncRoller.h
class AsyncRoller : public QThread
{
private:
Model* model;
QString platform;
public:
AsyncRoller();
AsyncRoller(Model* _mdl, QString _platform);
void run();
};
//AsyncRoller.cpp
AsyncRoller::AsyncRoller(Model* _mdl, QString _platform)
{
model = _mdl;
platform = _platform;
}
void AsyncRoller::run()
{
model->rollGame(platform);
}
Answer the question
In order to leave comments, you need to log in
And why do you need streams, especially in the amount of several dozen?
> Simply synchronous calls of a roll show only the last result.
Well, why does asynchrony immediately mean - several threads? And what does asynchrony have to do with it - you need to make a normal animation, animation is the rendering of frames in accordance with the passage of time. The last result is visible because you do not return control to the application loop so that it can process other messages normally. Remove all this multithreading, randomly generate before the animation all the games that you want to briefly show, set an ordinary timer (QTimer) and draw the games in turn at the signal of the timer until you reach the last one - the one that "dropped out". Deal with the materiel by mainloop and animation and everything will become clear as daylight. Once again, you don't need any threads for your task, especially 20 threads.
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question