简体   繁体   中英

How to synchronize 2 functions using C++11 thread features?

We have two functions: a() and b().

There are multiple threads. Some of them want to execute a(), the others want to execute b(). There are following restrictions:

  • no 2 threads are allowed to execute a() at the same time
  • when some thread is executing a(), no thread is allowed to execute b()
  • multiple threads ARE allowed to execute b() at the same time

How to code it using C++11 features?

As pointed out in the comments , this is a typical use case for a reader-writer-lock, as specified by C++14's std::shared_timed_mutex .

So in case your standard library implementation already supports it, simply use that one:

std::shared_timed_mutex mtx;

void a() {
    std::unique_lock<std::shared_timed_mutex> lk(mtx);
    // ...
}

void b() {
    std::shared_lock<std::shared_timed_mutex> lk(mtx);
    // ...
}

A compiler-agnostic implementation is provided by recent versions of Boost.Thread .

If you can use neither of those, you can still try to roll your own implementation (although this has the usual drawbacks of being likely to introduce subtle bugs if you are not careful).

The basic idea is to have a counter that is protected by an ordinary mutex. The counter gets increased whenever a shared lock is acquired and decreased whenever a shared lock is released. Acquiring an exclusive lock sets the counter to a special value, that is not reachable otherwise.

Acquiring an exclusive lock is only allowed if the counter is at 0 (ie. no shared locks are currently active). Acquiring a shared lock is only allowed if the counter is not at the special value (ie. no exclusive lock is currently held). If you try to acquire a lock and the respective precondition is not met, you either spin or (probably preferable) wait on a condition variable until the precondition is met. Note that you will need two condition variables in that case, one for each precondition.

If i understand you correctly, you will need one global lock guarding the function a, which has to be locked inside both a() and b(). It would look something like this:

#include <mutex>
#include <thread>

std::mutex a_lock;

void a() 
{
    std::lock_guard<std::mutex> lock(a_lock);
}

void b()
{
    std::lock_guard<std::mutex> lock(a_lock);

}

Note that using a lock_guard, the lock is automatically released when the function returns.

e: yes i misunderstood your question. wait a bit.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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