2012-08-30 252 views
1

我創建了一個程序,它顯示了作爲參數傳遞的shmid(共享內存ID)共享內存段信息。C - 獲取IPC共享內存信息

將數據與命令ipcs返回的數據進行比較,顯然我的程序顯示了一些有關共享內存段的錯誤信息。

你能幫我理解爲什麼嗎?

謝謝。

#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <sys/types.h> 
#include <sys/stat.h> 
#include <fcntl.h> 
#include <sys/ipc.h> 
#include <sys/shm.h> 
#include <time.h> 
#include <errno.h> 

struct shmem_info { 
    int id; 
    struct shmid_ds data; 
}; 

int *allocate_int(int n) { 
    int *mem; 

    if((mem=malloc(n*sizeof(int)))==NULL) { 
     perror("malloc"); 
     exit(EXIT_FAILURE); 
    } 

    return mem; 
} 

struct shmem_info *allocate_shminfo(int n) { 
    struct shmem_info *mem; 

    if((mem=malloc(n*sizeof(struct shmem_info)))==NULL) { 
     perror("malloc"); 
     exit(EXIT_FAILURE); 
    } 

    return mem; 
} 

int parse_int(char *str) { 
    int n; 

    n=atoi(str); 

    return n; 
} 

int open_fileRW(char *path) { 
    int fd; 

    if((fd=open(path,O_RDWR|O_CREAT,0666))==-1) { 
     perror("open"); 
     exit(EXIT_FAILURE); 
    } 

    return fd; 
} 

void close_file(int fd) { 

    if(close(fd)==-1) { 
     perror("close"); 
     exit(EXIT_FAILURE); 
    } 
} 

struct shmid_ds get_shminfo(int id) { 
    struct shmid_ds data; 

    errno=0; 

    if(shmctl(id,IPC_STAT,&data)==-1) { 
     switch(errno) { 
      case EACCES: 
       fprintf(stderr,"Shmid %d: read acces not allowed\n", id); 
       exit(EXIT_FAILURE); 

      case EINVAL: 
       fprintf(stderr,"Shmid %d: invalid shmid\n", id); 
       exit(EXIT_FAILURE); 

      default: 
       perror("shmctl"); 
       exit(EXIT_FAILURE); 
       break; 
     } 
    } 

    return data; 
} 

void write_shminfo(int fd, struct shmem_info shmi) { 
    ssize_t w, tot=0, size=sizeof(struct shmem_info); 

    for(;;) { 
     errno=0; 

     w=write(fd,&shmi,size-tot); 

     if(w==-1 && errno!=EINTR) { 
      perror("write"); 
      exit(EXIT_FAILURE); 
     } 

     if(w==0) return; 

     tot+=w; 
    } 
} 

struct shmem_info read_shminfo(int fd) { 
    ssize_t r, tot=0, size=sizeof(struct shmem_info); 
    struct shmem_info shmi; 

    for(;;) { 
     errno=0; 

     r=read(fd,&shmi,size-tot); 

     if(r==-1 && errno!=EINTR) { 
      perror("write"); 
      exit(EXIT_FAILURE); 
     } 

     if(r==0) return shmi; 

     tot+=r; 
    } 
} 

void print_shminfo(FILE *out, struct shmem_info shmi) { 
    fprintf(out,"Shmid: %d\n", shmi.id); 
    fprintf(out,"Size of segment (bytes): %d\n", (int)shmi.data.shm_segsz); 
    fprintf(out,"PID of creator: %d\n", (int)shmi.data.shm_cpid); 
    fprintf(out,"No. of current attaches: %d\n", (int)shmi.data.shm_nattch); 
    fprintf(out,"Last attach time: %ld\n", shmi.data.shm_atime); 
    fprintf(out,"Last detach time: %ld\n", shmi.data.shm_dtime); 
    fprintf(out,"Last change time: %ld\n", shmi.data.shm_ctime); 
    fprintf(out,"PID of last shmat/shmdt: %d\n", (int)shmi.data.shm_lpid); 
    fprintf(out,"Key supplied to shmget(2): %d\n", (int)shmi.data.shm_perm.__key); 
    fprintf(out,"Effective UID of owner: %d\n", (int)shmi.data.shm_perm.uid); 
    fprintf(out,"Effective GID of owner: %d\n", (int)shmi.data.shm_perm.gid); 
    fprintf(out,"Effective UID of creator: %d\n", (int)shmi.data.shm_perm.cuid); 
    fprintf(out,"Effective GID of creator: %d\n", (int)shmi.data.shm_perm.cgid); 
    fprintf(out,"Permissions + SHM_DEST and ESHM_LOCKED flag: %hd\n", shmi.data.shm_perm.mode); 
    fprintf(out,"Sequence number: %hd\n", shmi.data.shm_perm.__seq); 
    fprintf(out,"\n"); 
} 

int main(int argc, char *argv[]) { 
    int fd, n, i; 
    struct shmem_info *shmi; 

    if(argc<2) { 
     fprintf(stderr,"Usage: %s <shmid> <shmid> ... <shmid>\n", argv[0]); 
     exit(EXIT_FAILURE); 
    } 

    n=argc-1; 

    argv=argv+1; 

    shmi=allocate_shminfo(n); 

    for(i=0;i<n;i++) { 
     shmi[i].id=parse_int(argv[i]); 
    } 

    for(i=0;i<n;i++) { 
     shmi[i].data=get_shminfo(shmi[i].id); 
    } 

    fd=open_fileRW("shmid_info-log.txt"); 

    for(i=0;i<n;i++) { 
     write_shminfo(fd,shmi[i]); 
    } 

    for(i=0;i<n;i++) { 
     shmi[i]=read_shminfo(fd); 
    } 

    for(i=0;i<n;i++) { 
     print_shminfo(stdout,shmi[i]); 
    } 

    close_file(fd); 

    free(shmi); 

    exit(EXIT_SUCCESS); 
} 
+1

如何你知道這是錯的嗎?它顯示什麼? – John3136

+0

請向我們展示您的輸出。 – SirDarius

回答

0

這是你的read_shminfo功能有問題。它適用於當地水文氣象研究所,而不是處理與水文氣象研究所= allocate_shminfo(N)分配的水文氣象研究所;`

一種方法來解決:

void read_shminfo(int fd, struct shmem_info *shmi) { 
// struct shmem_info shmi; 
    ssize_t r, tot=0, size=sizeof(struct shmem_info); 

    for(;;) { 
     errno=0; 

     r=read(fd,(void *)&shmi,size-tot); 

     if(r==-1 && errno!=EINTR) { 
      perror("write"); 
      exit(EXIT_FAILURE); 
     } 

     if(r==0) 
       return ; 

     tot+=r; 
    } 
} 

,並在主:

for(i=0;i<n;i++) { 
    read_shminfo(fd,&shmi[i]); 
}