C Reader Writer程序,一个reader并没有读取所有数据

标签 c reader writer

我正在开发一个读取器/写入器程序,其中有一个写入器对应 n 个读取器。我遇到一个问题,如果有多个读者,如下面发布的屏幕截图,则不会显示共享内存中的整个消息。

输出:

输入消息:测试

读者1:测试

Reader2:测试

作者:测试测试

Reader1:测试

Reader2:测试测试

作者:

enter image description here

读者:

enter image description here

我尝试添加一个计数变量,因为我假设在所有读者都有能力打印之前,作者轮流被标记,这使得作者退出作者中的嵌套 while() 并阻止读者打印。

有什么建议可以让读者都打印出来,无论是一面旗帜还是某种计数?下面还附上了作者和读者循环的屏幕截图。

读者:

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


    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;
    data.count = 0;
    signal(SIGINT, sigHandler);

    key = ftok("mkey",65);

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

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

    while(1) {
        while (data.turn) {
            memcpy(&data, shmPtr, 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(shmPtr, &data, sizeof(DataShared));
    };

    return 0;
}

最佳答案

这可能无法解释您的观察结果,但您的做法很可疑。

您有多个进程,操作系统会调度每个进程。

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

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

关于C Reader Writer程序,一个reader并没有读取所有数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58219173/

相关文章:

c - C中的结构填充

c - 即使在关闭套接字后,服务器仍继续在客户端/服务器 C 应用程序中运行

parsing - 在没有所有可用包或加载所有内容的情况下从 lisp 读取/解析常见的 lisp 文件

Excel::Writer::XLSX 在公式中添加意外的 @

go - io.Writer 的日志数据

c - 匹配(搜索)C 列表中的 URL 的最佳方法(实现白名单或黑名单)?

c - qsort 一个指向结构体指针数组的双指针

go - Reader接口(interface)改变值

python - 如何将默认值插入缺失的 csv 字段?

java - 在 Java 中使用 ArrayList 从文件中读取