Hi,

I have a simple application under way that is invoked multiple times with different command line arguments. Each invocation accesses a common piece of shared memory for a different task. Display to monitor or file; Mysql interface; query data from machines and post to a structure in shared memory; (beginning to really like those semicolons) watch for specific abberant machine behaviour and send a corrective command. One arguement posts a flag that tells them all to die.

This all works

It works well enough that even if all the delays and watch-outs are inhibited in the code, half a dozen processes reading and writing to the same memory have run flat out for 48 hours without logged conflicts or memory leakage

The problem is that after any process times out and quits or is instructed to shut down by a command from a terminal, no further processes are able to attach to the memory. The next invocation creates and attaches another region of shared memory Subsequent invocations attach to second set of processes instead of the first, which still may still be active.

IPCS and top show predictable data. The number of attached processes increments and decremnts as it should. The creation of a new set of processes using a new piece of shared memory show up as expected.

One header of one column of the ipcs display looks as if should list some version of KEY but that part of the display is all 0s in my version. Anyone know about this?

There is something I do not know about accessing and releasing shared memory. The procedure is right out of the book:

Code:
      int shmid = shmget((key_t)mykey, bulk(),0666 |IPC_CREAT);
 
   if (shmid == -1) {
      fprintf(stderr, "shmget failed\n");
      goto shut_down_relay;
    	}

    shared_memory = shmat(shmid, (void *)0, 0);

    if (shared_memory == (void *)-1) {
        fprintf(stderr, "shmat failed\n");
        exit(EXIT_FAILURE);
    }

    printf("\nMemory attached at %X  shmid = %d\n", (int)shared_memory, shmid);
    
    .
    .
    .
    .
				
   if (shmdt(shared_memory) == -1) 

        fprintf(stderr, "shmdt failed\n");
  		else printf("detached memory");			
			printf( "shmid %d", shmid);

    
    if (shmctl(shmid, IPC_RMID, 0) == -1) 

        fprintf(stderr, "shmctl(IPC_RMID) failed\n");
		else printf(" released memory ");
The values of shared_memory and schmid are not modified anywhere in the code. Test print statments show that they are the same at exit as at acquisition.

The execution and development platform is a modest Ubuntu Linux machine with plenty of memory and processing capacity. The processes are now run from multiple Gnome terminal windows.

All routines exit through the same piece of code. There is only one exit() in the entire program. It compiles cleanly with -Wall


RATS! I just solved this well documented stupid repeateable problem, but the solution is informative so it gets posted.

After reading the pages for shmctl() a dozen times I realized it destroys the memory segment on every call, not a matter of "last one out turns off the lights". Got rid of it in the shut down code, just shmdt() now, and every thing is perfect. In this application it is a non_issue to leave 11206 bytes of memory stranded. The only things the computer does is perform these contol and logging functions. If the memory stays allocated to KEY and it is always the same KEY, the memory will still be there when the processes come back, and, as kind of an undependable bonus, will be filled with generic process data that may not cause any drastic process jerks before new data accumulates.

The clue was that as I was testing this question for repeatability, I realized that processes that exited with a ^c did not cause the problem.

Is a day wasted on education really wasted? I learn, but there is blood on the walls and ceiling.

I hope this helps someone avoid a problem.

J Carroll