C Reader Writer Program,一个读取器无法读取所有数据

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

我正在研究一个读/写程序,在该程序中,有一个写程序可供n个读者使用。我遇到的一个问题是,如果有多个阅读器,例如下面发布的屏幕截图,则不会显示来自共享内存的整个消息。

输出

输入消息:测试

阅读器1:测试

阅读器2:测试

作者:测试测试

阅读器1:测试

Reader2:测试测试

作家

enter image description here

读者

enter image description here

我已尝试添加一个count变量,因为我假设在所有阅读器都具有打印能力之前,已经标记了书写者转向,从而使书写者退出书写器中的嵌套while()并停止了阅读器的打印。

关于使读者都打印的任何建议,无论是标记还是计数?下面还附有writer和reader循环的屏幕截图。

读者:

int main() {
    DataShared data;
    data.turn = 0;
    signal(SIGINT, sigHandler);

    //generates key
    key = ftok("mkey",65);

    //returns an identifier in mId
    if ((mId = shmget(key, SIZE, IPC_CREAT|S_IRUSR|S_IWUSR)) < 0){
    perror("shared memory error");
    exit(1);
    }

    // shmat to attach to shared memory
    if((mPtr = shmat(mId, 0, 0)) == (void*) -1) {
    perror("Can't attach\n");
    exit(1);
    }

    data.count = 0;

    while(1) {
        // request critical section
        while(!data.turn && data.count == 0) {
        //not time for the reader, check if token is changed.
            memcpy(&data, mPtr, sizeof(DataShared));
        }

        data.count++;

        // enter critical section
        usleep(1);
        fprintf(stderr, "Read from memory: %s\n", data.message);
        usleep(1);
        // leave critical section

        data.count--;

        while(data.count > 0){
            ;
        }

        data.turn = 0;
        memcpy(mPtr, &data, sizeof(DataShared));
    };

    return 0;
}

作家:

    int main() {
    DataShared data;
    data.turn = 0;
    signal(SIGINT, sigHandler);

    //generate a key
    key = ftok("mkey",65);

    if((mId = shmget(key, SIZE, IPC_CREAT|S_IRUSR|S_IWUSR)) < 0 ) {
    perror("Error creating shared memory\n");
    exit(1);
    }

    if((mPtr = shmat(mId, 0, 0)) == (void*) -1) {
    perror("Can't attach\n");
    exit(1);
    }

    while(1) {
        while (data.turn) {
            memcpy(&data, mPtr, sizeof(DataShared));
        }

        // enter critical section
        printf("Enter a message: \n" );
        fgets(data.message, 1024, stdin);

        // leave critical section
        printf("Message written to memory: %s\n", data.message);
        data.turn = 1;
        memcpy(mPtr, &data, sizeof(DataShared));
    };

    return 0;
}
c reader writer
1个回答
0
投票

这可能不是您观察到的结果,但您所做的却是可疑的。

您有多个进程,并且操作系统安排了每个进程。

首先,不能保证所有读者都会阅读邮件。一个读取器很可能会完成,将标志设置为0并将数据复制回共享内存,然后另一个读取器才有机会读取数据。

然后您的data.count。它以编写器的局部变量data开头。在此,您无需初始化data.count,因此它具有不确定的值。在阅读器中,将其设置为0,但是它将被共享内存中的值(不确定的值)覆盖。您先做一个++,再做一个-,然后等待它变成0。那怎么会变成零呢?那位读者可以永远等待。

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