我是消息發佈/消息泵體系結構的忠實粉絲。這是MFC/Win32提供的在線程之間傳遞數據的主要方法。這種體系結構是事件驅動的線程消息,所以當接收線程正在處理線程消息時,它正在處理爲線程間通信明確提出的數據(參見下面的示例)。
您可以自己實現這一點,並將鎖定本地化爲每個線程的單個線程消息列表。所以,當一個線程需要消息的另一個線程你做大致有以下
PostThreadMessage(msg, void* param, int paramSize)
{
lock(msgQueueLock);
// may wish to copy param
char paramCpy = malloc
msgQueue.Queue(msg, pparam, paramSize);
unlock(msgQueueLock);
}
那麼任何線程的主循環只是
// thread's msg pump
while (1)
{
// can also use condition var to wait for queue to change...
lock(msgQueueLock);
HandleMsgLocally(msgQueue.Deque())
unlock(msgQueueLock);
}
反正又回到了MVC,如果事情模型的變化,它可以發佈到您的視圖來更新特定的字段,如:
// Well known msg name
int msgName = MODEL_FIELD_A_UPDATED
...
void Model::UpdateFieldA(int newVal)
{
int* valToCommunicate = new int(newVal)
PostThreadMessage(MODEL_FIELD_A_UPDATED, valToCommunicate, sizeof(int))
}
...
void HandleMsgLocally(...void * param,)
{
if (msg == MODEL_FIELD_A_UPDATED)
{
int* val = reinterpret_cast<int*>(param);
//... process param
delete val;
}
}
優點是你本地化你的鎖定。這是巨大的。另外,只要param被髮送者明確地識別並被接收者刪除,您就不必擔心訪問共享內存。
這有很多缺點,等待時間是一個。如果您需要馬上知道某些事情發生了變化,那麼您需要真正製作共享數據並考慮最佳鎖定方案。如果你確實需要一個可以從多個方向隨時更新的全局狀態,那麼在我的書中這種情況下單例就沒問題了。這種設計實際上大多數適用於朝一個方向發展的數據,您可以進入競爭狀態。但是,您也可以實現鎖定獲取器,以便通過一個線程從另一個線程進行檢查,但要設置必須發佈的值。有很多變數需要考慮,但希望這可以幫助你。另外,你可以忘記刪除消息中的參數。
更新基於編輯 根據您的信息,根據數據量,發佈可能會很好地工作。分析你的代碼很重要。如果我是你,我會玩一些概念證明,然後切換到使用條件變量來管理同步。如果你在Windows平臺上,一定要使用他們的消息泵。
對於一個有意義的答案,您必須至少給出一些數字來表示可視化的更新率,複雜度,必須複製的數據大小等等。否則,這將是我們的純粹猜測... – mghie 2009-02-17 16:53:13