C中的共享内存问题

问题描述 投票:0回答:1

将功能写入共享内存:

void* writer(void* arg) {
    pack_t *pack;
    pack = (pack_t*) arg;

    pthread_mutex_lock(&mutex);
    int shm_fd = shm_open(key, O_CREAT | O_RDWR | O_TRUNC, S_IRUSR | S_IWUSR);
    if (shm_fd == -1) {
        printf("Could not create shared memory\n");
        return (void*)-1;
    }

    if (ftruncate(shm_fd, DATA_LEN) == -1) {
        printf("Error on ftruncate to allocate \n");
        return (void*)-1;
    }

    void *shmp_wr =  mmap(NULL, DATA_LEN, PROT_WRITE, MAP_SHARED, shm_fd, 0);
    if(shmp_wr == MAP_FAILED){
        printf("Mapping failed\n");
        return (void*)-1;
    }
    char shm_data[70];
    sprintf(shm_data, "%s -> %s", pack->data, pack->hash);
    memcpy(shmp_wr, shm_data, strlen(shm_data));

    if (munmap(shmp_wr, DATA_LEN) == -1) {
        printf("Unmapping failed\n");
        return (void*)-1;
    }   
    close(shm_fd);
    pthread_mutex_unlock(&mutex);
    pthread_cond_signal(&cnd);
    return (void*)1;
}

从共享内存中读取功能:

void *reader(void* arg) {
    pack_t *pack = calloc(1, sizeof(pack_t)); 
    char data[32];
    char hash[32];

    pthread_cond_wait(&cnd, &mutex);
    pthread_mutex_lock(&mutex);
    int shm_fd = shm_open(key, O_CREAT | O_RDONLY , S_IRUSR | S_IWUSR);
    if (shm_fd == -1) {
        printf("Could not open shared memory \n");
        return (void*)-1;
    }

    void *shmp_rd = mmap(NULL, DATA_LEN, PROT_READ, MAP_SHARED, shm_fd, 0);
    if(shmp_rd == MAP_FAILED){
        printf("Mapping failed\n");
        return (void*)-1;
    }

    char shm_data[70];
    memcpy(shm_data, shmp_rd, DATA_LEN);
    sscanf(shm_data, "%s -> %s", data, hash);

    if (munmap(shmp_rd, DATA_LEN) == -1) {
        printf("Unmapping failed\n");
        return (void*)-1;
    }
    strcpy(pack->data, data);
    strcpy(pack->hash, hash);
    shm_unlink(key);
    close(shm_fd);
    pthread_mutex_unlock(&mutex);

    return (void*)pack;
}

在共享内存中写入的第一个程序:

pthread_t tid;
    if(node){
        while(node){
            void* ret_vpr;
            pack_t *pack = calloc(1, sizeof(pack_t));
            strcpy(pack->data, node->data);
            strcpy(pack->hash, node->hash);
            pthread_create(&tid, NULL, writer, (void *)pack);
            pthread_join(tid, &ret_vpr);
            int i = (int)ret_vpr;
            printf("%d\n", i);
            if(i == -1){
                printf("error in shared memory\n");
                break;
            }
            write(data_socket, op, sizeof(op));
            node = node->next;
            free(pack);
        }
    }
    else{
        printf("list is empty\n");
    }

从共享内存读取的第二个程序:

else if(!strcmp(sync_msg, "ADD")){
        int i = pthread_create(&tid, NULL, reader, NULL);
        i = pthread_join(tid, &ret_vpr);
        pack_t *ret = (pack_t *)ret_vpr;
        add(table, ret->data);
    }

    else if(!strcmp(sync_msg, "DELETE")){
        table_entry_t *node;
        int i = pthread_create(&tid, NULL, reader, NULL);
        i = pthread_join(tid, &ret_vpr);
        pack_t *ret = (pack_t *)ret_vpr;
        node = find(table, ret->data);
        if(node){
            del(table, node);   
        }
        else{
            printf("not found\n");
        }
    }

为什么该程序不能交互式地将其数据与共享内存同步?当第一个程序第二次要写入时,发生Mapping Failed错误。

c posix shared-memory
1个回答
0
投票

我完全不尝试从您的代码运行程序,但是您的问题可能是接下来的两行顺序错误

pthread_cond_wait(&cnd, &mutex);
pthread_mutex_lock(&mutex);

必须是

pthread_mutex_lock(&mutex);
pthread_cond_wait(&cnd, &mutex);

因此阅读器无法很好地同步

您必须先获取互斥锁才能调用pthread_cond_wait


[编辑]补充说明:

在折磨机中,您可以进行:

char shm_data[70];
sprintf(shm_data, "%s -> %s", pack->data, pack->hash);
memcpy(shmp_wr, shm_data, strlen(shm_data));

首先为什么是70而不是DATA_LEN(+1),读者中的相同问题

您确定您不写出shm_data吗?

最后,您不复制以字符串结尾的空字符,在阅读器中您执行_sscanf(shm_data,“%s->%s”,data,hash)_并且一个需要空字符]]

这也很奇怪

    int i = pthread_create(&tid, NULL, reader, NULL);

以及紧随其后

    i = pthread_join(tid, &ret_vpr);

只需在当前线程中完成工作

© www.soinside.com 2019 - 2024. All rights reserved.