🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.unix.programmer
Article #3636

Re: Problem using fork, shared memory

#3636
From: Xiaofeng Cheng
Date: Mon, 02 Feb 1998 00:00
213 lines
7025 bytes
Don't see your point, i.e. I won't believe your recursive structure will
work here by
princepal.

If your program is working, it is out of PURE LUCK.  i.e. after fork, the
address is
same, and the shm is still attached.  Anyway, you did not even use the
struct member "s" in child process.  the
member "_string" is essentially the same value as "pint", the starting point
of shared
memory, which means it is not a NORMAL variable, IT DOESN"T STORE ANYTHING!
i.e, you cannot write:  x->_string="hello".  In this sense, it is not even a
variable.

Out of curiousity,  I commented out your "creapoint" everywhere, and the
output
is the same, i.e. "creapoint" did not do anything.  I know 3 conditions will
crash this
program:
1) In child process, attach to a different base address.  just like you did
(I believe it is a coincidence,
because you forgot to detach the original segment).
2) dettach the original shared memory (you did not do)
3) In child process, try to use member "s", instead of member "_string".
(you did not do)

Try test it.  I commented some of your code.  Basic idea: fork can confuse
you.  First you
see it working.  But when you dynamically allocates memory, fork+shm will
kill you.

If only do 1) and 2) the result is same.  Because "_string" is playing an
important role.
When you combine 1),2) and 3).  You will see what I mean.

I commented some of the code.
I will be happy to see my above comments are wrong.   Tell me if you really
have some
clever workaround.
Xiaofeng Cheng



William Warner wrote in message <34CE9074.6262@airone.claircom.com>...
>> Then you can't access that memory from anothr process. If you need to
access
>> the contents from another process you'll need to copy them into the
shared
>> memory.
>
>I was hoping for clever approaches for making shared memory
>emulate memory in the free store. I have inherited libraries
>that create pointers and rely on pointers. The libraries provide
>functions that operate on recursive data structures. I had do
>figure out some way of making my shared memory look like it had
>pointers!
>
>I finally succeeded. Below is a very small program that that
>covers all the issues I was dealing with.I had hoped for
>something a little more elegant, but it's a start.
>
>To make pointers work in shared memory, one must first allocate
>shared memory for storage, along with storage for the pointer
>itself. I did this by creating a structure (struct tst) which
>contains the necessary storage. Second, one must redefine
>pointers after forking and returning. I did this with a
>procedure creapoint().
>
>Aknowledgment to Steven Hayes, whose shm1.c
><http://www.cs.rmit.edu.au/~steveh/tns/solaris/node68.html> was
>a starting point for this example.
>
>Also, thanks to all who replied by posting and by e-mail.
>
> ww
>
>#include <stdio.h>
>#include <signal.h>
>#include <unistd.h>
>#include <sys/types.h>
>#include <sys/ipc.h>
>#include <sys/shm.h>
>#define  SHMKEY 75
>#define  K      1024
>int shmid;
>
>struct tst {
>  char _string[10];
>  char *s;
>};
>
>cleanup()
>{
>  shmctl(shmid, IPC_RMID, 0);
>  exit(0);
>}
>
>void creapoint(array)
>struct tst* array;
>{
>  array->s = &array->_string;
>}
>
>main()
>{
>  int i, j, working, completed = 0;
>  struct tst* pint;
>  char *addr, *addr1, *addr2;
>
>  shmid = shmget(SHMKEY, 128 * K, 0777|IPC_CREAT);
>  if(shmid == -1) {
>    perror("could not get key to shared memory");
>    exit(1);
>  }
>  addr1 = (char *) shmat(shmid, 0, 0);
>  addr2 = (char *) shmat(shmid, 0, SHM_RDONLY);
>  printf("addr1 0x%x addr2 0x%x\n", addr1, addr2);
>  pint = (struct tst*) addr1;
>
>  for (i = 0; i < 16; ++i) {
>    bcopy("012345678", &pint->_string, 10);
>    pint->s = &pint->_string;
>    ++pint;
>  }
>
>  pint = (struct tst *) addr2;
>  for (i = 0; i < 16; ++i) {
>    printf("index %2d, _string %12s, s %12s\n", i, pint->_string, pint->s);
>    ++pint;
>  }
>  pint = (struct tst *) addr2;
>  working = 1;
>  while(working) {
>    for (i = 0; i < 16; ++i) {
>      if(strcmp(pint[i]._string, "done")) {
> myproc(i);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
I will call it by:
    myproc(i, addr1);  /* to detach addr1 in child process */

>      } else {
> ++completed;
>      }
>    }
>    if(completed == 16) {
>      working = 0;
>    } else {
>      sleep(1);
>    }
>  }
>  pint = (struct tst*) addr1;
>  for (i = 0; i < 16; ++i) {
>    creapoint(pint++);
>    /*
>     * same as creapoint(&pint[i]);
>     */
>  }
>  pint = (struct tst*) addr2;
>  for (i = 0; i < 16; ++i) {
>    printf("index %2d, _string %10s, s %10s\n", i, pint->_string, pint->s);
>    ++pint;
>  }
>  cleanup();
>  exit(0);
>}
>
>void myproc(i)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
I will declare as:
 void myproc(int i, char* add)
>int i;
>{
>  char* addr;
>  struct tst*  pint;
>  pid_t pid;
>
>  if((pid = fork()) < 0) {
>    perror("fork failed");
>    _exit(1);
>  } else if (pid == 0) { /* child */
>
>    pint = (struct tst*) shmat(shmid, 0, 0);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Ok, you attached again. now lets detach the original
    shmdt(add);  /*  I sware, "add" is different from "pint", so do not
worry that pint is being detached */

>    if(pint == (struct tst*) -1) {
>      perror("could not attach to shared memory in forked process");
>      fprintf(stderr, "fork %d: shmid = %d\n", i, shmid);
>      _exit(1);
>    }
>    printf("Forked... Writing\n");
>/*     pint += i; */
>    strcpy(pint[i]._string, "done");
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
If you keep this statement, everything will work fine.
But if you try this and remove the previous one:
    strcpy(pint[i].s, "done");
/* BLAH, BLAH,  run your program and see what happens */

>    shmdt(addr);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
what is this?  you mean: shmdt(pint) ???

>    _exit(0);
>  }
>}
>
>
>--
>   William Warner
Technical Details
Message-ID: <6b5rhf$75g@camel20.mindspring.com>
Path: arc1-ca.pugleaf.net!unknown!not-for-mail
References: <34C9045E.1C95@airone.claircom.com> <34C93501.47C@airone.claircom.com> <6abf4q$4np@camel12.mindspring.com> <34CBD718.4FB7@airone.claircom.com> <885913234snz@genesis.demon.co.uk> <34CE9074.6262@airone.claircom.com>

Show Full Headers
Complete Article Headers
X-Google-Language: ENGLISH,ASCII-7-bit
X-Google-Thread: 11318c,e74399effbe2897f
X-Google-Attributes: gid11318c,public
X-Google-Thread: fc89c,e74399effbe2897f
X-Google-Attributes: gidfc89c,public
X-Google-Thread: 11035d,8f3351c6e065c62a
X-Google-Attributes: gid11035d,public
From: "Xiaofeng Cheng" <chengxi@gestalt-tech.com>
Subject: Re: Problem using fork, shared memory
Date: 1998/02/02
Message-ID: <6b5rhf$75g@camel20.mindspring.com>
X-Deja-AN: 321529719
References: <34C9045E.1C95@airone.claircom.com> <34C93501.47C@airone.claircom.com> <6abf4q$4np@camel12.mindspring.com> <34CBD718.4FB7@airone.claircom.com> <885913234snz@genesis.demon.co.uk> <34CE9074.6262@airone.claircom.com>
X-Server-Date: 3 Feb 1998 01:22:55 GMT
Distribution: inet
X-MimeOLE: Produced By Microsoft MimeOLE V4.72.2106.4
Organization: Gestalt Technologies Inc.
Newsgroups: comp.unix.programmer,comp.unix.solaris,comp.unix.programmer,gnu.gcc.help