让读者知道作者写完了,等待读者读完

Let reader know that writer finished writing, and wait for reader to finish reading

提问人:odyssey 提问时间:1/3/2020 更新时间:1/3/2020 访问量:211

问:

我有以下读写器方案:

  1. 作家解雇读者。
  2. 读取器无限旋转,并在写入共享缓冲区后开始读取。
  3. 编写器开始写入共享缓冲区
  4. 作者等待读者读完。
  5. 程序结束。

伪代码 - 请假设一切都是线程安全的:

// shared buffer
var buffer = new [3];

// 1. fire a thread, pass it a function named read
thread reader = new thread(read);

// 2. write some text to a shared buffer
var source = new [] {"line 1", "line 2", "line 3"};
for (int i = 0; ++i; i< source.length) {
   buffer[i] = source[i];
}

// 3. wait for reader to finish consuming the buffer
reader.join();


// 4. reader function
function void read() {
    while (true) {
        while (!buffer.empty()) {
           for (int i = 0; ++i; i< buffer.length) {
              print(buffer[i]);
           }
        }
    }
}

我的问题是:如何让读者走出无限循环?

我知道这是一个经典问题,但找不到处理它的资源。我所看到的都涉及不同种类的锁,这不是我感兴趣的事情(如前所述 - 请假设一切都是线程安全的)。

多线程与 语言无关的 读取 编写器

评论


答:

0赞 erickson 1/3/2020 #1

使用共享标志 .finished

当编写者完成其内容的编写时,它会设置标志 .finished = true

而不是让读取器永远循环 ,在设置标志时终止。while (true)while (!finished)

评论

1赞 Jeremy Friesner 1/3/2020
请注意,在生产代码中,您可能希望使用条件变量或其他类型的正式线程信号机制,而不是轮询共享布尔变量,因为轮询循环要么浪费太多 CPU 周期(如果它们是旋转循环),要么引入不必要的延迟(如果它们在轮询之间休眠以避免浪费 CPU)。
0赞 odyssey 1/3/2020
1. 作者解雇读者 2.读取器获取 cpu 时间,完成计算 '!buffer.empty()' 3.Writer 获取 cpu 时间,写入,设置标志 4。读取器获取 cpu 时间 5。读取器退出而不读取
0赞 erickson 1/3/2020
@odyssey 循环终止后再次检查缓冲区。如果不为空,则处理其内容。