Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/clausklein/samples

short c++ samples, some from CppCoreGuidelines
https://github.com/clausklein/samples

clang-format clang-tidy cmake cpp

Last synced: 20 days ago
JSON representation

short c++ samples, some from CppCoreGuidelines

Awesome Lists containing this project

README

        

====================================================
volatile: The Multithreaded Programmer's Best Friend
====================================================

.. contents::

Summary
-------

When writing multithreaded programs, you can use **volatile** to your advantage.
You must stick to the following rules:

* Define all shared objects as **volatile**.
* Don't use **volatile** directly with primitive types.
* When defining shared classes, use **volatile** member functions to express *thread safety*.

Sample
------

volatile.cpp::

// from
// http://www.drdobbs.com/cpp/volatile-the-multithreaded-programmers-b/184403766

#include

#include

using namespace boost;

template class LockingPtr
{
public:
// Constructors/destructors
LockingPtr(const volatile T &obj, const volatile mutex &mtx)
: pObj_(const_cast(&obj)), pMtx_(const_cast(&mtx))
{
std::cout << BOOST_CURRENT_FUNCTION << " called" << std::endl;
pMtx_->lock();
}
~LockingPtr() { pMtx_->unlock(); }
// Pointer behavior
T &operator*() { return *pObj_; }
T *operator->() { return pObj_; }

private:
T *pObj_;
mutex *pMtx_;

// non copyable
LockingPtr(const LockingPtr &);
LockingPtr &operator=(const LockingPtr &);
};

/***
Notice the use of overloading.

Now Widget's user can invoke Operation using a uniform syntax either for
volatile objects and get thread safety, or for regular objects and get speed.

The user must be careful about defining the shared Widget objects as volatile.
***/
class Widget
{
public:
Widget(){};
void Operation() const volatile;
// ...

protected:
void Operation()
{
std::cout << BOOST_CURRENT_FUNCTION << " called" << std::endl;
Helper();
};
void Helper()
{
std::cout << BOOST_CURRENT_FUNCTION << " called" << std::endl;
}

private:
mutable mutex mtx_;
};

/***
When implementing a volatile member function, the first operation is usually
to lock this with a LockingPtr. Then the work is done by using the non-
volatile sibling:
***/
void Widget::Operation() const volatile
{
LockingPtr lpThis(*this, mtx_);
assert(&(*lpThis) == const_cast(this));

lpThis->Operation(); // invokes the non-volatile function
}

int main()
{
volatile Widget wg; // thread save object
wg.Operation();

return 0;
}

References
----------

* https://think-async.com/Asio/
* https://github.com/boostorg/beast
* https://github.com/onqtam/doctest
* https://github.com/martinmoene/gsl-lite
* http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines
* https://www.kdab.com/clang-tidy-part-1-modernize-source-code-using-c11c14/
* https://clang.llvm.org/extra/clang-tidy/index.html
* https://clang.llvm.org/docs/HowToSetupToolingForLLVM.html
* https://clang.llvm.org/docs/SourceBasedCodeCoverage.html
* https://clang.llvm.org/docs/DiagnosticsReference.html
* https://clang.llvm.org/docs/MemorySanitizer.html
* https://clang-analyzer.llvm.org
* http://llvm.org/docs/CodingStandards.html#do-not-use-static-constructors
* http://llvm.org/docs/HowToSetUpLLVMStyleRTTI.html
* http://ltp.sourceforge.net/coverage/lcov.php

___________________________________________________________

Generated with docutils_

.. _docutils: http://docutils.sourceforge.net/rst.html