En Qt, par exemple, si vous émettez un signal dans un fil d'autrui à d'autres que le fil de l'interface graphique, le signal est en cours et exécuté plus tard dans le fil de l'interface graphique, existe-t-il un moyen de le faire avec Boost? P>
merci p>
5 Réponses :
Pas directement, car Boost ne fournit pas de boucle d'événement. P>
Pour avoir un signal manipulé dans un autre fil, qu'un autre fil doit vérifier la file d'attente des gestionnaires, elle doit exécuter et les exécuter (qui signifie généralement une sorte de boucle d'événement). Boost n'en fournit pas une, vous aurez donc besoin de l'obtenir d'ailleurs ou d'écrire. P>
Si vous avez une boucle d'événement, cela ne fournit pas de signaux, (ou implémente une solution simple avec les files d'attente), vous devriez être capable de (ab) utiliser boost.signals2 (pas boost.signals, car cette version n'est pas du thread -Safe) en remplaçant l'opérateur + = code> pour envelopper chaque gestionnaire dans quelque chose, cela la fitera pour l'exécution dans l'autre thread. Vous pourriez même être en mesure de le mettre en œuvre pour les signaux avec des valeurs de retour (qui n'est pas pris en charge par QT, mais est pris en charge par Boost), mais vous devrez faire attention à éviter les blocages morts. P>
Pour une boucle d'événement Utilisez Boost :: Asio :: io_service. Vous pouvez publier des tâches à l'intérieur de cet objet et avoir un autre fil d'exécution, dans un fil de sécurité de fil:
struct MyClass { boost::io_service service; void doSomethingOp() const { ... } void doSomething() { service.post(boost::bind(&MyClass::doSomethingOp, this)); } void loop() { service.run(); // processes the tasks } }; boost::signal<void()> mySignal; MyClass myClass; mySignal.connect(boost::bind(&MyClass::doSomething, boost::ref(myClass))); // launches a thread and executes myClass.loop() there boost::thread t(boost::bind(&MyClass::loop(), boost::ref(myClass))); // calls myClass.doSomething() in this thread, but loop() executes it in the other mySignal();
Thx pour cet échantillon très utile! Depuis Boost :: Signal est obsolète, je dois utiliser Boost :: Signals2 :: Signal <>.
La réponse de Chila est correcte, mais il manque une chose importante:
Un objet Remarque: Au moment de la rédaction (Boost 1.67), cette méthode est déjà obsolète et vous êtes censé utiliser boost :: thread code> n'appellera que la fonction adoptée une fois. Depuis le
boost :: io_service code> n'a pas de travail à faire avant que le signal soit émis, le fil finira immédiatement. Pour contrer cela, il y a un
boost :: asio :: io_service :: travail code> classe.
Avant d'appeler la méthode
exécution () code> de
io_service code> Vous devez créer un objet de travail et transmettre le
io_service code>:
io_context :: exécuteur_work_guard code> (essentiellement la même fonctionnalité que
io_service :: Travail code>). Je n'ai pas pu compiler lorsque vous utilisez la nouvelle méthode et la solution de travail fonctionne toujours dans Boost 1.67. P> P>
Pour une raison quelconque, l'opérateur d'affectation de Voici ma version du code qui publie un événement code> Mouvable CODE> et le traite sur le thread exécutant Boost :: Asio :: Executor_work_guard
io_context :: exécuté () code>: p>
class MyClass {
public:
MyClass () : m_work(boost::asio::make_work_guard(m_service)) {}
size_t loop() {
return m_service.run();
}
void stop() {
m_work.reset();
}
void doSomething(Event&& e) {
m_service.post([this, e=std::move(e)]{ doSomethingOp(std::move(e)); });
}
private:
void doSomethingOp(const Event& event) {
...
}
//data:
boost::asio::io_context m_service;
boost::asio::executor_work_guard<boost::asio::io_context::executor_type> m_work;
};
Voici un exemple complet de io_service code>, code> exécuteur_work_guard code>,
signals2 :: signal code>.
.
io_service code> est le gestionnaire de boucle d'événement li>
exécuteur_work_guard code> Assurez-vous que le m_service.run () strong> n'exécute pas seulement une fois li>
signal code> /
Slot code> découle l'expéditeur et le récepteur li>
thread code> exécute tout le processus du
io_service code> li>
ul>