Question
Here's what I want your code to do: The parent process (only process at the start, right?) should get some new memory which will be
Here's what I want your code to do:
The parent process (only process at the start, right?) should get some new memory which will be shared with a child process that it (the parent) will create later. No magic here: In CS125 or some other C programming course, you've used the system service call malloc to get new memory before. Now you just need to learn to use a more complicated set of system service calls to get new memory that can be shared between processes (malloc'd memory is on the heap, remember, so it can't be shared between processes). All we need here is enough memory for an integer (later we'll try something more complicated ;-)
First use shmget to tell the OS to assign you a segment of memory (to be shared among multiple processes) big enough to hold an integer; have your program print out the shared memory identifier it receives from shmget. Shared memory identifier? Just an arbitrary number that identifies some chunk of shared memory, much the way a process identifier identifies a process. A shared memory identifier is not a segment number or address. Why not? Well, for one thing, shared memory can be shared among processes running very different programs; there's no way to insure that they can all use the same segment number for it. Although a shared segment is indeed a segment, the segment ID, which is common among all processes wanting to use this segment, is not a segment number in the MMU/address binding sense of the term, where different processes could use a different segment number to bind/attach to the same physical address. The point of the shared memory identifier is to allow mutliple processes to have a common name to refer to a region of memory that may be (generally will be) at different logical adrresses in the different processes --- hey guys, how about we all communicate via shared memory ID #37 ?
Next, use shmat to get the address for your process to use to refer to the shared memory (this step is known as "attaching" the shared memory to your process). shmat adds an entry to the calling process's segment table, often/usually assigning a different segment number in each process (since the processes often/usually have a different number of segments), but makes the base physical address of the new segement the same in the segment tables of all processes attached to this shared memory. But the protection bits in each process's segment table could be different if some processes were only to be allowed read access while others could write as well as read.
The parent process should set the new (shareable) integer to 0 and then spawn a child process (and make sure to do this in the correct order --- first set the new, shared memory to 0, then spawn a child).
In the parent (after the spawn):
Ask the user for a (non-zero) value to store in the new integer.
Once that has been accomplished, the parent should spin on that integer until it becomes zero again.
After exiting from the spin, the parent should print a message saying that the shared integer is now 0 again (thus confirming successful two way communications via shared memory).
Detach the shared memory from the process's address space using shmdt
Return the shared memory segment to the memory manager using shmctl (roughly analogous to the "free" function used to return malloc'd memory).
Print out an "all done" message.
In the child (after the spawn):
Print some sort of "I'm alive" message
Spin on the new integer until it becomes non-zero. Note: You caught a small break here; when a child process is spawned, it inherits any shared memory attachments of its parent; otherwise the child too would have to call shmat (as the parent did) before it could "see" the shared memory. How would the child know what shared memory segment identifier to attach to? In Unix/Linux, that variable would be "passed" to the child when the parent's address space was copied over during the spawn; exactly the same way your child processes figured out which child they were in homework #1 (in Windows it would be more difficult). Anyway, because a child inherits its parent's attachments (otherwise how could it's logical address space be a copy of its parent's?), it doesn't need to do a shmat itself, provided of course, that the parent attached before spawning the child.
After exiting from the spin (because the parent eventually puts a user-supplied non-zero value in the shared integer), print out the value just received from its parent and then re-set the shared integer back to 0 (so the parent can eventually stop spinning and finish up).
That's it for the child. You don't need to detach the child from the shared memory (the OS does that when a process terminates, which the child will do when it runs out of code to execute after step 4c, above) and you certainly don't want the child to destroy the shared memory segment since the parent may still need it to finish its printout. When the parent is done printing out the value the child re-zeroed, it (the parent) removes/destroys the (no longer shared) shared memory segment in step 3e, above it better; shared memory segments are persistent, they are allowed to continue to exist after their creating process terminates (as a means, perhaps, of allowing interprocess communication from beyond the grave). The first few times I myself tried this sort of programming I eventually discovered that I had left some previously shared segments around from several years earlier. Now I clean up each year over Xmas break, just in case you folks don't do your own cleanup properly (see Note D, below). Here (this homework) there's no need to leave that shared memory segment lying around "orphaned" after the parent terminates; so we'll have the parent return it (the previously shared segment) to the OS before it (the parent) terminates.
Here's what a sample output of mine looks like (user input in bold);
Parent: Successfully created shared memory segment with shared memory ID # (not segment #) of 12714047 (This shared memory doesn't get a true segment number until this process adds it to its segment table by attaching to it.)
Parent: My pid is 29355; now spawning a child after setting the shared integer to 0
Child: My pid is 29356, my parent's pid is 29355; the shared integer value is currently 0; I'll spin until it's not 0
Parent: My pid is 29355, spawned a child with pid of 29356; please enter an integer to be stored in shared memory: 48
Child: The value in the shared integer is now 48; I'll set it back to 0
Parent: the child has re-zeroed our shared integer
Child process terminating
Parent: Child terminated; parent successfully removed segment whose ID # was 12714047
Step by Step Solution
There are 3 Steps involved in it
Step: 1
Get Instant Access to Expert-Tailored Solutions
See step-by-step solutions with expert insights and AI powered tools for academic success
Step: 2
Step: 3
Ace Your Homework with AI
Get the answers you need in no time with our AI-driven, step-by-step assistance
Get Started