I want to make std::string append function thread safe, because I am appending a specific string from different threads.

I'm a quite beginner in c++ so I'm not sure what problems this may rise.

The solution I am thinking about is instead of using 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"); 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)! Here's why:

Consider noone has ever written to the bool and two threads execute 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! So tiny it will work almost always, but the read of the second thread may come exactly during that delay so both read true.

The solution: Let them share a 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. However, std::mutex has thread-safety.

I recommend using a std::lock_guard instead of 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.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top