2012-04-19 48 views

回答

2

你是什么意思“与模型互动”?如果你的意思是你想通过直接操作来从多个线程访问模型,那么你必须序列化访问模型。由于模型中有很多方法,我建议你不要在模型中添加互斥体 - 它会非常单调乏味,容易出错,因为它太容易忘记互斥锁。相反,请使用模型继承QObject的事实,从而可以接受事件。

  1. 您的GUI线程直接访问模式。
  2. 其他线程通过向它发布事件(也许接收回复事件)与模型进行交互。
  3. gui线程将以任何其他访问方式连续处理这些事件,从而保护您的模型免受并发访问。

其他线程当然可以从模型中收到回复 - 也通过事件。您将有两个事件基类:一个Request类用于从模型请求事物,然后将有一个模型用于回复的事件基类。 Request类应该有一个QObject* sender成员,以便模型知道发送回复事件的QObject。您可能希望请求和回复都携带相同的标识符(比如说连续增加int),以便请求和响应可以匹配。

您必须实现所有未通过重新实现QThread::run()通过事件模型交互的线程代码,而是一个QObject内。在实例化QObject后,只需将其移至单独的线程即可。 QThread的默认实现run()将旋转一个事件循环,以便在有任何事件,信号或定时器准备好时继续执行QObject。零持续时间定时器是保持线程永久繁忙的一种方式,但要确保一次不会做太多处理,否则会延迟处理传入事件。

您还可以使用信号和槽,但你不能直接给他们打电话,你只能:

  1. connect()他们,
  2. 通过QMetaObject::invokeMethod调用他们Qt::QueuedConnection
  3. 通过在主线程上下文中执行的仿函数(例如lambda)来调用它们;见this answer如何做到这一点。

场景中,当您的信号连接到驻留在单独的线程的QObject的槽后面,Qt的创建警每个信号的连接成QMetaCallEvent,然后解编它在螺纹其中QObject的与目标插槽生活。

相关问题