程序中可能存在任何问题以及我如何使用 lock() 和 unlock() 解决它们?

Where could be any problems in the program and how i solve them with using lock() and unlock()?

提问人:LaPlace 提问时间:2/1/2021 最后编辑:Peter CordesLaPlace 更新时间:5/24/2022 访问量:53

问:

以下一段伪代码显示了一个典型的读取器/写入器方案:

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 ()unlock ()

C++ 并发 锁定 producer-consumer readwritelock

评论

2赞 Alan Birtles 2/1/2021
为什么是伪代码?如果你问的是 c++,请使用 c++

答:

1赞 Xoozee 2/1/2021 #1

关于你的代码知之甚少,但我假设,既不是原子的,也不是原子的。这里需要区分写入访问和读取访问(假设读取访问是 const)。书写会改变文档和长度,必须防止其他访问。必须保护读取免受写入调用的更改,但由于读取不会更改文档或长度,因此允许同时在多个线程中完成。documentlength

我冒昧地使用和.使用完整的 lock() 调用执行此操作会使大多数线程变得无用。另外,我冒昧地修复了您在函数中的这个问题。lock_write()lock_read()readpos = length - 1read()

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()