简体   繁体   English

std :: string追加线程安全天真的解决方案?

[英]std::string append thread safe naive solution?

I want to make std::string append function thread safe, because I am appending a specific string from different threads. 我想使std :: string追加函数线程安全,因为我从不同的线程追加一个特定的字符串。

I'm a quite beginner in c++ so I'm not sure what problems this may rise. 我是c ++的初学者,所以我不确定这可能会出现什么问题。

The solution I am thinking about is instead of using somestring.append("appendthis"); 我正在考虑的解决方案是使用somestring.append("appendthis");

Use the following code: 使用以下代码:

bool appendtsReady = true;
void appendts(std::string& originalString, char* app)
{
    while (!appendtsReady) {}

    appendtsReady = false;
    originalString.append(app);
    appendtsReady = true;
}

appendts(somestring, "appendthis");

I would hope that if the string is being appended the new request appendts(somestring, "appendthis_from_different_thread"); 我希望如果字符串被追加到新的请求appendts(somestring, "appendthis_from_different_thread"); will be caught on loop until previous append is finished. 将被循环捕获,直到前一个附加完成。

Is this solution is too naive? 这个解决方案太天真了吗?

This is not a thread safe way. 这不是一种线程安全的方式。 Even if appendtsReady were an atomic bool (if you don't change the logic)! 即使appendtsReady是一个原子bool(如果你不改变逻辑)! Here's why: 原因如下:

Consider noone has ever written to the bool and two threads execute appendts . 考虑没有人写过bool并且两个线程执行appendts Both read the bool. 两人都读了博尔。 Now can both read true? 现在可以读到真的吗? Yes! 是! Because between the read of appendtsReady in the while loop and the write in the line below there is a tiny delay! 因为在while循环中读取appendtsReady和在下面的行中写入之间存在微小的延迟! So tiny it will work almost always, but the read of the second thread may come exactly during that delay so both read true . 如此微小,它几乎总能工作,但第二个线程的读取可能恰好在延迟期间,所以两者都是true

The solution: Let them share a std::mutex . 解决方案:让他们共享一个std::mutex

std::mutex mutex;
void appendts(std::string& originalString, char* app)
{
     std::lock_guard<std::mutex> lock(mutex);
     originalString.append(app);
}

Now you can call this method from two threads, provided that both threads know about the same mutex. 现在,您可以从两个线程调用此方法,前提是两个线程都知道相同的互斥锁。 Either declare it globally (not so nice) or pass references of the mutex to both threads. 要么全局声明它(不太好),要么将互斥锁的引用传递给两个线程。

std::mutex works by locking and unlocking, just as you wanted with your boolean variable. std::mutex通过锁定和解锁来工作,就像您想要的布尔变量一样。 However, std::mutex has thread-safety. 但是, std::mutex具有线程安全性。

I recommend using a std::lock_guard instead of mutex.lock(); work(); mutex.unlock(); 我建议使用std::lock_guard而不是mutex.lock(); work(); mutex.unlock(); mutex.lock(); work(); mutex.unlock(); as it provides the goodie of RAII, that is if work() returns, throws or breaks or whatever, the mutex get's unlocked automatically. 因为它提供了RAII的好处,即如果work()返回,抛出或中断或其他什么,则互斥锁自动解锁。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM