Using a lock_guard - C++ Thread

C++ examples for Thread:Mutex

Description

Using a lock_guard

Demo Code

                                                                                             
#include <cstdlib>
#include <iostream>
#include <mutex>
#include <stack>
#include <thread>
#include <vector>
                                                                                             
using namespace std;
class MyObject/*from w w  w .jav  a2  s .c o  m*/
{
private:
    static const unsigned int MAX_OBJECTS{ 8 };
                                                                                             
    using MyCollection = vector < MyObject >;
    static MyCollection s_ManagedObjects;
                                                                                             
    static stack<unsigned int> s_FreeList;
                                                                                             
    static mutex s_Mutex;
                                                                                             
    unsigned int m_Value{ 0xFFFFFFFF };
                                                                                             
public:
    MyObject() = default;
    MyObject(unsigned int value)
        : m_Value{ value }
    {
                                                                                             
    }
                                                                                             
    void* operator new(size_t numBytes)
    {
        lock_guard<mutex> lock{ s_Mutex };
                                                                                             
        void* objectMemory{};
                                                                                             
        if (s_ManagedObjects.capacity() < MAX_OBJECTS)
        {
            s_ManagedObjects.reserve(MAX_OBJECTS);
        }
                                                                                             
        if (numBytes == sizeof(MyObject) &&
            s_ManagedObjects.size() < s_ManagedObjects.capacity())
        {
            unsigned int index{ 0xFFFFFFFF };
            if (s_FreeList.size() > 0)
            {
                index = s_FreeList.top();
                s_FreeList.pop();
            }
                                                                                             
            if (index == 0xFFFFFFFF)
            {
                s_ManagedObjects.push_back({});
                index = s_ManagedObjects.size() - 1;
            }
            objectMemory = s_ManagedObjects.data() + index;
        }
        else
        {
            objectMemory = malloc(numBytes);
        }
                                                                                             
        return objectMemory;
    }
                                                                                             
    void operator delete(void* pMem)
    {
        lock_guard<mutex> lock{ s_Mutex };
                                                                                             
        const intptr_t index{
            (static_cast<MyObject*>(pMem)-s_ManagedObjects.data()) /
            static_cast<intptr_t>(sizeof(MyObject)) };
        if (0 <= index && index < static_cast<intptr_t>(s_ManagedObjects.size()))
        {
            s_FreeList.emplace(static_cast<unsigned int>(index));
        }
        else
        {
            free(pMem);
        }
    }
};
                                                                                             
MyObject::MyCollection MyObject::s_ManagedObjects{};
stack<unsigned int> MyObject::s_FreeList{};
mutex MyObject::s_Mutex;
                                                                                             
void ThreadTask()
{
    MyObject* pObject4{ new MyObject(5) };
                                                                                             
    cout << "pObject4: " << pObject4 << endl;
                                                                                             
    MyObject* pObject5{ new MyObject(6) };
                                                                                             
    cout << "pObject5: " << pObject5 << endl;
                                                                                             
    delete pObject4;
    pObject4 = nullptr;
                                                                                             
    MyObject* pObject6{ new MyObject(7) };
                                                                                             
    cout << "pObject6: " << pObject6 << endl;
                                                                                             
    pObject4 = new MyObject(8);
    cout << "pObject4: " << pObject4 << endl;
                                                                                             
    delete pObject5;
    pObject5 = nullptr;
                                                                                             
    delete pObject6;
    pObject6 = nullptr;
                                                                                             
    delete pObject4;
    pObject4 = nullptr;
}
                                                                                             
int main(int argc, char* argv[])
{
    cout << hex << showbase;
                                                                                             
    thread myThread{ ThreadTask };
                                                                                             
    MyObject* pObject1{ new MyObject(1) };
                                                                                             
    cout << "pObject1: " << pObject1 << endl;
                                                                                             
    MyObject* pObject2{ new MyObject(2) };
                                                                                             
    cout << "pObject2: " << pObject2 << endl;
                                                                                             
    delete pObject1;
    pObject1 = nullptr;
                                                                                             
    MyObject* pObject3{ new MyObject(3) };
                                                                                             
    cout << "pObject3: " << pObject3 << endl;
                                                                                             
    pObject1 = new MyObject(4);
                                                                                             
    cout << "pObject1: " << pObject1 << endl;
                                                                                             
    delete pObject2;
    pObject2 = nullptr;
                                                                                             
    delete pObject3;
    pObject3 = nullptr;
                                                                                             
    delete pObject1;
    pObject1 = nullptr;
                                                                                             
    myThread.join();
                                                                                             
    return 0;
}

Result


Related Tutorials