On MacOS, synchronization is handled by the OS, which makes things very simple for us. Changes to the IOSurface are pushed on glFlush() and picked up on the receiving end on glBindTexture(), with the driver taking care of synch. Discussion of its use (not implementation) is in the MacOS header CGLIOSurface.h.
Sorry not to have any useful advice for Windows (maybe vade does) – it sounds like double-buffering might be best if you can efficiently keep track of read/write buffer state in all processes.
We’d be super-interested to hear more about your project – it would be great if you dropped an e-mail to email@example.com.