I have an array that I need to share between two processes. The first process has an injected DLL that constantly grabs info about a few objects, and the second process needs to receive this information. I constantly update this array (the data in the object changes a lot), and the other process needs to constantly receive these updates. I've seen examples where people use shared memory, but I'm not sure how I could use it to constantly update the array. Any advice or code you can throw at me?
You can use memory mapped file to share your array among several processes.
You can share data in a DLL between processes that load that DLL. See How do I share data in my DLL with an application or with other DLLs? for details on how to use #pragma data_seg to do this. So if you store the array in your DLL and both processes open the DLL, all you need is some sort of synchronisation (e.g. a mutex) to arbitrate shared access to the data.
For convenience you would probably want to implement exported functions in the DLL to read/write the array data rather than exporting the raw array itself.
Related
Soft MetaTrader 5. It's trading terminal. It's "indicator" windows are little cpp-like programs. They can load pure cpp dlls. Every "indicator" works in separate thread.
I need to create shared memory stuff which can be accessable from every "indicator". Also for shared memory could be loaded in every indicator it must be in particular dll.
I found info about boost interprocesses.
I am newbee with boost and multithreading.
So I wonder am I right way?
Create dll with shared memory functionality and interface to access it from indicator.
Load dll in several "indicators".
Access it from several "indicators" in real-time?
Could you also advice other ways?
Global variables in shared libraries are not shared across the library user processes. That segment of data is created for every process which loads the library, only the read-only code segment is actually shared.
You need to use a library for shared memory, such as boost::interprocess shared_memory_object or POSIX Shared Memory, or Qt's QSharedMemory. That is however in case you need inter-process communication.
There is nothing special you need to do in order for multiple threads to access shared memory in the same process, aside from using a mutex to prevent data races.
I have an old C++ library which has been designed for use in single-threaded environmens.
The library exposes the interfaces for initialization, which change the internal data structures of the library, and usage, which only reads data and makes calculations.
My objective is to use this library in a Windows multithreaded application, with different threads calling instances of the dll initialized with different data.
Assuming that rewriting the dll to allow multithreading would be prohibitive, is there some way to let multiple instances of a DLL exist in the same process, with separate memory spaces, or to obtain a similar result by other means?
If the DLL contains static resources, then those would be shared among all instances created.
One possible way would be to create a single instance and restrict access to it using some kind of lock mechanism. This may reduce performance depending on usage, but without modifying internal structure of DLL, it may be difficult to work with multiple instance.
The sharing of static resources between all threads attached to a single DLL within a process conspires against you here.
However, there is a trick to achieve this. So long as DLLs have different names, then the system regards them as being different and so separate instances of code and data are created.
The way to achieve this is, for each thread, copy the DLL to a temporary file and load from there with LoadLibrary. You have to use explicit linking (GetProcAddress) rather than lib files but that's really the only way.
I know there are many way to handle inter-communication between two processes, but I'm still a bit confused how to deal with it. Is it possible to share queue (from standard library) between two processes in efficient way?
Thanks
I believe your confusion comes from not understanding the relationship between the memory address spaces of the parent and child process. The two address spaces are effectively unrelated. Yes, immediately after the fork() the two processes contain almost identical copies of memory, but you should think of them as copies. Any change one proces makes to memory in its address space has no impact on the other process's memory.
Any "plain old data structures" (such as provided by the C++ standard library) are purely abstractions of memory, so there is no way to use them to communicate between the two processes. To send data from one process to the other, you must use one of several system calls that provide interprocess communication.
But, note that shared memory is an exception to this. You can use system calls to set up a section of share memory, and then create data structures in the share memory. You'll still need to protect these data structures with a mutex, but the mutex will have to be shared-memory aware. With Posix threads, you'd use pthread_mutexattr_init with the PTHREAD_PROCESS_SHARED attribute.
Simple answer: Sharing an std::queue by two processes can be done but it is not trivial to do.
You can use shared memory to hold the queue together with some synchronization mechanism (usually a mutex). Note that not only the std::queue object must be constructed in the shared memory region, but also the contents of the queue, so you will have to provide your own allocator that manages the creation of memory in the shared region.
If you can, try to look at higher level libraries that might provide already packed solutions to your process communication needs. Consider Boost.Interprocess or search in your favorite search engine for interprocess communication.
I don't think there are any simple ways to share structures/objects like that between two projects. If you want to implement a queue/list/array/etc between two processes, you will need to implement some kind of communication between the processes to manage the queues and to retrieve and store entries.
For example, you could implement the queue management in one process and implement some kind of IPC (shared memory, sockets, pipes, etc.) to hand off entries from one process to the other.
There may be other methods outside of the standard C++ libraries that will do this for you. For example, there are likely Boost libraries that already implement this.
I have a count variable that should get counted up by a few processes I forked and used/read by the mother process.
I tried to create a pointer in my main() function of the mother process and count that pointer up in the forked children. That does not work! Every child seems to have it's own copy even though the address is the same in every process.
What is the best way to do that?
Each child gets its own copy of the parent processes memory (at least as soon as it trys to modify anything). If you need to share betweeen processes you need to look at shared memory or some similar IPC mechanism.
BTW, why are you making this a community wiki - you may be limiting responses by doing so.
2 processes cannot share the same memory. It is true that a forked child process will share the same underlying memory after forking, but an attempt to write to this would cause the operating system to allocate a new writeable space for it somewhere else.
Look into another form of IPC to use.
My experience is, that if you want to share information between at least two processes, you almost never want to share just some void* pointer into memory. You might want to have a look at
Boost Interprocess
which can give you an idea, how to share structured data (read "classes" and "structs") between processes.
No, use IPC or threads. Only file descriptors are shared (but not the seek pointer).
You might want to check out shared memory.
the pointers are always lies in the same process. It's private to the process, relative to the process's base address. There different kind of IPC mechanisms available in any operating systems. You can opt for Windows Messaging, Shared memory, socket, pipes etc. Choose one according to your requirement and size of data. Another mechanism is to write data in target process using Virtual memory APIs available and notify the process with corresponding pointer.
One simple option but limited form of IPC that would work well for a shared count is a 'shared data segment'. On Windows this is implemented using the #pragma data_seg directive.
See this article for an example.
I have written a C++ class that I need to share an instance of between at least two windows processes. What are the various ways to do this?
Initially I looked into #pragma data_seg only to be disappointed when I realised that it will not work on classes or with anything that allocates on the heap.
The instance of the class must be accessible via a dll because existing, complete applications already use this dll.
You can potentially use memory-mapped files to share data between processes. If you need to call functions on your object, you'd have to use COM or something similar, or you'd have to implement your own RPC protocol.
Look into Boost::interprocess. It takes a bit of getting used to, but it works very well. I've made relatively complex data structures in shared memory that worked fine between processes.
edit: it works with memory-mapped files too. The point is you can use data in a structured way; you don't have to treat the memory blocks (in files or shared memory) as just raw data that you have to carefully read/write to leave in a valid state. Boost::interprocess takes care of that part and you can use STL containers like trees, lists, etc.
You can use placement new to create the object in a shared memory zone. As long as the object doesn't use any pointers, that sould be fine.
Is it a POD or do you need to be able to share a single instance across processes? Have you considered using the Singleton pattern (static initialization version, for thread safety reasons)? You will need to use Mutexes as well to protect concurrent writes and stuff.
On Windows, you can use COM as well.