Question
What can I do to get a blocking mechanism that provides a minimal and stable delay, ensuring that a thread cannot reload a resource before another thread acquires and releases it?
The desirability of answers to this question is evaluated as follows:
Some combination of built-in features of C ++ 11, working in the MinGW in Windows 7 (note that library <thread>and <mutex>do not work on the Windows platform)
Some combination of Windows API functions
FairLock modification below, my own attempt to implement such a mechanism
Some features provided by the free open source library that does not require the installation process .configure / make / make install (getting this to work in MSYS is more of an adventure than I care)
Background
I am writing an application that is effectively a multi-stage producer / consumer. One thread generates the input consumed by another thread, which produces the output consumed by another thread. The application uses pairs of buffers, so that after the initial delay, all threads can work almost simultaneously.
Windows 7, CriticalSections . CriticalSections (, , Windows ++ 11) , - , , , . - (Encoder) , . , .
, , , , , - . ( ). FairLock Encoder , , CriticalSection, , 60% . 40% 10 100 , .
FairLock
#ifndef FAIRLOCK_HPP
#define FAIRLOCK_HPP
#include <atomic>
using namespace std;
class FairLock {
private:
atomic_bool owned {false};
atomic<DWORD> lastOwner {0};
public:
FairLock(bool owned);
bool inline hasLock() const;
bool tryLock();
void seizeLock();
void tryRelease();
void waitForLock();
};
#endif
#include <windows.h>
#include "FairLock.hpp"
#define ID GetCurrentThreadId()
FairLock::FairLock(bool owned) {
if (owned) {
this->owned = true;
this->lastOwner = ID;
} else {
this->owned = false;
this->lastOwner = 0;
}
}
bool inline FairLock::hasLock() const {
return owned && lastOwner == ID;
}
bool FairLock::tryLock() {
bool success = false;
DWORD id = ID;
if (owned) {
success = lastOwner == id;
} else if (
lastOwner != id &&
owned.compare_exchange_strong(success, true)
) {
lastOwner = id;
success = true;
} else {
success = false;
}
return success;
}
void FairLock::seizeLock() {
bool success = false;
DWORD id = ID;
if (!(owned && lastOwner == id)) {
while (!owned.compare_exchange_strong(success, true)) {
success = false;
}
lastOwner = id;
}
}
void FairLock::tryRelease() {
if (hasLock()) {
owned = false;
}
}
void FairLock::waitForLock() {
bool success = false;
DWORD id = ID;
if (!(owned && lastOwner == id)) {
while (lastOwner == id);
while (!owned.compare_exchange_strong(success, true)) {
success = false;
}
lastOwner = id;
}
}
FairLock ; !
, ++. . CouchDeveloper . , , , FairLock, , , . , , :
New owner: set owned to true
Old owner: is owned true? yes
Old owner: am I the last owner? yes
New owner: set me as the last owner
.
, . , .