|
Boost : |
From: Ion Gaztañaga (igaztanaga_at_[hidden])
Date: 2006-12-07 12:06:10
Hi Daren,
> Hi -
>
> I am having problems porting some boost::interprocess code from Win32 to Linux
> (rhel4). I am using boost-1.55.
>
> Here's the setup: I need to find if there is an existing instance of the
> process already running. When the process starts up, it checks the shared
> memory for a bIsProcessingRunning flag. If it is true, the process dumps some
> data into the shared memory and then exits. If not true, then the process
> starts up normally and then checks the shared memory for any updates. The
> class I use to wrap the boost::interprocess is below.
>
> Note: I needed the shared memory location to only be initialized the first
> time it was created so the only way I saw how to do it was through the src
> code was to use the initialization_func_t().
>
> This approach works fine on Win32 but on Linux, it doesn't work.
>
> Thanks in advance for any suggestions or hints.
In the code you've attached I see that you are using
managed_open_or_create_impl which is a implementation detail class. You
shouldn't use it, because this might change.
I understand that you wanted to execute an atomic functor when creating
the shared memory and that possibility is not in the public interface,
so I think this is an option I should add ASAP.
Now, looking the code I see that you try to erase the shared memory
every time in the CSharedMemory class:
// erase previous shared memory
boost::interprocess::shared_memory_object::remove( sName.c_str() );
This function works just like "std::remove" works with files and in UNIX
systems we can remove a file while it's been used. In UNIX we can remove
a shared memory segment while it's in use (well, actually, the
file/shared memory becomes "unaccessible", and although it's not
physically erased until processes attached to that removed segment end,
the name can be reused for new processes creating new segments.
This means that in Windows, if there is another process using the shared
memory, the remove call will not success and you will find that the
shared memory is initialized with data. In Unix, the shared memory will
be removed from the filesystem (that is, won't be found using
open/create) and although you try to create a shared memory with the
same name you will crate a new, fresh, uninitialized segment.
You can find more about UNIX behavior here:
http://www.opengroup.org/onlinepubs/009695399/functions/shm_unlink.html
This is really the same portability problem we have with files between
Windows and Unix and something I haven't solved yet. And it seems that
it's not an easy task, because we are talking about a resource that it's
shared between processes.
I'm afraid you will need to find a better way to know if a process is
already active... Maybe if you comment "remove" from the code you might
get what you want, but then you have a problem to know when to remove
the shared memory segment.
Regards,
Ion
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk