可能有更简单的方法可以解决您的问题。例如,我会考虑研究QtConcurrent框架。或者,您也可以重新设计您的设计,以便客户端首先连接到缓存上的“完成”信号,然后再请求缓存执行任何操作。如果没有这些,您可能还会考虑依靠QMetaObject::invokeMethod函数(用于客户端或缓存)。这个函数允许你使用任意的泛型参数(以线程安全的方式)在任意QObject上调用任意方法(假设你有一个指向它的指针)。
如果您使用QMetaObject::invokeMethod
方法,您应该注意一些缺点。首先,您必须使用其字符串名称调用该方法,这意味着您不会在编译时发现是否使用了错误的名称。其次,由于您的客户端与中央缓存具有不同的线程关联性,因此当缓存调用方法时,客户端可能会被销毁(可能对您而言,这对您来说不会有问题) 。最后,你可能不希望你的缓存知道它必须在它的客户端上执行的方法的名字。
我没有办法绕过第一个缺点(我不确定这是否会在即将到来的Qt 5.0版本中以不同方式处理)。至于第二个和第三个问题,我建议创建封装到一个方法的引用一个对象 - 像下面的东西:
class MethodReference
{
MethodReference(QObject* object, const QString& methodName);
...
bool invoke(QGenericArgument val0 = QGenericArgument(),
QGenericArgument val1 = QGenericArgument(),
...
QGenericArgument val9 = QGenericArgument());
private:
QPointer<QObject> mObject;
QString mMethod;
};
你会然后把这个对象传递给你的缓存从客户端。缓存然后调用此对象的调用。
请注意QPointer
的使用 - 这为您提供了一种线程安全的方法,用于在尝试调用其上的方法之前检查对象是否已被销毁。由于我之前完成了这个工作,我还会告诉你,4.8之前的Qt版本有一个bug in QPointer
,这会导致多线程环境中的崩溃。如果你想这样做,请使用更新版本的Qt。
我希望这很清楚。
- 从客户端对象或数据缓存中调用'QObject :: connect'以形成客户端和数据缓存之间的链接? - 这个问题的标题是什么意思 - 你的应用程序创建的具体线程是什么? - 客户端对象在接收到“数据缓存完成”信号时需要做什么,我指的是客户端需要从缓存中检索多少数据? – sjwarner 2012-08-17 17:49:30
澄清@sjwarner评论。我从客户端对象调用QObject :: connect,即QMainwindow派生对象。我一直假设它们中的每一个代表一个单独的GUI线程。返回的数据量取决于数据缓存的要求,数量可能很少或很大。我正在使用指向数据缓存的指针来访问这些数据。正在被访问的数据一旦被初始化就是静态的,因此没有锁定机制。到目前为止,我没有任何冲突。 – bogflap 2012-08-22 14:14:37