I just implemented something like that. Shared memory was my first approach, but there is a problem with that. On Windows shared memory behaves pretty much like a smart pointer. The last holder of the shared memory deletes the shared memory object when it is no longer needed. On posix systems shared memory is created by a server and clients can connect to it. I don’t think there is a way to transfer ownership. This is a problem as the plugin that acts as a server can be deleted, while it is still being used by the other process.
So far so good. In my case I wanted to implement communication between plugins. At this point in time I believed that all plugins are running in the same process. So I just implemented a communication class and used a juce::SharedResourcePointer to have the same instance available in all plugin instances. When a plugin gets instantiated it registers itself. Now other instances of the plugin can request a list of all instances. I had to implement a pretty complicated connection mechanism to make sure that you are not accessing an instance of a plugin that is no longer available. Now with AU v3 things are going to change as plugins might run in different processes. I’ll have to look into that. I think running plugins in different processes is optional but I’m not sure yet. I really hope that there is/will be an option to run plugins of the same kind in the same process.
You need to create a shared memory object that is available all the time. If you only need a Windows implementation things are easier as your first instance of your plugin can create the shared memory block, all other instances are able to use it and the last instance will delete it automatically. If you need an implementation for posix (OS X etc.) systems as well, you probably have to use a service that creates the shared memory block. You might wanna take a look at the boost shared memory implementation as you can use their implementation to load container into shared memory and you don’t have to worry about allocation.
Before I used the SharedResourcePointer I had an implementation based on the juce::InterprocessConnection. You have to implement some message handling, but you don’t have to worry that much about synchronization. I used broadcast messages (juce::MessageManager) to discover all plugin instances. An instance of a plugin sent out a discover message and all other instances answered with offers that included the name of their pipe (yes I forgot to mention, I used pipes!).