my case is one thread read and want to
decide if needed to change the value or not?
some thing like below
void set(bool status)
{
if(status == m_status)
return;
monitor.lock();
m_status = status;
}
if this possible?
Using a synchronization object for boolean state is overkill.
On Windows you can use Interlocked Variable Access.
For cross platform solution .. see Boost Atomic
std::atomic from C++11 is also a solution
I think you need to clarify your question a bit. Is it possible? Yes. Is it necessary? Probably. Are there other ways to do it? Yes, as another answer has noted.
Don't forget to unlock when you're done with the things you want to change. And just a stylistic note, I find it much clearer to use your 'if' statement to encase the code block instead of return'ing out of the function. Like this:
void set(bool status)
{
if(status != m_status)
{
monitor.lock();
m_status = status;
monitor.unlock();
}
}
Just my opinion, of course.
Generally it's not possible. It will work most of the time on most platforms, but it's formally undefined and there are cases where cache coherency issues will come to hunt you.
If you can get C++11, use std::atomic<bool> from the new <atomic> header. If not, you should be using legacy compiler-specific equivalent. Windows have Interlocked* functions, GCC has __sync keyword. There is actually a cross-platform implementation of the important bits of the C++11 standard buried deep in Boost.Interprocess library, but it's unfortunately not exposed to the user.
Related
I have a property which is similar to the following:
private:
Foo* myFoo_m;
public:
Foo getMyFoo() const
{
if (myFoo_m == NULL)
{
myFoo_m = new Foo();
// perform initialization
This works well in a single-threaded environment, but how do I handle this in a multi-threaded environment? Most of the info I've found deals with static singletons, but in this case, myFoo is a public instance property.
I am porting this over from C# (where I can use Lazy) and Java (where I can use double check locking), but it doesn't seem that there is a straightforward way to do this in C++. I cannot rely on any external libraries (no BOOST), and this needs to work on windows and linux. I also cannot use C++11.
Any insight would be good. I am new to C++.
If you have access to c++11 you can use std::mutex to lock prevent multiple threads from initializing the lazy section. (Note: std::mutex only became available on Windows with VS2012)
You can even perform a scoped aquisition of the mutex with std::lock_guard:
private:
std::mutex m_init_mutex;
public:
Foo getMyFoo() const
{
{
std::lock_guard<std::mutex> lock(m_init_mutex);
if (myFoo_m == NULL)
{
myFoo_m = new Foo();
// perform initialization
}
}
EDIT: The OPs now stated that C++11 isn't an option, but perhaps this answer will be useful in the future
By saying "no C++11", "no Boost or other third-party code", "must work on Windows and Linux", you have restricted yourself to using implementation-specific locking mechanisms.
I think your best option is to define a simple lock class for yourself, and implement it to use pthread_mutex on Linux and a CriticalSection on Windows. Possibly you already have some platform-specific code, to start the threads in the first place.
You could try something like Windows Services for UNIX to avoid writing platform-specific code, but it's probably not worth it for one lock. And although it's supplied by Microsoft, you'd probably consider it an external library anyway.
Warning: I didn't see the "no C++11" requirement, so please disregard the answer.
Since C++11 mandates that static variable initialization be thread-safe, here's a simple way that you might consider "cheating":
Foo init_foo()
{
// initialize and return a Foo
}
Foo & get_instance_lazily()
{
static Foo impl = init_foo();
return impl;
}
The instance will be initialized the first time that you call get_instance_lazily(), and thread-safely so.
All coroutine implementations I've encountered use assembly or inspect the contents of jmp_buf. The problem with this is it inherently not cross platform.
I think the following implementation doesn't go off into undefined behavior or rely on implementation details. But I've never encountered a coroutine written like this.
Is there some inherent flaw is using long jump with threads?
Is there some hidden gotcha in this code?
#include <setjmp.h>
#include <thread>
class Coroutine
{
public:
Coroutine( void ) :
m_done( false ),
m_thread( [&](){ this->start(); } )
{ }
~Coroutine( void )
{
std::lock_guard<std::mutex> lock( m_mutex );
m_done = true;
m_condition.notify_one();
m_thread.join();
}
void start( void )
{
if( setjmp( m_resume ) == 0 )
{
std::unique_lock<std::mutex> lock( m_mutex );
m_condition.wait( lock, [&](){ return m_done; } );
}
else
{
routine();
longjmp( m_yield, 1 );
}
}
void resume( void )
{
if( setjmp( m_yield ) == 0 )
{
longjmp( m_resume, 1 );
}
}
void yield( void )
{
if( setjmp( m_resume ) == 0 )
{
longjmp( m_yield, 1 );
}
}
private:
virtual void routine( void ) = 0;
jmp_buf m_resume;
jmp_buf m_yield;
bool m_done;
std::mutex m_mutex;
std::condition_variable m_condition;
std::thread m_thread;
};
UPDATE 2013-05-13 These days there is Boost Coroutine (built on Boost Context, which is not implemented on all target platforms yet, but likely to be supported on all major platforms sooner rather than later).
I don't know whether stackless coroutines fit the bill for your intended use, but I suggest you have a look at them here:
Boost Asio: The Proactor Design Pattern: Concurrency Without Threads
Asio also has a co-procedure 'emulation' model based on a single (IIRC) simple preprocessor macro, combined with some amount of cunningly designed template facilities that come things eerily close to compiler support for _stack-less co procedures.
The sample HTTP Server 4 is an example of the technique.
The author of Boost Asio (Kohlhoff) explains the mechanism and the sample on his Blog here: A potted guide to stackless coroutines
Be sure to look for the other posts in that series!
There is a C++ standard proposal for coroutine support - N3708 which is written by Oliver Kowalke (who is an author of Boost.Coroutine) and Goodspeed.
I suppose this would be the ultimate clean solution eventually (if it happens…)
Because we don't have stack exchange support from C++ compiler, coroutines currently need low level (usually assembly level, or setjmp/longjmp) hack, and that's out of abstraction range of C++. Then the implementations are fragile, and need help from compiler to be robust.
For example, it's really hard to set stack size of a coroutine context, and if you overflow the stack, your program will be corrupted silently. Or crash if you're lucky. Segmented stack seems can help this, but again, this needs compiler level support.
If once it becomes standard, compiler writers will take care. But before that day, Boost.Coroutine would be the only practical solution in C++ to me.
In C, there's libtask written by Russ Cox (who is a member of Go team). libtask works pretty well, but doesn't seem to be maintained anymore.
P.S. If someone know how to support standard proposal, please let me know. I really support this proposal.
There is no generalized cross-platform way of implementing co-routines. Although some implementations can fudge co-routines using setjmp/longjmp, such practices are not standards-compliant. If routine1 uses setjmp() to create jmp_buf1, and then calls routine2() which uses setjmp() to create jmp_buf2, any longjmp() to jmp_buf1 will invalidate jmp_buf2 (if it hasn't been invalidated already).
I've done my share of co-routine implementations on a wide variety of CPUs; I've always used at least some assembly code. It often doesn't take much (e.g. four instructions for a task-switch on the 8x51) but using assembly code can help ensure that a compiler won't apply creative optimizations that would break everything.
I don't believe you can fully implement co-routines with long jump. Co-routines are natively supported in WinAPI, they are called fibers. See for example, CreateFiber(). I don't think other operating systems have native co-routine support. If you look at SystemC library, for which co-routines are central part, they are implemented in assembly for each supported platform, except Windows. GBL library also uses co-routines for event-driven simulation based on Windows fibers. It's very easy to make hard to debug errors trying to implement co-routines and event-driven design, so I suggest using existing libraries, which are already thoroughly tested and have higher level abstractions to deal with this concept.
I would like confirmation that my approach is extremely fast and appropriate for cross platform protection of a shared resource for a mostly multiple reader, single writer approach using C++. It favors writers such that when they enter all current threads are allowed to finish, but all new threads of any type must wait. The reverse of these two functions should be obvious.
The reading I've done suggest that boost shared_mutex and other type rwlocks are not implemented very well and should be avoided. In fact, shared_mutex will not make it into C++0x I take it. See this response by Anthony Williams.
It seems it might even be possible to write to an integer and not need locking of any kind if it is aligned correctly. There is so many articles out there, any good reading on this subject so I don't have to sort the wheat from the chaff?
void AquireReadLock(void)
{
mutex::enter();
if(READ_STATE == true)
{
iReaders++;
mutex::leave();
return;
}
else
{
mutex::leave();
sleep(1);
AquireReadLock();
return;
}
}
void AquireWriteLock(void)
{
mutex::enter();
READ_STATE = false;
if (iReaders != 0)
{
mutex::leave();
sleep(1);
AquireWriteLock();
return;
}
else
{
mutex::leave();
return;
}
}
The decision to leave shared_mutex was made independently of any quality issues. The decision was part of the "Kona compromise" made in the Fall of 2007. This compromise was aimed at reducing the feature set of C++0x so as to ship a standard by 2009. It didn't work, but nevertheless, that is the rationale.
shared_mutex's will be discussed for inclusion to a technical report (i.e. tr2) after the committee has completed C++0x. The chairman on the library working group has already contacted me on this very subject. That is not to say that shared_mutex will be in tr2. Just that it will be discussed.
Your implementation of AquireReadLock and AquireWriteLock have the disadvantage in that they eat a stack frame at the rate of once per second when under contention. And when contention is over, they delay up to a second before reacting. This makes them both stack hungry and poor performing (sorry).
If you are interested, there is a full description and implementation of shared_mutex here:
http://home.roadrunner.com/~hinnant/mutexes/locking.html
The code is not part of boost, but does carry the boost open source license. Feel free to use it, just keep the copyright with the source code. No other strings attached. Here is its analog to your AquireReadLock:
void
shared_mutex::lock_shared()
{
std::unique_lock<mutex_t> lk(mut_);
while ((state_ & write_entered_) || (state_ & n_readers_) == n_readers_)
gate1_.wait(lk);
count_t num_readers = (state_ & n_readers_) + 1;
state_ &= ~n_readers_;
state_ |= num_readers;
}
And here is its analog to your AquireWriteLock:
void
shared_mutex::lock()
{
std::unique_lock<mutex_t> lk(mut_);
while (state_ & write_entered_)
gate1_.wait(lk);
state_ |= write_entered_;
while (state_ & n_readers_)
gate2_.wait(lk);
}
I consider this a well-tested and high-performing, fair read/write mutex implementation for C++. If you have ideas on how to improve it, I would welcome them.
I would like confirmation that my
approach is extremely fast and
appropriate for cross platform
protection of a shared resource for a
mostly multiple reader, single writer
approach using C++.
Faster than what? Your question seems like a micro-optimization, any solution will require profiling to make an adequate conclusion.
The reading I've done suggest that
boot shared_mutex and other type
rwlocks are not implemented very well
and should be avoided.
What are your sources for this statement?
I'm looking for a portable way of jumping to a computed offset in C++.
I know that GCC has a mechanism for doing this using goto as discussed here:
http://social.msdn.microsoft.com/forums/en-US/vclanguage/thread/ec7e52b5-0978-4123-9d29-9dc7d807c6b4
Sadly I don't think other compilers implement this.
Normally I wouldn't have reason to use goto in C++ but I found that it could be useful for optimizing an interpreted language (search for 'threaded interpreter' if you are interested in this).
I know that I can implement this using inline assembly language, but the problem then is I have to implement this for every platform the interpreter runs on.
So does anyone know if there is a portable way of doing this?
The solution might involve goto but I'm open to any other sort of hackery that you can think of ;)
UPDATE: Currently the interpreter uses a switch statement. I'm looking for techniques that improve on this and make the interpreter run faster. Specifically I'm trying to figure out a portable way of saying 'goto <next-byte-code-instruction>' where <next-byte-code-instruction> is a computed offset that can be stored in the byte code itself.
UPDATE: I found a related question here.
What opcode dispatch strategies are used in efficient interpreters?
switch allows to jump to predefined offsets
Array of function pointers/function objects
setjmp/longjmp
I think setjmp/longjmp is as close as you can get. Beyond that, the spec calls things like offsets in the instruction stream "implementation details", and you're stuck with platform-specific stuff like intrinsics and inline asm.
The other (really ugly) thing you could try is using a switch statement, which is typically implemented as a jump table of offsets. Ie,
int ip = 0;
top:
switch( ip )
{
case 0:
ip += do_whatever(); // returns an offset
goto top;
case 1:
ip += some_other_function();
goto top;
case 2:
ip += etc();
goto top;
// ad infinitum...
}
This is in the spirit of Bell's original article, and the gist is that the body of each case is a single VM "opcode" in the stream. But that seems really icky.
Aside from goto's and longjumping and other nonportable tricks, could you consider virtual functions or at least ponters to functions? You can have several singleton objects of types derived from single base class. Array of pointers has all those objects. Virtual function returns index of the next interpreter state. Base object holds all data ever needed by any derived object.
EDIT: Pointers to functions could be a little faster even, but a little messier too. There is a Guru of the Week article that explains it.
It looks like it is not possible to implement this in a portable way.
(Although I still welcome alternative answers!)
I found this blog post from someone who has already tried what I wanted to do. He uses the GCC approach and got a 33% speed improvement (stats are at the end of the post).
The solution is conditionally compiled under Win32 to use inline assembly to compute the address of the labels. But he reports that using inline assembly in this way is 3 times slower than normal! Ouch
http://abepralle.wordpress.com/2009/01/25/how-not-to-make-a-virtual-machine-label-based-threading/
Oh well, I didn't want to use inline assembly anyway.
I seriously wouldn't use any form of goto. It died a long time ago. If you must, however, perhaps you should just write a macro for this, and use a bunch of ifdefs to make it portable. This shouldn't be too hard, and it is the fastest solution.
I'm looking for a good reader/writer lock in C++. We have a use case of a single infrequent writer and many frequent readers and would like to optimize for this. Preferable I would like a cross-platform solution, however a Windows only one would be acceptable.
Since C++ 17 (VS2015) you can use the standard:
#include <shared_mutex>
typedef std::shared_mutex Lock;
typedef std::unique_lock< Lock > WriteLock;
typedef std::shared_lock< Lock > ReadLock;
Lock myLock;
void ReadFunction()
{
ReadLock r_lock(myLock);
//Do reader stuff
}
void WriteFunction()
{
WriteLock w_lock(myLock);
//Do writer stuff
}
For older compiler versions and standards you can use boost to create a read-write lock:
#include <boost/thread/locks.hpp>
#include <boost/thread/shared_mutex.hpp>
typedef boost::shared_mutex Lock;
typedef boost::unique_lock< Lock > WriteLock;
typedef boost::shared_lock< Lock > ReadLock;
Newer versions of boost::thread have read/write locks (1.35.0 and later, apparently the previous versions did not work correctly).
They have the names shared_lock, unique_lock, and upgrade_lock and operate on a shared_mutex.
Using standard pre-tested, pre-built stuff is always good (for example, Boost as another answer suggested), but this is something that's not too hard to build yourself. Here's a dumb little implementation pulled out from a project of mine:
#include <pthread.h>
struct rwlock {
pthread_mutex_t lock;
pthread_cond_t read, write;
unsigned readers, writers, read_waiters, write_waiters;
};
void reader_lock(struct rwlock *self) {
pthread_mutex_lock(&self->lock);
if (self->writers || self->write_waiters) {
self->read_waiters++;
do pthread_cond_wait(&self->read, &self->lock);
while (self->writers || self->write_waiters);
self->read_waiters--;
}
self->readers++;
pthread_mutex_unlock(&self->lock);
}
void reader_unlock(struct rwlock *self) {
pthread_mutex_lock(&self->lock);
self->readers--;
if (self->write_waiters)
pthread_cond_signal(&self->write);
pthread_mutex_unlock(&self->lock);
}
void writer_lock(struct rwlock *self) {
pthread_mutex_lock(&self->lock);
if (self->readers || self->writers) {
self->write_waiters++;
do pthread_cond_wait(&self->write, &self->lock);
while (self->readers || self->writers);
self->write_waiters--;
}
self->writers = 1;
pthread_mutex_unlock(&self->lock);
}
void writer_unlock(struct rwlock *self) {
pthread_mutex_lock(&self->lock);
self->writers = 0;
if (self->write_waiters)
pthread_cond_signal(&self->write);
else if (self->read_waiters)
pthread_cond_broadcast(&self->read);
pthread_mutex_unlock(&self->lock);
}
void rwlock_init(struct rwlock *self) {
self->readers = self->writers = self->read_waiters = self->write_waiters = 0;
pthread_mutex_init(&self->lock, NULL);
pthread_cond_init(&self->read, NULL);
pthread_cond_init(&self->write, NULL);
}
pthreads not really being Windows-native, but the general idea is here. This implementation is slightly biased towards writers (a horde of writers can starve readers indefinitely); just modify writer_unlock if you'd rather the balance be the other way around.
Yes, this is C and not C++. Translation is an exercise left to the reader.
Edit
Greg Rogers pointed out that the POSIX standard does specify pthread_rwlock_*. This doesn't help if you don't have pthreads, but it stirred my mind into remembering: Pthreads-w32 should work! Instead of porting this code to non-pthreads for your own use, just use Pthreads-w32 on Windows, and native pthreads everywhere else.
Whatever you decide to use, benchmark your work load against simple locks, as read/write locks tend to be 3-40x slower than simple mutex, when there is no contention.
Here is some reference
C++17 supports std::shared_mutex . It is supported in MSVC++ 2015 and 2017.
Edit: The MSDN Magazine link isn't available anymore. The CodeProject article is now available on https://www.codeproject.com/Articles/32685/Testing-reader-writer-locks and sums it up pretty nicely. Also I found a new MSDN link about Compound Synchronisation Objects.
There is an article about reader-writer locks on MSDN that presents some implementations of them. It also introduces the Slim reader/writer lock, a kernel synchronisation primitive introduced with Vista. There's also a CodeProject article about comparing different implementations (including the MSDN article's ones).
Intel Thread Building Blocks also provide a couple of rw_lock variants:
http://www.threadingbuildingblocks.org/
They have a spin_rw_mutex for very short periods of contention and a queueing_rw_mutex for longer periods of contention. The former can be used in particularly performance sensitive code. The latter is more comparable in performance to that provided by Boost.Thread or directly using pthreads. But profile to make sure which one is a win for your access patterns.
Boost.Thread has since release 1.35.0 already supports reader-writer locks. The good thing about this is that the implementation is greatly cross-platform, peer-reviewed, and is actually a reference implementation for the upcoming C++0x standard.
I can recommend the ACE library, which provides a multitude of locking mechanisms and is ported to various platforms.
Depending on the boundary conditions of your problem, you may find the following classes useful:
ACE_RW_Process_Mutex
ACE_Write_Guard and ACE_Read_Guard
ACE_Condition
http://www.codeproject.com/KB/threads/ReaderWriterLock.aspx
Here is a good and lightweight implementation suitable for most tasks.
Multiple-Reader, Single-Writer Synchronization Lock Class for Win32 by Glenn Slayde
http://www.glennslayden.com/code/win32/reader-writer-lock
#include <shared_mutex>
class Foo {
public:
void Write() {
std::unique_lock lock{mutex_};
// ...
}
void Read() {
std::shared_lock lock{mutex_};
// ...
}
private:
std::shared_mutex mutex_;
};
You could copy Sun's excellent ReentrantReadWriteLock. It includes features such as optional fairness, lock downgrading, and of course reentrancy.
Yes it's in Java, but you can easily read and transpose it to C++, even if you don't know any Java. The documentation I linked to contains all the behavioral properties of this implementation so you can make sure it does what you want.
If nothing else, it's a guide.