Xref: utzoo comp.unix.xenix:1691 comp.unix.microport:259 comp.unix.wizards:7090 Path: utzoo!mnetor!uunet!steinmetz!davidsen From: davidsen@steinmetz.steinmetz.UUCP (William E. Davidsen Jr) Newsgroups: comp.unix.xenix,comp.unix.microport,comp.unix.wizards Subject: Re: IPC facilities (shared memory) Message-ID: <9947@steinmetz.steinmetz.UUCP> Date: 15 Mar 88 20:38:04 GMT References: <335@mancol.UUCP> <9844@steinmetz.steinmetz.UUCP> <150@marob.MASA.COM> Reply-To: davidsen@crdos1.UUCP (bill davidsen) Organization: General Electric CRD, Schenectady, NY Lines: 148 Keywords: IPC, shared memory, semaphores Summary: I still think I'm right I added unix.wizards to this, because this is the type of esoteric subject which brings clarifying information from that group. In article <150@marob.MASA.COM> samperi@marob.UUCP (Dominick Samperi) writes: | In article <9844@steinmetz.steinmetz.UUCP> Bill Davidsen writes: | > | > SysV shared memory segments are inherited by the child, like any other | >open handle. If you open the segment and then do a fork, the child has | >access. If you fork and then open, the child will have to open, too. | | Perhaps you are talking about the Xenix-style IPC facilities here See original posting... I said SysV and meant it. | (sgget, etc.) which I no nothing about. When the SysV-style facilities | are used a forked child process must attach a shared memory segment Not true! | (using the segment identifier that the parent got when it created the | segment) before it can use it. That segment id is already in use by the child. What I said is that the child gets it from the parent. That's what happens. | This works fine on an AT&T 3b2 and under | Microport's System V/AT, but the child gets an "invalid argument" error | under SCO Xenix (same source code used on each system, compiled with | -Mle in the Xenix environment). I've learned something... I didn't know you could reopen a segment. Does it get a new address? | -- | Dominick Samperi, Manhattan College, NYC | manhat!samperi@NYU.EDU ihnp4!rutgers!nyu.edu!manhat!samperi | philabs!cmcl2!manhat!samperi ihnp4!rutgers!hombre!samperi | (^ that's an ell) uunet!swlabs!mancol!samperi When a child is forked it keeps open file, segments, and semiphores (as far as I can tell). Here is a program which assumes that what I say is correct. It runs on Xenix (286/386), 3B2-200, and the person who tested it for me says it runs on V/AT. It runs on Sun in SysV compile mode, but crashes at the end. I stand by my original statement in light of the evidence. Here's what it does: Process opens a shared segment Process opens a semiphore group Process forks Parent Child ================================================================ waits semiphore prints shared mem value sends semiphore waits semiphore changes shared mem value sends semiphore waits for child to die prints shared mem value (should be changed) terminates releases semiphore releases shared mem ================================================================ #include #include #include #include #include #define xerror(m) if (errno) perror(m) extern int errno; main() { int key; /* shared memory key */ int far *ptr; /* address of shared memory */ int semi; /* semiphore key */ /* semiphore control buffers */ static struct sembuf set1 = {0,1,0}, /* set flag 1 */ wait1 = {0, -1, 0}, /* wait for flag 1 */ set2 = {1,1,0}, /* set flag 2 */ wait2 = {1,-1,0}; /* wait for flag 2 */ int pid; /* PID of child process */ /* get a portion of shared memory */ key = shmget((key_t)IPC_PRIVATE, 5*1024, 0700); printf("Parent attaching key %d\n", key); ptr = shmat(key, (char far *)NULL, 0); printf("Parent buffer at %08lx\n", ptr); if (errno) { perror("memory attach"); shmctl(key, IPC_RMID, (char far *)0); exit(1); } ptr[10] = 0x8228; if (key >= 0) { /* the shared memory is created, create a semiphore set */ semi = semget(IPC_PRIVATE, 2, 0700); printf("Parent semi id %d\n", semi); if (pid = fork()) { /* wait for the first signal */ semop(semi, &wait1, 1); ptr[10] = 0x1234; /* flag that the value has changed and wait for reread */ semop(semi, &set2, 1); semop(semi, &wait1, 1); while (wait() != pid); } else { printf(" Child buffer at %08lx\n", ptr); printf(" Child semi %d\n", semi); printf("Val: %04x\n", ptr[10]); /* flag that the child is ready */ semop(semi, &set1, 1); /* wait for the value to change */ semop(semi, &wait2, 1); printf("Val: %04x\n", ptr[10]); semop(semi, &set1, 1); #if 0 /* now release the semiphore */ semctl(semi, 0, IPC_RMID, 0); xerror("Child semi release"); #endif exit(0); } /* cleanup the semiphore and shared memory */ errno = 0; semctl(semi, 0, IPC_RMID, 0); xerror("Semi release"); shmdt(ptr); shmctl(key, IPC_RMID, NULL); xerror("Shared memory release"); } } -- bill davidsen (wedu@ge-crd.arpa) {uunet | philabs | seismo}!steinmetz!crdos1!davidsen "Stupidity, like virtue, is its own reward" -me