2011-10-16 26 views
6

Temelde sahip olduğum şey şudur:Güvenli İleti Birden çok ileti dizisi ile Kuyruk

İletileri periyodik olarak denetleyen ve işleyen bir A iş parçacığım var.

Konuları B ve C A.

B ve C veya B veya C A, bir mesajın, ve böylece kuyruk erişen bir süre bir mesaj göndermek çalıştığınızda sorun doğar

mesaj göndermek gerekiyor.

Bu sorun genellikle nasıl çözülür?

sayesinde

Bu normalde mutexes veya diğer çok iplikli koruma mekanizmaları kullanılarak çözülmüştür
+0

? Küçük pseudocode örneğimi temizlememe yardımcı olur. – Nate

cevap

4

.

Windows'ta çalışıyorsanız, MFC bu sorun için CMutex class sağlar.

Bir posix sisteminde çalışıyorsanız, posix API pthread_mutex_lock, pthread_mutex_unlock, and pthread_mutex_trylock functions sağlar.

Bazı temel yalancı kod sizin durumunuzda kullanımlarını göstermek için kullanışlı olacaktır: Her üç dizileri için

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() 
    } 
} 

, kuyrukta hareket etme yeteneği muteksi elde etme yapmasıyla mümkün - onlar blok basitçe olacak ve muteks elde edilene kadar bekleyin. Bu, bu kaynağın kullanımından kaynaklanan çakışmaları önler.

+0

Nate'in cevabı doğrudur, ancak mutekslerin kullanımı kolay olmakla birlikte, oldukça yüksek iş yükü senaryoları için uygun olmayabilir, çünkü nispeten yüksek bir yüke sahiptirler. –

+0

Ah, ama genel olarak iş parçacığı yapmak; ^) Cidden olsa da, farklı platformlar iş parçacığı korumasına gelince farklı zayıflıklara sahiptir; Orada kisisel kisim (ki sana bakiyorum, pencerelere) ve mutekslerin sadece atomik kontroller etrafinda "sarici" olduklarini (ki bu da bir kacina mal olur) olan kisileri var. – Nate

+0

@Nate: Windows'da, muhtemelen çok ucuz olan Kritik Bölümleri arıyorsunuz. –

0

Windows'ta değilseniz veya C++ uygulamasında çapraz platform olan bir şey uyguluyorsanız, ACE kitaplıklarındaki Kuyruğu kullanmayı deneyin. kuyruktan almak için

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_Queue<ACE_MT_SYNCH> *msg_queue; 

ACE kütüphane örneklerinden numune olarak, Sonra sıraya mesajı koyarak için kullanabilirsiniz

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(); 

avantajı ise Çok fazla kod yazmak zorunda kalmadan senkronizasyonu ilkel olarak kolayca değiştirebilir. Win32 veya posix ile çalışıyorsunuz