staggers@casbah.acns.nwu.edu (Ken Staggers) (06/06/91)
If anybody knows the answer to the problem below, please respond as soon as possible....thanks a plenty! The program is basically supposed to schedule running processes. My main() uses execution.o to fork and then exec separately compiled programs. execution.o issues a SIGSTOP so that main can schedule the processes (i.e. round robin scheduling). PCBs, semaphores, buffers, etc are all part of the shared memory that main() and the separately compiled (and executable) processes can access. main() and the processes use a library of system calls (syscall.o) to manipulate the shared memory. In my test run, main() creates the shared memory (shmget()), accesses it (shmget()), and then attaches it (shmat()). In then intializes all the structs in shared memory. This seems to work perfectly. Next, main() calls execution() in execution.o to fork and exec the separately compiled processes. It fills in a shared memory PCB for each using create() in syscall.o. In create(), its possible for one of the separately compiled processes to want to fork off its own process. Thus its going to have to access shared memory. Thus, in create() I issue an access and then attach. Well, I am getting an error in create(). Here's the code: /* Access the shared memory segment */ if ((shmid= shmget((key_t)42, 0, 0)) == -1) { printf( "CREATE: Cannot access shared memory segment\n"); exit(1); } /* Attach the shared memory segment */ shm= (struct sharedmemory *) shmat(shmid, (char *)0, 0); if (shm == (struct sharedmemory *) -1) { perror ("CREATE: Cannot attach the shared memory segment"); exit(1); } And here is the error: CREATE: Cannot attach the shared memory segment: Too many open files Yet, the only open files are main(), its header files, and the separately complied processes. I am attempting to schedule 4 processes in my system. So, I knocked that down to 1 process to see if that would help. Well, it did. Except after exec-ing the one process, it correctly returned to main() to continue running. I print out the queue, and the process has been successfully loaded into memory, and the PCB for it has been initialized. Then I issue a command to print out all of shared memory, to see if everything has been initialized properly. Then I get this error from memorydump() located in syscall.o: MEMORYDUMP: Cannot attach the shared memory segment: Too many open files So what am I doing wrong? Each of the 15 functions in syscall.o has code to access and attach. Is this wrong? I seemed to be able to access, but not attach. WHY? How does shared memory work? If you have ANY clues, please let me know as soon AS POSSIBLE. Since the program doesnt ever get to the part of removing shared memory, I do it myself in the shell. Below is more info on the program. Any help would be appreciated! --Ken staggers@casbah.acns.nwu.edu ------------------------------------------------------------------------ Shared Memory In globals.h: struct sharedmemory { struct PCB shpcb[MAXPCB]; /* All the PCBs available in system */ struct semaphore shsema[ MAXSEMAPHORES]; /* Semaphores available in system */ struct buffer shbuf[MAXBUFFERS]; /* Buffers available in system */ int Waitflag; /* Prevents process from being interrupted */ int Syspid; /* System pid counter */ struct PCB shq[ MAXQUEUES+MAXSEMAPHORES]; /* Head of queues */ int cpu; /* Pointer to PCB of running process */ }; struct sharedmemory *shm; /* Pointer to the shared memory */ Makefile: CFLAGS=-g p.out: queue.o syscall.o execution.o p1.o cc $(CFLAGS) -o p.out queue.o syscall.o execution.o p1.o queue.o: queue.c globals.h cc $(CFLAGS) -c queue.c syscall.o: syscall.c globals.h cc $(CFLAGS) -c syscall.c execution.o: execution.c globals.h cc $(CFLAGS) -c execution.c p1.o: p1.c queue.o globals.h cc $(CFLAGS) -c p1.c queue.o clean: rm *.o Shared Memory Initialization in main() [located in p1.c]: (Question: Is create and the access necessary) /* Create the shared memory segment */ if ((shmid= shmget((key_t)42, sizeof(struct sharedmemory), (IPC_CREAT | 0666))) == -1) { printf( "MAIN: Cannot create shared memory segment\n"); exit(1); } /* Access the shared memory segment */ if ((shmid= shmget((key_t)42, sizeof( struct sharedmemory), 0)) == -1) { printf( "MAIN: Cannot access shared memory segment\n"); exit(1); } /* Attach the shared memory segment */ shm= (struct sharedmemory *) shmat(shmid, (char *)0, 0); if (shm == (struct sharedmemory *) -1) { printf("MAIN: Cannot attach the shared memory segment\n"); exit(1); }
cpcahil@virtech.uucp (Conor P. Cahill) (06/06/91)
staggers@casbah.acns.nwu.edu (Ken Staggers) writes: >CREATE: Cannot attach the shared memory segment: Too many open files This is one of the reasons that perror is useless. "Too many open files" is the perror output for the errno EMFILE. Looking up shmat() (on the shmop(2) manual page) we see: [EMFILE] The number of shared memory segments attached to the calling process would exceed the system-imposed limit. Depending upon your OS configuration parameters, this should be configurable with a configuration parameter named SHMSEG (or something similar to it). -- Conor P. Cahill (703)430-9247 Virtual Technologies, Inc. uunet!virtech!cpcahil 46030 Manekin Plaza, Suite 160 Sterling, VA 22170
scl@unislc.uucp (Sean Landis) (06/08/91)
staggers@casbah.acns.nwu.edu (Ken Staggers) writes: >If anybody knows the answer to the problem below, please respond as soon >as possible....thanks a plenty! > ... Lot's deleted ... The man page for shmop(2) indicates: [EMFILE] The number of shared memory segments attached to the calling process would exceed the system-imposed limit. If you look in /usr/include/sys/errno.h: ... #define EMFILE 24 /* Too many open files */ ... Which is what drives perror(). Now what this really means is that your process is violating a tunable parameter called SHMSEG. The attachments are inherited by the forked process that tries to do one more and fails. Maybe you could do the attach after the exec()? I know that it removes some of the object-orientedness from your code, but processes in say UNIX, do have some startup code in them anyway. To get a picture of what is going on, use ipcs(1) command to get interprocess communication status. Hope this helps, Sean -- Sean C. Landis | {hpda, sun, uplherc}!unislc!scl Unisys Open Systems Group | unislc!scl@cs.utah.edu 320 North 2200 West B2D01 | (801) 594-3988 Salt Lake City, Utah 84116 | (801) 594-3827 Fax