C ++ fix méretű várólista teljes / üres jelzés

Olyan alkalmazást fontolgatok, ahol gyakran nagy adatokat kell fájlba írni. Szeretnék használni várakozási sorra van szükségem, és a termelő és a fogyasztó különböző szálakon fut. Ezenkívül szeretnék egy rögzített méretű várólistát, mivel az adatméret nagyon nagy lehet. A boost :: lockfree :: queue with boost egyszerű tesztjét hajtottam végre :: feltétel_változó a sor állapotának jelzésére. Szeretném elkerülni a mutexet, de kivételtől eltekintve, ha a sor tele van (blokk előállító) vagy üres (blokkolja a fogyasztót)

Szeretném tudni (vélemény alapján …), ha igen m, ha a feltételeket megfelelően használom, vagy ha valamilyen teljesítményprobléma van – összehasonlítva más módszerekkel. Itt van, amit eddig tettem (kis adatok) Ez működik (output):

consumer waiting pushed 0 pushed 1 pushed 2 producer waiting popped 0 pushed 3 producer waiting popped 1 pushed 4 producer waiting popped 2 pushed 5 producer waiting popped 3 pushed 6 popped 4 popped 5 popped 6 

Arra számítok, hogy az adatok többnyire szinte mindig rendelkezésre állnak, de torlódások esetén blokkolni szeretnék ( fájlírás, hálózat stb.). A fix méret iránti érdeklődés a tömeges adatkészletek és a sor dinamikus allokációjának aggodalma –

(Ez inkább egy kísérlet a megtehető dolgokról. A valóságban az adataim legfeljebb kb. 20 Hz-re frissülnek. szóval az is nagyon jól fog menni, ha egy zárat veszek egy std :: sorba, amelynek a méretét kezelem.)

Válasz

Használjon egy szemaforot, hogy a gyártók aludjanak, amikor a sor megtelt, és egy másik szemaforral, hogy a fogyasztók aludjanak, amikor a sor üres. amikor a sor nem teljes és nem üres, a sem_post és a sem_wait műveletek nem blokkolódnak (újabb kernelekben)

#include <semaphore.h> template<typename lock_free_container> class blocking_lock_free { public: lock_free_queue_semaphore(size_t n) : container(n) { sem_init(&pop_semaphore, 0, 0); sem_init(&push_semaphore, 0, n); } ~lock_free_queue_semaphore() { sem_destroy(&pop_semaphore); sem_destroy(&push_semaphore); } bool push(const lock_free_container::value_type& v) { sem_wait(&push_semaphore); bool ret = container::bounded_push(v); ASSERT(ret); if (ret) sem_post(&pop_semaphore); else sem_post(&push_semaphore); // shouldn"t happen return ret; } bool pop(lock_free_container::value_type& v) { sem_wait(&pop_semaphore); bool ret = container::pop(v); ASSERT(ret); if (ret) sem_post(&push_semaphore); else sem_post(&pop_semaphore); // shouldn"t happen return ret; } private: lock_free_container container; sem_t pop_semaphore; sem_t push_semaphore; }; 

Válasz

Nagyon szkeptikus lennék a zár nélküli tárolót, két mutexet és egy feltételes változót tartalmazó kóddal a szálak közötti blokkolási sor megvalósításához. Anélkül, hogy tovább néznék.

Valószínűleg az alábbi prototípusból indulnék ki (lehet, hogy először ellenőrizném, hogy a boost :: interprocess tartalmaz-e valamit, amit azonnal felhasználhatnék):

  1. wrap boost::circular_buffer facebook/Folly/Synchronized -be, de egyéni szekrénnyel, amely try_lock() -re képes, majd további 41-szer forog try_lock(), majd letiltja a (z) lock() alkalmazást, számolva mindhárom forgatókönyv előfordulásait, és felül az értesítés / várakozás
  2. Kiadnám ezt pilóta módban a gyártáshoz, és megvizsgálnám, hogy valóban kell-e bajlódnom egy zár nélküli konténerrel.

Megjegyzések

  • Én ' nem nagyon követem az álkódodat, de megértem az aggodalmaidat. Arra számítottam, hogy a scoped_lock használatával ez rendben lesz, és mindegyikhez szükség van ' s mutexre a feltételes várakozáshoz.

Válasz

A Boost egyetlen termelő egyfogyasztói várólistát biztosít, amely zármentes. Azt hiszem, tud róla? Úgy gondolom, hogy pontosan megfelel az Ön használati esetének.

http://www.boost.org/doc/libs/1_61_0/doc/html/boost/lockfree/spsc_queue.html

Használhat rögzített méretet, és blokkolja a fogyasztót, ha nem áll rendelkezésre adat stb., Anélkül, hogy saját maga hajtaná végre azokat.

Megjegyzések

  • vegye észre ezt, de a (nem hálózatba kötött) gépemnek mintha hiányzott volna. Ennek ellenére úgy gondolom, hogy a pop és a push ugyanúgy működik, nem blokkolja a visszatérő boolot, akár sikeres, akár nem.

Vélemény, hozzászólás?

Az email címet nem tesszük közzé. A kötelező mezőket * karakterrel jelöltük