问题描述
for (int i = 0; i < N; ++i)
cout << B[i] << endl;
delete[] B; //release memory after use
return 0;
我的问题是:
这个程序哪里会出现并发执行问题?
以及如何仅使用伪代码函数 string document;
string::size_type length = 0;
write()
{
while (true) {
string text = readFromKeyboard();
document.append(text);
length = length + text.length();
}
}
read()
{
static string::size_type pos = 0;
while (true) {
if (pos < length) {
process(document.substr(pos,length - pos));
pos = length - 1;
}
}
}
main()
{
unsigned int k = 20;
while (k--)
Thread consumer(read).start;
Thread producer(write).start;
wait();
}
和 lock ()
来保护它们?
解决方法
对您的代码知之甚少,但我假设 document
和 length
都不是原子的。您在这里需要的是写访问和读访问之间的区别(假设读访问是常量)。写入会改变文档和长度,必须防止其他访问。必须通过 write 调用来保护读取不受更改,但由于读取既不改变文档也不改变长度,因此允许一次在多个线程中完成。
我冒昧使用 lock_write()
和 lock_read()
。使用完整的 lock() 调用执行此操作会使大多数 read
线程无用。另外,我冒昧地修复了您在 pos = length - 1
函数中的这个 read()
问题。
write()
将变成:
write()
{
while (true) {
string text = readFromKeyboard();
lock_write();
document.append(text);
length = length + text.length();
unlock();
}
}
而 read()
将变成:
read()
{
static string::size_type pos = 0;
while (true) {
lock_read();
if (pos < length) {
process(document.substr(pos,length - pos));
pos = length;
}
unlock();
}
}
此外,read()
将进入繁忙的等待状态,这并不好。这可以通过使用条件变量来修复。