I've been working on getting a key value hash dictionary, and one of the things I need to do is rehash when the load factor reaches a threshold, so to make sure no other threads are accessing it I'm trying to bring it down to a single queue.
Will this successfully prevent more than one thread from being able to read/write to the resource at the same time, or is there something I'm missing.
Thanks!!
typedef struct {
pthread_mutex_t mutex;
pthread_cond_t cond;
pthread_rwlock_t rw_lock;
} thread_conch;
typedef struct {
thread_conch d_lock;
size_t elements;
size_t hash_size;
struct kv_record **bucket;
} dictionary;
void init_conch(thread_conch *t_lock)
{
pthread_mutex_init(&t_lock->mutex, NULL);
pthread_cond_init(&t_lock->cond, NULL);
pthread_rwlock_init(&t_lock->rw_lock, NULL);
}
void destroy_conch(thread_conch *t_lock)
{
pthread_mutex_destroy(&t_lock->mutex);
pthread_cond_destroy(&t_lock->cond);
pthread_rwlock_destroy(&t_lock->rw_lock);
}
void hold_conch(thread_conch *t_lock)
{
pthread_rwlock_wrlock(&t_lock->rw_lock);
while (pthread_mutex_trylock(&t_lock->mutex) != 0)
;
}
void read_conch(thread_conch *t_lock)
{
while (pthread_rwlock_tryrdlock(&t_lock->rw_lock) != 0)
pthread_cond_wait(&t_lock->cond, &t_lock->mutex);
}
void release_conch(thread_conch *t_lock)
{
pthread_rwlock_unlock(&t_lock->rw_lock);
pthread_mutex_unlock(&t_lock->mutex);
pthread_cond_broadcast(&t_lock->cond);
}
Related
I'm writing a DLL in C++Builder XE6, that creates a separate thread (derived from TThread) to retrieve JSON data from a REST server every X seconds (using TIdHTTP), and parse the JSON data.
The thread fills a simple struct (no dynamically allocated data) with the parsed JSON data in the Execute() method of the thread:
typedef struct
{
char MyString[40 + 1];
double MyDouble;
bool MyBool;
} TMyStruct;
The thread should store the struct in a list, for example a std::vector:
#include <vector>
std::vector<TMyStruct> MyList;
The thread will add a TMyStruct to the list:
TMyStruct Data;
...
MyList.push_back(Data);
The list will be guarded by a TCriticalSection to prevent data corruption.
The DLL exports a function to retrieve a TMyStruct from MyList.
bool __declspec(dllexport) __stdcall GetMyStruct (int Index, TMyStruct* Data)
{
...
}
Only thing is, I don't know where to put MyList...
If I make MyList a global variable, it is located in the main thread's memory and GetMyStruct() can access it directly. How does the thread access MyList?
If I make MyList a member of the TThread-derived class, it is located in the thread's memory and the thread can access it directly. How does GetMyStruct() access MyList?
What is the best/prefered/common way to store MyList and access it in a different thread?
If I make MyList a global variable, it is located in the main thread's memory and GetMyStruct() can access it directly. How does the thread access MyList?
The exact same way. All threads in a process can freely access global variables within that process. For example:
#include <vector>
#include <System.SyncObjs.hpp>
typedef struct
{
char MyString[40 + 1];
double MyDouble;
bool MyBool;
} TMyStruct;
std::vector<TMyStruct> MyList;
TCriticalSection *Lock = NULL; // why not std::mutex instead?
class TMyThread : public TThread
{
...
};
TMyThread *Thread = NULL;
...
void __fastcall TMyThread::Execute()
{
TMyStruct Data;
...
Lock->Enter();
try {
MyList.push_back(Data);
}
__finally {
Lock->Leave();
}
...
}
...
void __declspec(dllexport) __stdcall StartThread ()
{
Lock = new TCriticalSection;
Thread = new TMyThread;
}
void __declspec(dllexport) __stdcall StopThread ()
{
if (Thread) {
Thread->Terminate();
Thread->WaitFor();
delete Thread;
Thread = NULL;
}
if (Lock) {
delete Lock;
Lock = NULL;
}
}
bool __declspec(dllexport) __stdcall GetMyStruct (int Index, TMyStruct* Data)
{
if (!(Lock && Thread)) return false;
Lock->Enter();
try {
*Data = MyList[Index];
}
__finally {
Lock->Leave();
}
return true;
}
If I make MyList a member of the TThread-derived class, it is located in the thread's memory and the thread can access it directly. How does GetMyStruct() access MyList?
By accessing it via a pointer to the thread object. For example:
#include <vector>
#include <System.SyncObjs.hpp>
typedef struct
{
char MyString[40 + 1];
double MyDouble;
bool MyBool;
} TMyStruct;
class TMyThread : public TThread
{
protected:
void __fastcall Execute();
public:
__fastcall TMyThread();
__fastcall ~TMyThread();
std::vector<TMyStruct> MyList;
TCriticalSection *Lock;
};
TMyThread *Thread = NULL;
...
__fastcall TMyThread::TMyThread()
: TThread(false)
{
Lock = new TCriticalSection;
}
__fastcall TMyThread::~TMyThread()
{
delete Lock;
}
void __fastcall TMyThread::Execute()
{
TMyStruct Data;
...
Lock->Enter();
try {
MyList.push_back(Data);
}
__finally {
Lock->Leave();
}
...
}
void __declspec(dllexport) __stdcall StartThread ()
{
Thread = new TMyThread;
}
void __declspec(dllexport) __stdcall StopThread ()
{
if (Thread) {
Thread->Terminate();
Thread->WaitFor();
delete Thread;
Thread = NULL;
}
}
bool __declspec(dllexport) __stdcall GetMyStruct (int Index, TMyStruct* Data)
{
if (!Thread) return false;
Thread->Lock->Enter();
try {
*Data = Thread->MyList[Index];
}
__finally {
Thread->Lock->Leave();
}
return true;
}
What is the best/prefered/common way to store MyList and access it in a different thread?
That is entirely up to you to decide, based on your particular needs and project design.
I'm reading C++ concurrency in action.
It introduces how to implement interrupting thread using std::condition_variable_any.
I try to understand the code more than a week, but I couldn't.
Below is the code and explanation in the book.
#include <condition_variable>
#include <future>
#include <iostream>
#include <thread>
class thread_interrupted : public std::exception {};
class interrupt_flag {
std::atomic<bool> flag;
std::condition_variable* thread_cond;
std::condition_variable_any* thread_cond_any;
std::mutex set_clear_mutex;
public:
interrupt_flag() : thread_cond(0), thread_cond_any(0) {}
void set() {
flag.store(true, std::memory_order_relaxed);
std::lock_guard<std::mutex> lk(set_clear_mutex);
if (thread_cond) {
thread_cond->notify_all();
} else if (thread_cond_any) {
thread_cond_any->notify_all();
}
}
bool is_set() const { return flag.load(std::memory_order_relaxed); }
template <typename Lockable>
void wait(std::condition_variable_any& cv, Lockable& lk);
};
thread_local static interrupt_flag this_thread_interrupt_flag;
void interruption_point() {
if (this_thread_interrupt_flag.is_set()) {
throw thread_interrupted();
}
}
template <typename Lockable>
void interrupt_flag::wait(std::condition_variable_any& cv, Lockable& lk) {
struct custom_lock {
interrupt_flag* self;
// (1) What is this lk for? Why is lk should be already locked when it is used in costume_lock constructor?
Lockable& lk;
custom_lock(interrupt_flag* self_, std::condition_variable_any& cond,
Lockable& lk_)
: self(self_), lk(lk_) {
self->set_clear_mutex.lock();
self->thread_cond_any = &cond;
}
void unlock() {
lk.unlock();
self->set_clear_mutex.unlock();
}
void lock() { std::lock(self->set_clear_mutex, lk); }
~custom_lock() {
self->thread_cond_any = 0;
self->set_clear_mutex.unlock();
}
};
custom_lock cl(this, cv, lk);
interruption_point();
cv.wait(cl);
interruption_point();
}
class interruptible_thread {
std::thread internal_thread;
interrupt_flag* flag;
public:
template <typename FunctionType>
interruptible_thread(FunctionType f) {
std::promise<interrupt_flag*> p;
internal_thread = std::thread([f, &p] {
p.set_value(&this_thread_interrupt_flag);
f();
});
flag = p.get_future().get();
}
void interrupt() {
if (flag) {
flag->set();
}
};
void join() { internal_thread.join(); };
void detach();
bool joinable() const;
};
template <typename Lockable>
void interruptible_wait(std::condition_variable_any& cv, Lockable& lk) {
this_thread_interrupt_flag.wait(cv, lk);
}
void foo() {
// (2) This is my implementation of how to use interruptible wait. Is it correct?
std::condition_variable_any cv;
std::mutex m;
std::unique_lock<std::mutex> lk(m);
try {
interruptible_wait(cv, lk);
} catch (...) {
std::cout << "interrupted" << std::endl;
}
}
int main() {
std::cout << "Hello" << std::endl;
interruptible_thread th(foo);
th.interrupt();
th.join();
}
Your custom lock type acquires the lock on the internal
set_clear_mutex when it’s constructed 1, and then sets the
thread_cond_any pointer to refer to the std:: condition_variable_any
passed in to the constructor 2.
The Lockable reference is stored for later; this must already be
locked. You can now check for an interruption without worrying about
races. If the interrupt flag is set at this point, it was set before
you acquired the lock on set_clear_mutex. When the condition variable
calls your unlock() function inside wait(), you unlock the Lockable
object and the internal set_clear_mutex 3.
This allows threads that are trying to interrupt you to acquire the
lock on set_clear_mutex and check the thread_cond_any pointer once
you’re inside the wait() call but not before. This is exactly what you
were after (but couldn’t manage) with std::condition_variable.
Once wait() has finished waiting (either because it was notified or
because of a spurious wake), it will call your lock() function, which
again acquires the lock on the internal set_clear_mutex and the lock
on the Lockable object 4. You can now check again for interruptions
that happened during the wait() call before clearing the
thread_cond_any pointer in your custom_lock destructor 5, where you
also unlock the set_clear_mutex.
First, I couldn't understand what is the purpose of Lockabel& lk in mark (1) and why it is already locked in constructor of custom_lock. (It could be locked in the very custom_lock constructor. )
Second there is no example in this book of how to use interruptible wait, so foo() {} in mark (2) is my guess implementation of how to use it. Is it correct way of using it ?
You need a mutex-like object (lk in your foo function) to call the interruptiple waiting just as you would need it for the plain std::condition_variable::wait function.
What's problematic (I also read the book and I have doubts about this example) is that the flag member points to a memory location inside the other thread which could finish right before calling flag->set(). In this specific example the thread only exists after we set the flag so that is okay, but otherwise this approach is limited in my opinion (correct me if I am wrong).
I am working on a c++ (11) project and on the main thread, I need to check the value of two variables. The value of the two variables will be set by other threads through two different callbacks. I am using two condition variables to notify changes of those two variables. Because in c++, locks are needed for condition variables, I am not sure if I should use the same mutex for the two condition variables or I should use two mutex's to minimize exclusive execution. Somehow, I feel one mutex should be sufficient because on one thread(the main thread in this case) the code will be executed sequentially anyway. The code on the main thread that checks (wait for) the value of the two variables wont be interleaved anyway. Let me know if you need me to write code to illustrate the problem. I can prepare that. Thanks.
Update, add code:
#include <mutex>
class SomeEventObserver {
public:
virtual void handleEventA() = 0;
virtual void handleEventB() = 0;
};
class Client : public SomeEventObserver {
public:
Client() {
m_shouldQuit = false;
m_hasEventAHappened = false;
m_hasEventBHappened = false;
}
// will be callbed by some other thread (for exampe, thread 10)
virtual void handleEventA() override {
{
std::lock_guard<std::mutex> lock(m_mutexForA);
m_hasEventAHappened = true;
}
m_condVarEventForA.notify_all();
}
// will be called by some other thread (for exampe, thread 11)
virtual void handleEventB() override {
{
std::lock_guard<std::mutex> lock(m_mutexForB);
m_hasEventBHappened = true;
}
m_condVarEventForB.notify_all();
}
// here waitForA and waitForB are in the main thread, they are executed sequentially
// so I am wondering if I can use just one mutex to simplify the code
void run() {
waitForA();
waitForB();
}
void doShutDown() {
m_shouldQuit = true;
}
private:
void waitForA() {
std::unique_lock<std::mutex> lock(m_mutexForA);
m_condVarEventForA.wait(lock, [this]{ return m_hasEventAHappened; });
}
void waitForB() {
std::unique_lock<std::mutex> lock(m_mutexForB);
m_condVarEventForB.wait(lock, [this]{ return m_hasEventBHappened; });
}
// I am wondering if I can use just one mutex
std::condition_variable m_condVarEventForA;
std::condition_variable m_condVarEventForB;
std::mutex m_mutexForA;
std::mutex m_mutexForB;
bool m_hasEventAHappened;
bool m_hasEventBHappened;
};
int main(int argc, char* argv[]) {
Client client;
client.run();
}
There is an object shared by multiple threads to read from and write to, and I need to implement the class with a reader-writer lock which has the following functions:
It might be declared occupied by one and no more than one thread. Any other threads that try to occupy it will be rejected, and continue to do their works rather than be blocked.
Any of the threads are allowed to ask whether the object is occupied by self or by others at any time, except for the time when it is being declared occupied or released.
Only the owner of the object is allowed to release its ownership, though others might try to do it as well. If it is not the owner, the releasing operation will be canceled.
The performance needs to be carefully considered.
I'm doing the work with OpenMP, so I hope to implement the lock using only the APIs within OpenMP, rather than POSIX, or so on. I have read this answer, but there are only solutions for implementations of C++ standard library. As mixing OpenMP with C++ standard library or POSIX thread model may slow down the program, I wonder is there a good solution for OpenMP?
I have tried like this, sometimes it worked fine but sometimes it crashed, and sometimes it was dead locked. I find it hard to debug as well.
class Element
{
public:
typedef int8_t label_t;
Element() : occupied_(-1) {}
// Set it occupied by thread #myThread.
// Return whether it is set successfully.
bool setOccupiedBy(const int myThread)
{
if (lock_.try_lock())
{
if (occupied_ == -1)
{
occupied_ = myThread;
ready_.set(true);
}
}
// assert(lock_.get() && ready_.get());
return occupied_ == myThread;
}
// Return whether it is occupied by other threads
// except for thread #myThread.
bool isOccupiedByOthers(const int myThread) const
{
bool value = true;
while (lock_.get() != ready_.get());
value = occupied_ != -1 && occupied_ != myThread;
return value;
}
// Return whether it is occupied by thread #myThread.
bool isOccupiedBySelf(const int myThread) const
{
bool value = true;
while (lock_.get() != ready_.get());
value = occupied_ == myThread;
return value;
}
// Clear its occupying mark by thread #myThread.
void clearOccupied(const int myThread)
{
while (true)
{
bool ready = ready_.get();
bool lock = lock_.get();
if (!ready && !lock)
return;
if (ready && lock)
break;
}
label_t occupied = occupied_;
if (occupied == myThread)
{
ready_.set(false);
occupied_ = -1;
lock_.unlock();
}
// assert(ready_.get() == lock_.get());
}
protected:
Atomic<label_t> occupied_;
// Locked means it is occupied by one of the threads,
// and one of the threads might be modifying the ownership
MutexLock lock_;
// Ready means it is occupied by one the the threads,
// and none of the threads is modifying the ownership.
Mutex ready_;
};
The atomic variable, mutex, and the mutex lock is implemented with OpenMP instructions as following:
template <typename T>
class Atomic
{
public:
Atomic() {}
Atomic(T&& value) : mutex_(value) {}
T set(const T& value)
{
T oldValue;
#pragma omp atomic capture
{
oldValue = mutex_;
mutex_ = value;
}
return oldValue;
}
T get() const
{
T value;
#pragma omp read
value = mutex_;
return value;
}
operator T() const { return get(); }
Atomic& operator=(const T& value)
{
set(value);
return *this;
}
bool operator==(const T& value) { return get() == value; }
bool operator!=(const T& value) { return get() != value; }
protected:
volatile T mutex_;
};
class Mutex : public Atomic<bool>
{
public:
Mutex() : Atomic<bool>(false) {}
};
class MutexLock : private Mutex
{
public:
void lock()
{
bool oldMutex = false;
while (oldMutex = set(true), oldMutex == true) {}
}
void unlock() { set(false); }
bool try_lock()
{
bool oldMutex = set(true);
return oldMutex == false;
}
using Mutex::operator bool;
using Mutex::get;
};
I also use the lock provided by OpenMP in alternative:
class OmpLock
{
public:
OmpLock() { omp_init_lock(&lock_); }
~OmpLock() { omp_destroy_lock(&lock_); }
void lock() { omp_set_lock(&lock_); }
void unlock() { omp_unset_lock(&lock_); }
int try_lock() { return omp_test_lock(&lock_); }
private:
omp_lock_t lock_;
};
By the way, I use gcc 4.9.4 and OpenMP 4.0, on x86_64 GNU/Linux.
I've been trying to get a project rid of every boost reference and switch to pure C++11.
At one point, thread workers are created which wait for a barrier to give the 'go' command, do the work (spread through the N threads) and synchronize when all of them finish. The basic idea is that the main loop gives the go order (boost::barrier .wait()) and waits for the result with the same function.
I had implemented in a different project a custom made Barrier based on the Boost version and everything worked perfectly. Implementation is as follows:
Barrier.h:
class Barrier {
public:
Barrier(unsigned int n);
void Wait(void);
private:
std::mutex counterMutex;
std::mutex waitMutex;
unsigned int expectedN;
unsigned int currentN;
};
Barrier.cpp
Barrier::Barrier(unsigned int n) {
expectedN = n;
currentN = expectedN;
}
void Barrier::Wait(void) {
counterMutex.lock();
// If we're the first thread, we want an extra lock at our disposal
if (currentN == expectedN) {
waitMutex.lock();
}
// Decrease thread counter
--currentN;
if (currentN == 0) {
currentN = expectedN;
waitMutex.unlock();
currentN = expectedN;
counterMutex.unlock();
} else {
counterMutex.unlock();
waitMutex.lock();
waitMutex.unlock();
}
}
This code has been used on iOS and Android's NDK without any problems, but when trying it on a Visual Studio 2013 project it seems only a thread which locked a mutex can unlock it (assertion: unlock of unowned mutex).
Is there any non-spinning (blocking, such as this one) version of barrier that I can use that works for C++11? I've only been able to find barriers which used busy-waiting which is something I would like to prevent (unless there is really no reason for it).
class Barrier {
public:
explicit Barrier(std::size_t iCount) :
mThreshold(iCount),
mCount(iCount),
mGeneration(0) {
}
void Wait() {
std::unique_lock<std::mutex> lLock{mMutex};
auto lGen = mGeneration;
if (!--mCount) {
mGeneration++;
mCount = mThreshold;
mCond.notify_all();
} else {
mCond.wait(lLock, [this, lGen] { return lGen != mGeneration; });
}
}
private:
std::mutex mMutex;
std::condition_variable mCond;
std::size_t mThreshold;
std::size_t mCount;
std::size_t mGeneration;
};
Use a std::condition_variable instead of a std::mutex to block all threads until the last one reaches the barrier.
class Barrier
{
private:
std::mutex _mutex;
std::condition_variable _cv;
std::size_t _count;
public:
explicit Barrier(std::size_t count) : _count(count) { }
void Wait()
{
std::unique_lock<std::mutex> lock(_mutex);
if (--_count == 0) {
_cv.notify_all();
} else {
_cv.wait(lock, [this] { return _count == 0; });
}
}
};
Here's my version of the accepted answer above with Auto reset behavior for repetitive use; this was achieved by counting up and down alternately.
/**
* #brief Represents a CPU thread barrier
* #note The barrier automatically resets after all threads are synced
*/
class Barrier
{
private:
std::mutex m_mutex;
std::condition_variable m_cv;
size_t m_count;
const size_t m_initial;
enum State : unsigned char {
Up, Down
};
State m_state;
public:
explicit Barrier(std::size_t count) : m_count{ count }, m_initial{ count }, m_state{ State::Down } { }
/// Blocks until all N threads reach here
void Sync()
{
std::unique_lock<std::mutex> lock{ m_mutex };
if (m_state == State::Down)
{
// Counting down the number of syncing threads
if (--m_count == 0) {
m_state = State::Up;
m_cv.notify_all();
}
else {
m_cv.wait(lock, [this] { return m_state == State::Up; });
}
}
else // (m_state == State::Up)
{
// Counting back up for Auto reset
if (++m_count == m_initial) {
m_state = State::Down;
m_cv.notify_all();
}
else {
m_cv.wait(lock, [this] { return m_state == State::Down; });
}
}
}
};
Seem all above answers don't work in the case the barrier is placed too near
Example: Each thread run the while loop look like this:
while (true)
{
threadBarrier->Synch();
// do heavy computation
threadBarrier->Synch();
// small external calculations like timing, loop count, etc, ...
}
And here is the solution using STL:
class ThreadBarrier
{
public:
int m_threadCount = 0;
int m_currentThreadCount = 0;
std::mutex m_mutex;
std::condition_variable m_cv;
public:
inline ThreadBarrier(int threadCount)
{
m_threadCount = threadCount;
};
public:
inline void Synch()
{
bool wait = false;
m_mutex.lock();
m_currentThreadCount = (m_currentThreadCount + 1) % m_threadCount;
wait = (m_currentThreadCount != 0);
m_mutex.unlock();
if (wait)
{
std::unique_lock<std::mutex> lk(m_mutex);
m_cv.wait(lk);
}
else
{
m_cv.notify_all();
}
};
};
And the solution for Windows:
class ThreadBarrier
{
public:
SYNCHRONIZATION_BARRIER m_barrier;
public:
inline ThreadBarrier(int threadCount)
{
InitializeSynchronizationBarrier(
&m_barrier,
threadCount,
8000);
};
public:
inline void Synch()
{
EnterSynchronizationBarrier(
&m_barrier,
0);
};
};