可能有更簡單的方法可以解決您的問題。例如,我會考慮研究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