Unix Programming - IPC Question

This is Interesting: Free IT Magazines  
Home > Archive > Unix Programming > July 2004 > IPC Question





You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

Author IPC Question
Manfred Schlager

2004-07-28, 6:19 pm

Hello, everyone. I have looked everywhere for a solution but haven't
found one. It seems my problem is not the typical one, so if someone
knows of a good solution, I'd really appreciate some pointers.

This is the scenario. I am writing a daemon in C, which as expected,
will be providing a service. This daemon has to prepare some
information needed in servicing its clients. It does this by reading
a number of files which are then scanned and a dynamic structure
created with information about the contents of the files.

It is desired, almost required, that the daemon starts servicing
(listening on a socket) its clients as soon as it is started. The
obvious solution is then to create a child process that takes care of
the job of scanning the files and creating the structure. At the end,
the child must return (in some way) the whole structure to the parent,
which will spawn servicing childs as needed.

In fact, during the creation of the structure, the parent should
already be able to read it. Yes, the parent can use incomplete
information when servicing the clients, it just affects the quality of
the service, but it does not prevent it from giving it. BTW, only the
child writes to the structure, the parent only reads from it, so there
is no need for exclusive access.

Not giving enough thought to the matter, I imagined that just creating
the root of the dynamic structure before forking the child process
would be enough for both to be able to see the structure. When in
fact, of course, the child is working on a copy of the root, and all
the pointers are to its own memory space, so the parent isn't really
aware of the work of the child.

I've been reading about shared memory, but it seems it is not what I
need either. For two compelling reasons: 1- There is no way to
calculate the size of the structure prior to shmget'ting the required
block (that's why I'm using a dynamic structure in the first place,
duh!) 2- Even if there was, since there is no way to do malloc's on
this block of memory because it is already allocated, it means that I
would have to memory-manage the block myself (yikes!).

In reality, if the original block of shared memory requested by the
parent was not enough to store the structure in the child, it cannot
grow, and if it was too big, it would mean wasting memory. Again,
that is why I am using a dynamic structure.

Pipes don't seem to be an option either, because of the sequential
nature of them, passing the whole structure (pointers coded in some
way), is far worse a problem than just having the server load the
structure by itself prior to servicing any client. Unless, that is, I
had some way of packing all the memory space of the child in a
sequential block and pipe it to the parent.

Keeping the child running and have the parent (and its siblings) talk
to it to request information stored in the structure seems a far more
reasonable solution, but it means having a server within a server, and
it doesn't seem very attractive. It does seem the best solution
though, because later on, when forking the servicing children, init
will need to copy the whole structure for each forked child (and it is
not small).

Sorry for the length of this briefing, but I am trying to cover enough
detail so that you can understand the problem.

Thanks for any suggestions/comments you may have.
Lev Walkin

2004-07-28, 6:19 pm

Manfred Schlager wrote:
>
> It is desired, almost required, that the daemon starts servicing
> (listening on a socket) its clients as soon as it is started. The
> obvious solution is then to create a child process that takes care of
> the job of scanning the files and creating the structure. At the end,
> the child must return (in some way) the whole structure to the parent,
> which will spawn servicing childs as needed.


The equally obvious solution is to spawn a thread, instead of creating
a child.

man pthread_create

Don't forget to use mutexes to protect the memory. In your case, it
is well may be that you can go without mutexes, but it would not work
on some hardware configurations (notably, Alpha+SMP) due to unpredictable
memory access serializations.

--
Lev Walkin
vlm@lionet.info
Manfred Schlager

2004-07-28, 6:19 pm

Lev Walkin <vlm@lionet.info> wrote in message news:<2mi14lFmd04qU1@uni-berlin.de>...
> The equally obvious solution is to spawn a thread, instead of creating
> a child.
>
> man pthread_create
>
> Don't forget to use mutexes to protect the memory. In your case, it
> is well may be that you can go without mutexes, but it would not work
> on some hardware configurations (notably, Alpha+SMP) due to unpredictable
> memory access serializations.


Thank you very much Lev, that's exactly the solution that I've come
across. Threads will still let me use the spawning (main) process'
memory space so that my structure is loaded right there by the thread.
Hadn't even crossed my mind when I wrote earlier ;-)

I am trying to decide if my servicing sockets will also be handled by
threads in order to avoid dynamic duplication of my whole structure;
it can easily reach 10-15MB or more in RAM, and it may be painful to
fork() children this big, hehe.

I gather that some implementations of fork(), particularly old
implementations of vfork() and more recently fork() under cygwin or
linux, create a duplicate of the parent memory space only when memory
on the child is to be written (copy-on-write). This may make it
easier and more straightforward to use fork() since I don't plan to
write, but since it is implementation dependent, I think I'll stick
with pthreads.

But regarding this... do you know if fork()'s copy-on-write will copy
the whole memory space or will it copy only the pages it needs for
writing?

Thanks for the tip about mutexes. I'll incorporate them.
Manfred Schlager

2004-07-28, 6:19 pm

To SHALANNA on a previous message:

What you are looking for in avoiding the "address already in use"
message is:

int yes=1;

if (setsockopt(listener, SOL_SOCKET, SO_REUSEADDR, &yes,
sizeof(int)) == -1) {
perror("setsockopt");
exit(1);
}

From: Beej's guide to network programming @
http://www-db.stanford.edu/~cho/pro...ng/network.html
Jens.Toerring@physik.fu-berlin.de

2004-07-28, 6:19 pm

Manfred Schlager <mschlager@go.com> wrote:
> I am trying to decide if my servicing sockets will also be handled by
> threads in order to avoid dynamic duplication of my whole structure;
> it can easily reach 10-15MB or more in RAM, and it may be painful to
> fork() children this big, hehe.


> I gather that some implementations of fork(), particularly old
> implementations of vfork() and more recently fork() under cygwin or
> linux, create a duplicate of the parent memory space only when memory
> on the child is to be written (copy-on-write). This may make it
> easier and more straightforward to use fork() since I don't plan to
> write, but since it is implementation dependent, I think I'll stick
> with pthreads.


I am not absolutely sure about this but I think that all modern Unices
are using copy-on-write on fork(). But I guess there are several
regulars here that will be able to tell you much more...

> But regarding this... do you know if fork()'s copy-on-write will copy
> the whole memory space or will it copy only the pages it needs for
> writing?


It only copies the pages that get really written to, otherwise it would
not make much sense anyway.
Regards, Jens
--
\ Jens Thoms Toerring ___ Jens.Toerring@physik.fu-berlin.de
\__________________________ http://www.toerring.de
Barry Margolin

2004-07-28, 6:19 pm

In article <2miucgFn43dcU1@uni-berlin.de>,
Jens.Toerring@physik.fu-berlin.de wrote:

> Manfred Schlager <mschlager@go.com> wrote:
>
>
> I am not absolutely sure about this but I think that all modern Unices
> are using copy-on-write on fork(). But I guess there are several
> regulars here that will be able to tell you much more...


Just about every Unix that has virtual memory does it this way. It's
trivial to implement, so it's pretty much a no-brainer.

--
Barry Margolin, barmar@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
Manfred Schlager

2004-07-28, 6:19 pm

Thanks, Jens, Barry and Lev for your posts!
Sponsored Links






Free braindumps | Software forum | Database administration forum

Copyright 2003 - 2008 webservertalk.com