【问题标题】:In which thread are the slots executed?插槽在哪个线程中执行?
【发布时间】:2016-09-16 00:49:52
【问题描述】:

假设我有四个线程,具有以下对象:

线程 1:管理一个 boost::signals2 对象。叫它s。

线程 2:管理 X 对象和对 s 的引用。调用X 对象o2。成员函数X::do() 连接到s,将在o2 上执行。

线程 3:管理 Y 对象和对 s 的引用。调用Y 对象o3。成员函数Y::do() 连接到s,将在o3 上执行。

线程 4:管理对s 的引用和emits 信号。

插槽在哪里执行?它们都在线程 4 中,emit 调用发生在哪里?在线程 1 上,因为那是信号内存地址的线程?还是每个槽都在其对应的线程(2和3)上执行?

最明显的事情是插槽是在thread 4 上执行的,因为有信号被发出(并且调用是同步的),但对我来说,执行函数的线程似乎很奇怪,或者一般来说,操作一个对象,该对象的内存地址属于另一个线程(例如,一个在线程堆上创建的对象,但正在另一个线程中使用)。

访问“外来”线程是否至少比操作“我自己的”对象慢,或者根本没有区别?

【问题讨论】:

  • 与 Qt 的信号和槽实现不同,boost::signals2 没有任何类型的消息循环,因此它不能将工作发布到另一个线程。插槽在发出信号的线程上执行。如果您确实希望特定插槽在另一个线程上运行,则需要某种工作队列。 boost::asio 可能是个不错的选择。
  • 内存不被任何特定线程拥有。任何给定线程访问另一个线程的堆栈或堆上由另一个线程分配的对象都没有问题。这种共享内存空间会使线程处理变得困难,因为它使您面临data races 的恐惧。
  • @SeanCline 如果您的评论是一个答案,我会选择它作为有效答案。
  • @SeanCline en.wikipedia.org/wiki/Thread-local_storage 不是线程“拥有”的吗?
  • 我会说 thread_local 变量只是一个全局变量,但每个线程都有不同的内存地址(因此,每个 thread_local 变量名绑定到每个线程中的不同内存地址) .我认为您可以将该地址(通过指针或引用)传递给另一个线程。所以,一个线程可以操纵一个外来的thread_local变量。

标签: c++ multithreading boost-signals2


【解决方案1】:

在调用(发出)信号的线程上串行调用插槽。为简单起见,您可以将 signlas 视为简单的插槽列表。一旦某个线程调用了一个信号,就好像该线程在该列表上迭代并调用每个连接的插槽。

关于您的第二个问题,线程并不真正“拥有”从中分配的内容。内存和对象所有权是您根据管理代码的方式确定的。一般来说,任何线程都可以访问其进程内存空间上的任何内存地址,只要您设法将有效地址传递给该位置即可。

【讨论】:

    猜你喜欢
    • 2019-01-30
    • 1970-01-01
    • 1970-01-01
    • 2013-03-31
    • 2017-05-17
    • 2011-05-02
    • 1970-01-01
    • 1970-01-01
    • 2016-02-23
    相关资源
    最近更新 更多