I'm not really sure if this types of questions are frowned upon here, but it is the first place I come for when I have a question in mind, so, here we go.
I have a std::vector<T> v
that I use to store data. In thread t1
, there is a data generator and data insertion can happen at any time. On the other hand, in thread t2
, at arbitrary times, I need to search v
and access and return an element from it. Deletions, swaps etc. are guaranteed to not happen on v
until both t1
and t2
join on main thread.
Without any thread-safety measures, code exits with SIGABRT
. I first used std::mutex
and std::lock_guard
and succeeded, however the number of lock/unlocks are in millions and I wish to speed things up a bit. So I tried to implement the following system:
#include <atomic>
#include <cassert>
#include <thread>
// Mutex-like thingy begin
class MyMutex
{
private:
std::atomic<bool> modifyLockRequest;
std::atomic<bool> accessLockRequest;
std::atomic<bool> accessLock;
public:
MyMutex() :
modifyLockRequest(false),
accessLockRequest(false),
accessLock(false) {}
void acquireModifyLock() {
assert(!modifyLockRequest);
modifyLockRequest = true;
while( accessLockRequest && accessLock ) {
std::this_thread::yield();
}
}
void releaseModifyLock() {
assert(modifyLockRequest);
modifyLockRequest = false;
}
void acquireAccessLock() {
assert(!accessLockRequest);
accessLockRequest = true;
while (modifyLockRequest) {
std::this_thread::yield();
}
accessLock = true;
}
void releaseAccessLock() {
assert(accessLockRequest);
accessLock = false;
accessLockRequest = false;
}
};
MyMutex myMutex;
Then I use this by
myMutex.acquireModifyLock();
// Do insertion/deletion etc. on `v`
myMutex.releaseModifyLock();
and
myMutex.acquireAccessLock();
// Do stuff with `v[i]`
myMutex.releaseAccessLock();
My rationale was to have 2 Boolean flags to alert whichever thread is trying to get a lock, and to have a third flag to break off cases where the two threads try to acquire a lock at the same time.
This code seems to work well in about 1/8th time of std::mutex
and std::lock_guard
duo, however, my question is, is this solution guaranteed to always work in my case where there is only 2 threads?
Aucun commentaire:
Enregistrer un commentaire