dan@rna.UUCP (Dan Ts'o) (09/23/86)
x Has anyone used the System V-style shared memory facility in Ultrix-32m (Microvax II), especially in double-buffered I/O operations ? For example, the continuous DMA'ing in of data while DMA'ing out to magtape. one process DMA's into shared memory and then signals the second process for it to DMA's to magtape while the first process fills the second buffer. Can someone mail me a simple C program in which to processes communicate using these System V shared memory calls ? Please educate a poor 4.XBSD user to the wonders of shared memory. Thanks. Cheers, Dan Ts'o Dept. Neurobiology Rockefeller Univ. 1230 York Ave. NY, NY 10021 212-570-7671 ...cmcl2!rna!dan rna!dan@cmcl2.arpa
dan@rna.UUCP (Dan Ts'o) (09/24/86)
In article <547@rna.UUCP> dan@rna.UUCP (Dan Ts'o) writes: >x > Has anyone used the System V-style shared memory facility in >Ultrix-32m (Microvax II), especially in double-buffered I/O operations ? >For example, the continuous DMA'ing in of data while DMA'ing out to >magtape. one process DMA's into shared memory and then signals the second >process for it to DMA's to magtape while the first process fills the second >buffer. > > Can someone mail me a simple C program in which to processes communicate >using these System V shared memory calls ? Please educate a poor 4.XBSD user >to the wonders of shared memory. Thanks. Well, here I am answering my own question - sort of. I came up with a simple shm*() program below which seems to work. However I'm still confused about a number of the facilities of shm*(). For example, what role does "key" play ? How do I pass the shared memory segment to non-related process ? Perhaps what I should do (it doesn't seem to be documented) is stick a non zero long in key and require that the communicating process shmget() with the same key. Right ? Is the shared memory segment automatically destroyed if no process has it "open" ? What constitutes the "open" - the shmget() or the shmat() ? If it isn't destroyed then probably the shmat() is the "open" and the shmget() is a lookup/create. Sorry if these questions are trivial but the documentation in Ultrix seems scarce. I would still like to know if there are problems with using these operations for the style of I/O mentioned above. Cheers, Dan Ts'o Dept. Neurobiology Rockefeller Univ. 1230 York Ave. NY, NY 10021 212-570-7671 ...cmcl2!rna!dan rna!dan@cmcl2.arpa #include <sys/types.h> #include <sys/ipc.h> #include <sys/shm.h> #include <stdio.h> #define NSHM 10 char *shmat(); main() { key_t key; int size, shmflg; int shmid; int pid; register char *p; register int *v, i; size = NSHM * (sizeof *v); shmflg = IPC_CREAT + 0666; key = IPC_PRIVATE; shmid = shmget(key, size, shmflg); if (shmid < 0) { fprintf(stderr, "%d: Bad shmget(), ", shmid); perror(""); exit(1); } pid = fork(); if (pid == -1) { perror("Bad fork()"); exit(1); } shmflg = SHM_RND; p = shmat(shmid, (char *)0, shmflg); if (p == (char *)-1) { perror("Bad shmat()"); exit(1); } v = (int *)p; if (pid == 0) { for (i = 0; i < NSHM; i++) printf("%d ", v[i]); printf("\n"); sleep(10); for (i = 0; i < NSHM; i++) printf("%d ", v[i]); printf("\n"); exit(0); } sleep(3); for (i = 0; i < NSHM; i++) v[i] = i*i; sleep(10); exit(0); }
jrw@hropus.UUCP (Jim Webb) (09/25/86)
> > Has anyone used the System V-style shared memory facility in > >Ultrix-32m (Microvax II) Since Ultrix-32m is "supposedly" SV compatible, I will comment on how "real" SV shared memory works. > about a number of the facilities of shm*(). For example, what role does "key" > play ? The "key" is used to generate a unique, yet reproducable, shared memory identifier for use by the current or any other process. One way is to use ftok(). This function is in SV, so I am hoping it is in Ultrix... It takes two arguments and returns a key: ftok(file,proj) key=ftok("/unix",'x'); char *file; char proj; You pass it a file name and any character you choose and it diddles with the info in the inode of the file and combines it with the character and returns a key. Just choose a file that doesn't change often. > How do I pass the shared memory segment to non-related process ? You just use shmget() to get the shmid and then pass it to shmat(). For example, you could do: key=ftok("/unix",'x'); shmid=shmget(key,SIZE,FLAGS); shmat(shmid,ADDR,FLAGS); or even: shmat(shmget(ftok("/unix",'x'),SIZE,FLAGS),ADDR,FLAGS); :-) > Perhaps what I should do (it doesn't seem to be documented) is stick a non > zero long in key and require that the communicating process shmget() with the > same key. Right ? You got it right! I guess the Ultrix docs are worse than the SV ones :-) > Is the shared memory segment automatically destroyed if no process has > it "open" ? No, for several reasons. For example, a program might want to use a shared memory segment for initialization data instead of a file, or, a program might store info in a segment, exit, and come back later to process the info. However, there are two FLAGs (at least on my vax) SHM_CLEAR and SHM_DEST that clear the segment on the next attach and destroy it when no one is attached to it, respectively. cat /usr/include/sys/shm.h to see if they are on you machine as well. > What constitutes the "open" - the shmget() or the shmat() ? If it > isn't destroyed then probably the shmat() is the "open" and the shmget() is > a lookup/create. There really is no "open." shmget() creates an identifier in the kernel. When you shmat() a segment, you utilize the resource, eg memory. -- Jim Webb "Out of phase--get help" ...!ihnp4!hropus!jrw
dpw@rayssd.UUCP (Darryl P. Wagoner) (09/25/86)
> However I'm still confused > about a number of the facilities of shm*(). For example, what role does "key" > play ? How do I pass the shared memory segment to non-related process ? > Perhaps what I should do (it doesn't seem to be documented) is stick a non > zero long in key and require that the communicating process shmget() with the > same key. Right ? Let me start by saying that I am no expert on shared memory. STDIPC(3C) is the System V standard for IPC. The only routine that is currently in the stdipc package is ftok, which when called and passed a file name and an "id", it returns a unique key in key_t (long int) format. The key is based on the id (8 bits) minor device name (8 bits) and the inode number (16 bits). By different processes knowing what file name and "id" that was passed to ftok, they can get the same key and therefore access the same shared memory. The trick is to insure that all IPC programs adhere to this standard. > Is the shared memory segment automatically destroyed if no process has > it "open" ? What constitutes the "open" - the shmget() or the shmat() ? If it > isn't destroyed then probably the shmat() is the "open" and the shmget() is > a lookup/create. No, once shmget is called, the shared memory identifier will remain until one of two things happen. First shmctl is called to remove it. Second the system is rebooted. This is what I believe, but I could very well be wrong. The shmget call creates an entry for the key in a shared memory table (link list I would guess). That contains the shared memory identifier, the key, a pointer to the shared memory and the rest of the shared memory information. Shmat() attaches a segment to the shared memory identifier. The question that I have is, if you call shmat with the address of a segment in your program, will that segment dry up and blow away when you program exited. I know the shared memory identifier will remain. > shmflg = IPC_CREAT + 0666; > key = IPC_PRIVATE; key = ftok("/usr/bin/lint",'a'); /* if the file is change (as in remove then recreated) it will change the key that is returned */ Damn it Jim, I am a programmer, not a Englist Major Darryl Wagoner Raytheon Co.; Portsmouth RI; (401)-847-8000 x4089 best path {allegra|gatech|mirror|raybed2} ---------\ next best {linus|ihnp4|pyrbos} ---------------------->!rayssd!dpw if all else fails {brunix|cci632} -------------------------/ -- Darryl Wagoner Raytheon Co.; Portsmouth RI; (401)-847-8000 x4089 best path {allegra|gatech|mirror|raybed2} ---------\ next best {linus|ihnp4|pyrbos} ---------------------->!rayssd!dpw if all else fails {brunix|cci632} -------------------------/
rml@hpfcdc.HP.COM (Bob Lenk) (09/26/86)
> > Is the shared memory segment automatically destroyed if no process has > > it "open" ? > > However, there are two FLAGs (at least on my vax) SHM_CLEAR and SHM_DEST > that clear the segment on the next attach and destroy it when no one is > attached to it, respectively. cat /usr/include/sys/shm.h to see if they > are on you machine as well. These flags are in <sys/shm.h> on System V implementations, but they are not documented or accessable to the user (eg. through shmget or shmctl). The only way to get something like what was requested is to explicitly remove the segement (with shmctl (,IPC_RMID,)); this must be done after the last attach (as subsequent attaches will fail). What the implementation does, if any processes have the segement attached at the time of the IPC_RMID, is to set the SHM_DEST bit. On the last detach, the segment is actually destroyed. Bob Lenk {ihnp4, hplabs}!hpfcla!rml
dan@rna.UUCP (Dan Ts'o) (09/27/86)
In article <168@rayssd.UUCP> dpw@rayssd.UUCP (Darryl P. Wagoner) writes: >System V standard for IPC. The only routine that is currently in the stdipc >package is ftok, which when called and passed a file name and an "id", it >returns a unique key in key_t (long int) format. The key is based on the >id (8 bits) minor device name (8 bits) and the inode number (16 bits). By >different processes knowing what file name and "id" that was passed to ftok, >they can get the same key and therefore access the same shared memory. The >trick is to insure that all IPC programs adhere to this standard. Since ftok() doesn't make use of the major device number, I would think that one could get screwed. Also it appears that ftok() returns -1 if it can't stat() the filename which is reasonable except that the user program had better check for it before blindly giving it to sh*() otherwise many segments will have -1 as the key. ftok() should probably be smarted than this if it is truly going to be the standard convention for creating key_t's. Thanks for all the sh*() hints. In particular, thanks for reminding me about ftok(). The reason that I had "forgotten" about ftok() is that it doesn't appears to be in the older System V manuals and Ultrix-32 has stuck ftok(3C) in the C (compatibility) section of the manual without any cross- reference.