簡體   English   中英

C-獲取IPC共享內存信息

[英]C - Get IPC shared memory information

我創建了一個程序,該程序通過作為參數傳遞的shmid(共享內存ID)顯示共享內存段信息。

將數據與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);
}

是您的read_shminfo函數出現問題。 它適用於本地shmi,而不是處理通過shmi = allocate_shminfo(n);分配的shmi。

一種解決方法:

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]);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM