handling central data buffer for many processes in C++

时间秒杀一切 提交于 2019-12-01 08:31:11

I think (also based on your comment to Maciek) you have to start by understanding the difference between threads and processes and how they can communicate.

Regarding the design problem: Try to start with a simple design. for instance, using only threads and passing each of the subscribers a shared_ptr to the job using it's own synchronized queue*. Since the access to the data is read-only and, AFAICR, boost::shared_ptr is multi-threading safe for such a use, there are no synchronization problems and the data is cleaned automatically. Don't worry about memory realocations (yet), Just make sure you are using a finite amount of memory (o(1)) (as you said, about 51 shared_ptrs at most) per subscriber/thread.

When you'll have this working skeleton, you will be able to start optimizing based on the problems you encounter. If realocations are the problem, you can move to a ring buffer (as suggested by bcat). or you can replace your allocator (/new operator) with a pool allocator. if you have many subscribers, it might be effective to merge the queues into a single one used by all the threads. Doing that requires more information (what if one thread is very slow due to a very long computation? do you have some way to signal it to stop processing? or should the queue grow? if this is the case, a cyclic buffer may not work so well...) and may have its complications, but remember we are only trying to save the room occupied by the shared_ptrs (and not the jobs).

Bottom line, try to avoid premature optimizations. instead, write it with reasonable optimization and extendability in design and go on from there based on what you learn.

Good luck

* synchronized queue - a queue between threads. push(j) adds the job and pop() waits until the queue is not empty and returns the top job (unlike stl::queue. This is important when the queue is read by more than one thread). I usually implement it by wrapping an stl::queue and protecting it using boost::mutex.

I'd look into a ring buffer/circular queue. This will allow you to do what you want with only a one-time memory allocation (provided you make the initial buffer size large enough to hold the maximum necessary number of frames).

As for managing access to the buffer, signaling when data is ready and sharing pointers with the reader(s) will work, but if you're using multiple threads some type of synchronization will be necessary, c.f. the produced-consumer problem.

I've recently implemented something similiar to what you're describing.

I highly recommend the boost::interprocess library (boost.org for more information).

What you're looking for is boost::interprocess / managed_shared_memory. It's gonna look a bit weird at first but once you get the hang of it - you'll love it.

What you want to do is : Create a managed shared memory segment. Allocate an object that is going to handle interprocess communication using a void_allocator (look up allocators). Implement synchronisation mechanisms (boost::interprocess:semaphore & boost::interprocess_mutex for instance). Implement communication from separate processes via the managed shared memory.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!