{"id":16109881,"url":"https://github.com/clausklein/samples","last_synced_at":"2025-04-06T05:22:53.957Z","repository":{"id":56570390,"uuid":"200117955","full_name":"ClausKlein/samples","owner":"ClausKlein","description":"short c++ samples, some from CppCoreGuidelines","archived":false,"fork":false,"pushed_at":"2020-11-12T09:01:40.000Z","size":545,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"develop","last_synced_at":"2025-02-12T11:13:39.016Z","etag":null,"topics":["clang-format","clang-tidy","cmake","cpp"],"latest_commit_sha":null,"homepage":null,"language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ClausKlein.png","metadata":{"files":{"readme":"README.rst","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-08-01T20:54:34.000Z","updated_at":"2021-07-08T02:02:00.000Z","dependencies_parsed_at":"2022-08-15T21:10:24.366Z","dependency_job_id":null,"html_url":"https://github.com/ClausKlein/samples","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ClausKlein%2Fsamples","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ClausKlein%2Fsamples/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ClausKlein%2Fsamples/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ClausKlein%2Fsamples/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ClausKlein","download_url":"https://codeload.github.com/ClausKlein/samples/tar.gz/refs/heads/develop","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247438095,"owners_count":20938863,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["clang-format","clang-tidy","cmake","cpp"],"created_at":"2024-10-09T19:34:48.746Z","updated_at":"2025-04-06T05:22:53.746Z","avatar_url":"https://github.com/ClausKlein.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"\n====================================================\nvolatile: The Multithreaded Programmer's Best Friend\n====================================================\n\n\n.. contents::\n\n\nSummary\n-------\n\nWhen writing multithreaded programs, you can use **volatile** to your advantage.\nYou must stick to the following rules:\n\n * Define all shared objects as **volatile**.\n * Don't use **volatile** directly with primitive types.\n * When defining shared classes, use **volatile** member functions to express *thread safety*.\n\n\nSample\n------\n\nvolatile.cpp::\n    \n    // from\n    // http://www.drdobbs.com/cpp/volatile-the-multithreaded-programmers-b/184403766\n    \n    #include \u003cboost/thread.hpp\u003e\n    \n    #include \u003ciostream\u003e\n    \n    using namespace boost;\n    \n    template \u003ctypename T\u003e class LockingPtr\n    {\n    public:\n        // Constructors/destructors\n        LockingPtr(const volatile T \u0026obj, const volatile mutex \u0026mtx)\n            : pObj_(const_cast\u003cT *\u003e(\u0026obj)), pMtx_(const_cast\u003cmutex *\u003e(\u0026mtx))\n        {\n            std::cout \u003c\u003c BOOST_CURRENT_FUNCTION \u003c\u003c \" called\" \u003c\u003c std::endl;\n            pMtx_-\u003elock();\n        }\n        ~LockingPtr() { pMtx_-\u003eunlock(); }\n        // Pointer behavior\n        T \u0026operator*() { return *pObj_; }\n        T *operator-\u003e() { return pObj_; }\n    \n    private:\n        T *pObj_;\n        mutex *pMtx_;\n    \n        // non copyable\n        LockingPtr(const LockingPtr \u0026);\n        LockingPtr \u0026operator=(const LockingPtr \u0026);\n    };\n    \n    /***\n    Notice the use of overloading.\n    \n    Now Widget's user can invoke Operation using a uniform syntax either for\n    volatile objects and get thread safety, or for regular objects and get speed.\n    \n    The user must be careful about defining the shared Widget objects as volatile.\n     ***/\n    class Widget\n    {\n    public:\n        Widget(){};\n        void Operation() const volatile;\n        // ...\n    \n    protected:\n        void Operation()\n        {\n            std::cout \u003c\u003c BOOST_CURRENT_FUNCTION \u003c\u003c \" called\" \u003c\u003c std::endl;\n            Helper();\n        };\n        void Helper()\n        {\n            std::cout \u003c\u003c BOOST_CURRENT_FUNCTION \u003c\u003c \" called\" \u003c\u003c std::endl;\n        }\n    \n    private:\n        mutable mutex mtx_;\n    };\n    \n    /***\n    When implementing a volatile member function, the first operation is usually\n    to lock this with a LockingPtr. Then the work is done by using the non-\n    volatile sibling:\n     ***/\n    void Widget::Operation() const volatile\n    {\n        LockingPtr\u003cWidget\u003e lpThis(*this, mtx_);\n        assert(\u0026(*lpThis) == const_cast\u003cWidget *\u003e(this));\n    \n        lpThis-\u003eOperation(); // invokes the non-volatile function\n    }\n    \n    int main()\n    {\n        volatile Widget wg; // thread save object\n        wg.Operation();\n    \n        return 0;\n    }\n\n\nReferences\n----------\n\n * https://think-async.com/Asio/\n * https://github.com/boostorg/beast\n * https://github.com/onqtam/doctest\n * https://github.com/martinmoene/gsl-lite\n * http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines\n * https://www.kdab.com/clang-tidy-part-1-modernize-source-code-using-c11c14/\n * https://clang.llvm.org/extra/clang-tidy/index.html\n * https://clang.llvm.org/docs/HowToSetupToolingForLLVM.html\n * https://clang.llvm.org/docs/SourceBasedCodeCoverage.html\n * https://clang.llvm.org/docs/DiagnosticsReference.html\n * https://clang.llvm.org/docs/MemorySanitizer.html\n * https://clang-analyzer.llvm.org\n * http://llvm.org/docs/CodingStandards.html#do-not-use-static-constructors\n * http://llvm.org/docs/HowToSetUpLLVMStyleRTTI.html\n * http://ltp.sourceforge.net/coverage/lcov.php\n\n___________________________________________________________\n\nGenerated with docutils_\n\n.. _docutils: http://docutils.sourceforge.net/rst.html\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fclausklein%2Fsamples","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fclausklein%2Fsamples","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fclausklein%2Fsamples/lists"}