蓝森林首页 | 返回主页 | 本站地图 | 站内搜索 | 联系信箱 |
 您目前的位置:首页 > 自由软件 > 技术交流 > 应用编程


    

蓝森林 http://www.lslnet.com 2006年6月6日 10:18


请教一个共享内存问题

[code]
#include "stdio.h"
#include "sys/types.h"
#include "errno.h"
#include "sys/shm.h"
#include "sys/ipc.h"
#include "string.h"
#include "sys/sem.h"
#include "unistd.h"


#define K    1024
#define SHMSIZE K*4*16
#define SHMFLAGS IPC_CREAT|0644

struct mystruct{
  int user_name;
  struct mystruct * next;
};

typedef struct mystruct * MYSTRUCT;


int shmid;
cleanup(){
   shmctl(shmid,IPC_RMID,0);
   exit(0);
}


main(){
  char * addr1;
  int i;
  pid_t pid;

  MYSTRUCT user_struct;
  MYSTRUCT p,q,r;


  for(i=0;i<20;i++)
   signal(i,cleanup);

  shmid = shmget(IPC_PRIVATE,SHMSIZE,SHMFLAGS);

  if(shmid == -1){
   printf("shm create failed!\n");

  }else{
   printf("shared memory segment ID = %d\n",shmid);
   addr1 = shmat(shmid,0,0);

if((pid=fork())==0){
        user_struct = (MYSTRUCT)addr1;
        r = user_struct;
        i=0;

  while(i<100){
/*      q=(MYSTRUCT)malloc(sizeof(struct mystruct));
*/
      q=user_struct++;
      q->;user_name = i;
      q->;next=NULL;
      r->;next=q;
      r=r->;next;
      i++;
   
/*      sleep(1);     */
/*
此处如果不加sleep(1),则一切正常,如果加上sleep(1),
那么仅仅打印链表的第一二个节点的地址,等很久以后,
可能会打印以后节点的地址,是不是由于进程不同步的问题?
*/


  }      
}
   if((pid=fork())==0){
   while(1){   
      p= (MYSTRUCT)addr1;
           i=0;   
      while(p!=NULL){
         printf("0x%x\n",p);   
         p=p->;next;
         i++;
      }
      sleep(2);
   }
   }
   shmdt(addr1);

   shmctl(shmid,IPC_RMID,0);
  }   

}[/code]

请教一个共享内存问题

代码看着觉得有点混乱。你本来想要开几个进程的?实际上开了三个。此外你用的结构又象数组,又象链表........  :em06:

重复打印链表第一项的原因是:

[code]

......
        r = user_struct;
......
        while(i<100){
                q=user_struct++;
                q->;user_name = i;
                q->;next=NULL;
                r->;next=q;        <== when i==0, r is user_struct, is q, so in effect, q->;next = q, a ring.
                r=r->;next;
                i++;
                // sleep (1);
        }
[/code]


在 i = 0 的时候,由于代码上的失误,链表变成了只包含一项的环。

当你把 sleep(1) 打开的时候,这个环要保持近一秒。在这一秒里,第一个进程 fork 出的第二个进程中的一段代码:

[code]
        while(p!=NULL){
                printf("0x%x\n",p);   
                p=p->;next;
                i++;
        ......
[/code]

会陷在环中,不断打印出链表的首地址。



Copyright © 1999-2000 LSLNET.COM. All rights reserved. 蓝森林网站 版权所有。 E-mail : webmaster@lslnet.com