![](/img/trans.png)
[英]Is it safe to consume a boost::interprocess::message_queue multiple applications?
[英]Safe Message Queue with multiple threads
這是我基本上擁有的:
我有線程A定期檢查消息並處理它們。
線程B和C需要向A發送消息。
當A正在處理消息並因此訪問隊列時,B和C或B或C嘗試向A發送消息時出現問題。
這個問題通常如何解決?
謝謝
這通常使用互斥鎖或其他多線程保護機制來解決。
如果您正在使用Windows,MFC會為此問題提供CMutex類 。
如果您正在使用posix系統,posix api會提供pthread_mutex_lock
, pthread_mutex_unlock
和pthread_mutex_trylock
函數 。
一些基本的偽代碼可以方便地展示它們在你的情況下的用法:
pthread_mutex_t mutex; *or* CMutex mutex;
Q queue; // <-- both mutex and queue are global state, whether they are
// global variables, or passed in as parameters, they must
// be the shared by all threads.
int threadA(/* params */){
while( threadAStillRunning ){
// perform some non-critical actions ...
pthread_mutex_lock(mutex) *or* mutex.Lock()
// perform critical actions ...
msg = queue.receiveMessage()
pthread_mutex_unlock(mutex) *or* mutex.Unlock()
// perform more non-critical actions
}
}
int threadBorC(/* params */){
while( theadBorCStillRunning ){
// perform some non-critical actions ...
pthread_mutex_lock(mutex) *or* mutex.Lock()
// perform critical actions ...
queue.sendMessage(a_msg)
pthread_mutex_unlock(mutex) *or* mutex.Unlock()
}
}
對於所有三個線程,它們在隊列上行動的能力取決於它們獲取互斥鎖的能力 - 它們將簡單地阻塞並等待直到獲取互斥鎖。 這可以防止因使用該資源而產生的沖突。
如果您不在Windows上或者在C ++中實現跨平台的東西,請嘗試使用ACE庫中的Queue。
ACE_Message_Queue<ACE_MT_SYNCH> *msg_queue;
作為ACE庫樣本的示例,您可以使用For將消息放入隊列:
ACE_NEW_RETURN (mb,
ACE_Message_Block (rb.size (),
ACE_Message_Block::MB_DATA,
0,
buffer),
0);
mb->msg_priority (ACE_Utils::truncate_cast<unsigned long> (rb.size ()));
mb->wr_ptr (rb.size ());
ACE_DEBUG ((LM_DEBUG,
"enqueueing message of size %d\n",
mb->msg_priority ()));
// Enqueue in priority order.
if (msg_queue->enqueue_prio (mb) == -1)
ACE_ERROR ((LM_ERROR, "(%t) %p\n", "put_next"));
從隊列中獲取:
ACE_Message_Block *mb = 0;
msg_queue->dequeue_head (mb) == -1;
int length = ACE_Utils::truncate_cast<int> (mb->length ());
if (length > 0)
ACE_OS::puts (mb->rd_ptr ());
// Free up the buffer memory and the Message_Block.
ACE_Allocator::instance ()->free (mb->rd_ptr ());
mb->release ();
優點是您可以非常輕松地更改同步原語,而無需編寫太多代碼。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.