子进程无法访问C中的共享内存

时间:2014-04-17 14:48:07

标签: c shared-memory

我有一个程序,我想在其中设置指向结构的指针作为共享内存。我想我已经在main方法中正确设置了共享内存;然后我调用一个函数来初始化struct和fork。但是,子进程无法访问共享内存;父进程按预期工作,这并不是一个惊喜。我确信子进程执行并且有效,但是它无法访问共享内存,因此除了打印出printf语句之外,该函数并没有做很多事情。

struct OverSharedData{
    struct SharedData ** rep;
    int rop;
};

void initialize( struct OverSharedData * bill){
bill->rep = (struct SharedData**)malloc(sizeof(struct SharedData*)*consumerthreads);
int on =0;
for (on=0; on<consumerthreads; on++) {
    *(bill->rep+on) = (struct SharedData *)malloc(sizeof(struct SharedData));
    init(*(bill->rep + on), on); //
 }}

int main(int argc, const char * argv[])
{

    databases(argv[1]); /* Takes care of setting up the database*/
    categories(argv[2]); /*Takes care of setting up the book categories*/
    bookorders = argv[3];

    key_t key = ftok("garbage.txt", 71);
    int eyedee = shmget(key, sizeof(struct OverSharedData ),
                        IPC_CREAT | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
    if (eyedee == -1)
    {
        perror("shmget");
        exit(1);
    }

    struct OverSharedData *remp = (struct OverSharedData *) shmat(eyedee, 0, 0);

    if (remp == (void *) -1)
    {
        perror("shmat");
        exit(1);
    }

    initialize(remp);
    struct SharedData * d = *(remp->rep + 0);


    printf("Hallo\n");
    shmctl(eyedee, IPC_RMID, 0);



    pid_t forkk = fork();

    if (forkk==0) {
        /*THIS DOES NOT WORK*/
        printf("Entered consumer check: %d\n", remp->rop);

         int z = 0;
         pthread_t Consumer_Threads[consumerthreads];
         for (z=0; z<consumerthreads; z++) {
         remp->rop = z;
         d = *(remp->rep + z);
         d->da = z;
         pthread_create((Consumer_Threads+z), 0, Consumer, d);


         }
         for (z = 0; z<consumerthreads; z++) {
         pthread_join(Consumer_Threads[z], NULL);
         }
         shmdt(remp);

    }

    else{
       /*THIS WORKS*/
        printf("Entered Producer: %d\n",remp->rop);

        pthread_t Produc;
        pthread_create(&Produc, 0, Producer, remp); 
        pthread_join(Produc, NULL);


        printf("Hey guys: %d\n", remp->rop);
        shmdt(remp);
    }

我的猜测是我没有正确地初始化结构,但我并不是很清楚我做错了什么。我遗漏了一些其他的初始化代码,但我想,因为我甚至无法访问OverSharedData结构中的int,更重要的是我无法在第一个访问结构的地方的地方。

1 个答案:

答案 0 :(得分:3)

问题是您的共享数据(单个OverSharedData对象)包含指向非共享数据的指针。您需要分配要在共享内存段中共享的所有数据,而不是使用malloc。类似的东西:

static void *shared_available;
static size_t shared_left;
void init_shared(size_t size) {
    key_t key = ftok("garbage.txt", 71);
    int eyedee = shmget(key, size,
                        IPC_CREAT | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
    if (eyedee == -1) {
        perror("shmget");
        exit(1); }
    shared_available = shmat(eyedee, 0, 0);
    if (shared_available == (void *) -1) {
        perror("shmat");
        exit(1); }
    shared_left = size;
}
void *alloc_shared(size_t size) {
    void *rv = shared_available;
    if (size > shared_left) {
        fprintf(stderr, "Ran out of shared memory!\n");
        exit(1); }
    shared_available = (char *)rv + size;
    shared_left -= size;
    return rv;
}

OverSharedData *initialize() {
    init_shared(sizeof(struct OverSharedData) +
                       sizeof(struct SharedData *) * consumerthreads +
                       sizeof(struct SharedData) * consumerthreads)
    OverSharedData *bill = alloc_shared(sizeof(OverSharedData));
    bill->rep = alloc_shared(sizeof(struct SharedData*)*consumerthreads);
    for (int on=0; on<consumerthreads; on++) {
        bill->rep[on] = alloc_shared(sizeof(struct SharedData));
        init(&bill->rep[on], on); }
}

如果init例程试图将指向非共享内存的指针存储到SharedData结构中,那么上面仍然会出现问题(你不能显示任何一个的定义,所以我们可以& #39; t))。

如果您希望能够跨流程更灵活地分配和管理共享内存,您确实需要使用通用共享内存分配器/管理器,例如this