多线程程序中的QPointer

发布于 2024-12-06 18:43:18 字数 667 浏览 2 评论 0原文

根据 http://doc.qt.io/qt-5/qpointer.html、QPointer非常有用。但我发现它在以下情况下可能效率低下:

如果我想显示标签三次或做其他事情,我必须使用

if(label) label->show1(); if(label) label->show2(); if(label) label->show3();

而不是 if(label) { 标签->show1();标签->show2();标签->show3(); 。

只是因为在 label->show1();label->show2(); 之后,标签可能会在另一个线程中被销毁

除了三个 if 之外,还有其他更好的方法来获得相同的功能吗?

另外一个问题是,当label在if(label)之后被销毁时,if(label) label->show1();仍然是错误的吗?

我没有多线程程序的经验。任何帮助表示赞赏。 ;)

According to http://doc.qt.io/qt-5/qpointer.html, QPointer is very useful. But I found it could be inefficient in the following context:

If I want to show label for three times or do something else, I have to use

if(label) label->show1();
if(label) label->show2();
if(label) label->show3();

instead of
if(label) { label->show1();label->show2();label->show3(); }

just because label might be destroyed in another thread after label->show1(); or label->show2();.

Is there a beautiful way other than three ifs to get the same functionality?

Another question is, when label is destroyed after if(label), is if(label) label->show1(); still wrong?

I don't have experience in multi-threaded programs. Any help is appreciated. ;)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

分開簡單 2024-12-13 18:43:18

我认为唯一安全的方法是确保您只从主/GUI 线程(即在 QApplication::exec() 内部运行 Qt 事件循环的线程)访问 QWidget。

如果您有在不同线程中运行的代码,并且该代码希望显示/隐藏 QLabels/无论什么,那么该代码需要创建一个 QEvent 对象(或其子类)并调用 qApp->postEvent()将该对象发送到主线程。然后,当 Qt 事件循环在主线程中拾取并处理该 QEvent 时,您的代码就可以安全地对 QLabels 执行操作。

或者(也许更简单),线程的代码可以发出跨线程信号(如所述此处)并让 Qt 在内部处理事件发布。这可能更适合您的目的。

I think the only safe way to do it is to make sure you only access your QWidgets from within the main/GUI thread (that is, the thread that is running Qt's event loop, inside QApplication::exec()).

If you have code that is running within a different thread, and that code wants the QLabels to be shown/hidden/whatever, then that code needs to create a QEvent object (or a subclass thereof) and call qApp->postEvent() to send that object to the main thread. Then when the Qt event loop picks up and handles that QEvent in the main thread, that is the point at which your code can safely do things to the QLabels.

Alternatively (and perhaps more simply), your thread's code could emit a cross-thread signal (as described here) and let Qt handle the event-posting internally. That might be better for your purpose.

双马尾 2024-12-13 18:43:18

您的方法都不是线程安全的。您的第一个线程可能会执行 if 语句,然后另一个线程将删除您的标签,然后您将进入 if 语句并崩溃。

Qt 提供了许多线程同步构造,您可能希望从 QMutex 并在继续处理此程序之前了解有关线程安全的更多信息。

使用互斥体将使您的函数看起来像这样:

mutex.lock();
label1->show();
label2->show();
label3->show();
mutex.unlock()

只要您的其他线程正在使用锁定同一个互斥体对象,那么它就会阻止您在显示标签时删除它们。

Neither of your approaches is thread-safe. It's possible that your first thread will execute the if statement, then the other thread will delete your label, and then you will be inside of your if statement and crash.

Qt provides a number of thread synchronization constructs, you'll probably want to start with QMutex and learn more about thread-safety before you continue working on this program.

Using a mutex would make your function would look something like this:

mutex.lock();
label1->show();
label2->show();
label3->show();
mutex.unlock()

As long as your other thread is using locking that same mutex object then it will prevented from deleting your labels while you're showing them.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文