You are not logged in.
in my current project i'm using shared memory as kind of decentralized (only on local host) communication system.
It's possible for any process linked to my library to access the shared memory. If it doesnt exist, the shm is created.
The last process who doesnt need it any more also destroy's the memory.
From shm point of view the memory segment is created from process A but maybe destroyed sometimes later by process D
while process B and C are just attaching and read/write something.
That's how it actually works.
What i want to do now is getting better performance in accessing the segment. E.g. a shm drawback is that no process get's
notified if something changes. Think about the following situation: The segment is accessed by 20 (or way more) processes.
Most of them are just waiting for someone else to write to the shm. Then process 21 has information which all the other 20 need to know.
So it writes to the memory and know needs to notify a bunch of processes for which:
o) the process id is not known - since processes can attach and leave as they want it's hard to track this in consistent way with good performance, think about segfault's of a process
o) a semaphore would only notify 1 of those 20 processes
The idea is that i use inotify. Thus process 21 just needs to access a specified file using a specified pattern.
One further problem to note: there can be a bunch of shared memory segments all having different internal unique id's so there must be different inotify files for them.
o) is it possible to use inotify without actually create a file BUT get notified if a file of a specified name get's accessed. Maybe even in case of an error, e.g. permission denied?
thus i could listen to "is file /LIBNAME.UUID opened for reading altough the file doesnt exist"-events and thus dont need to actually create a real file. this would also mean
in case of a crash i dont need to think about cleanup and such OR preventing situations like: the files permissions are changed by someone who doesnt know about it and thus nothing
will work any more, ...
just asking for the best self organizing solution ^^
o) is there some kind of abstract filesystem mechanism i could use like the one of unix domain sockets?
o) anyone else has a another idea on how to notify a bunch of processes with pretty much standard tools available on linux?
any hint on this or further guidance would be great.
Last edited by thinking (2012-03-29 08:29 AM)
I'm not sure if it works with inotify, but if you're using POSIX shared memory segments, those exist in the filesystem, typically under "/dev/shm/", so you might be able to use the segment itself without needing a separate file... Even if not, you could actually use a real file and just mmap() that, and effectively use that as "shared memory", too... Then, just wait to get notified when the segment/file is modified...
Alternatively, you could have a multicast group all the processes join and listen for notifications of changes... Or, you could slog your way through "/proc/<pid>/maps" looking for anyone who has the shared memory segment mapped and hit them with a signal or something... (But, you may run into permission issues, if the processes are run by different users...)
/proc/pid/maps: i already thought about that, but this may cause kind of race conditions during iterating the pid's - this is solvable, but i think the other ways should be prefered
multicasting: this is one i never used. i tested an example and in general this seems to be a possibility. one thing to note about this
the loopback interface doesn't seem to handle multicast out of the box
i found a few thread's about this and suggesting to add a route like this
route add -net 220.127.116.11 netmask 240.0.0.0 dev lo
in the end, either a route needs to be added or an interface capable of multicasting must be available for this to work
first i'll have a look on mmap - thx
Last edited by thinking (2012-03-29 01:39 PM)
If you don't mind Linux-only code anyway, I would just use a futex on the
shared memory mapping: Processes waiting for changes call FUTEX_WAIT
and the process writing something calls FUTEX_WAKE. If you do the
operations atomically then it's race free too, and if you ever want to
have multiple writers then it's easy to extend it to use it for locking too.