Shared counter variable among different threads I have a need to use a shared variable among different threads in c/C++.
So putting my knowledge of threads and mutexes I have written the below sample code.
Can anyone please review the code and provide me review comments so that I can improvise it in a more better way. Also I know about atomic variables but somehow I don't want to get into that and wanted to stick with threads &amp; mutexes and locking mechanism. Below code is a working code.

#include &lt;iostream&gt;
#include &lt;unistd.h&gt;
#include &lt;pthread.h&gt;

using namespace std; 

class Thread
{
  public:
    Thread();
    virtual ~Thread();

    int start();
    int join();
    int detach();
    pthread_t self();

    virtual void* run() = 0;

  private:
    pthread_t  m_tid;

    int        m_running;
    int        m_detached;
};

static void* runThread(void* arg)
{
    return ((Thread*)arg)-&gt;run();
}

Thread::Thread() : m_tid(0), m_running(0), m_detached(0) {}

Thread::~Thread()
{
    if (m_running == 1 &amp;&amp; m_detached == 0) {
        pthread_detach(m_tid);
    }
    if (m_running == 1) {
        pthread_cancel(m_tid);
    }
}

int Thread::start()
{
    int result = pthread_create(&amp;m_tid, NULL, runThread, this);
    if (result == 0) {
        m_running = 1;
    }
    return result;
}

int Thread::join()
{
    int result = -1;
    if (m_running == 1) {
        result = pthread_join(m_tid, NULL);
        if (result == 0) {
            m_detached = 0;
        }
    }
    return result;
}

int Thread::detach()
{
    int result = -1;
    cout&lt;&lt;"Detaching thread"&lt;&lt;endl;
    if (m_running == 1 &amp;&amp; m_detached == 0) {
        result = pthread_detach(m_tid);
        if (result == 0) {
            m_detached = 1;
        }
    }
    return result;
}

pthread_t Thread::self() {
    return m_tid;
}



class Mutex
{
    friend class CondVar;
    pthread_mutex_t  m_mutex;

  public:
    // just initialize to defaults
    Mutex() { pthread_mutex_init(&amp;m_mutex, NULL); }
    virtual ~Mutex() { pthread_mutex_destroy(&amp;m_mutex); }

    int lock() { return  pthread_mutex_lock(&amp;m_mutex); }
    int trylock() { return  pthread_mutex_trylock(&amp;m_mutex); }
    int unlock() { return  pthread_mutex_unlock(&amp;m_mutex); }   
};

class shared_integer { 
private: 
    int i;
    Mutex mlock;

public: 
    // Parameterised constructor 
    shared_integer(int i = 0) 
    { 
        this-&gt;i = i; 
    } 
    // Overloading the postfix operator 
    void operator++(int) 
    { 
       mlock.lock();
       (this-&gt;i)++; 
       mlock.unlock();
    } 

    void operator--(int) 
    { 
         (this-&gt;i)--; 
    } 

    // Function to display the value of i 
    void display() 
    { 
        cout &lt;&lt; "Value became:" &lt;&lt;i &lt;&lt; endl; 
    } 
}; 
class MyThread:public Thread  
{
Mutex mlock;
shared_integer &amp;wd; 
public:
MyThread( 
         shared_integer &amp; workd
        ):
         wd(workd){}
void *run() {
        for (int i = 0; i &lt; 10; i++) {
            cout&lt;&lt;"thread "&lt;&lt;(long unsigned int)self()&lt;&lt;endl;
            //Currently testing with only work done
            wd++;
            wd.display();
            sleep(1);
            }
        cout&lt;&lt;"thread done "&lt;&lt;(long unsigned int)self()&lt;&lt;endl;
        return NULL;
    }

};
// Driver function 
int main(int argc , char ** argv) 
{ 
    shared_integer workdone(0); 



    MyThread* thread1 = new MyThread(workdone);
    MyThread* thread2 = new MyThread(workdone);
    MyThread* thread3 = new MyThread(workdone);
    MyThread* thread4 = new MyThread(workdone);

    cout&lt;&lt;"main After creating threads"&lt;&lt;endl;
    thread1-&gt;start();
    thread2-&gt;start();
    thread3-&gt;start();
    thread4-&gt;start();
    cout&lt;&lt;"main Before joining first therad"&lt;&lt;endl;
    cout&lt;&lt;"main Before joining second therad"&lt;&lt;endl;
    thread1-&gt;join();
    thread2-&gt;join();
    thread3-&gt;join();
    thread4-&gt;join();

    cout&lt;&lt;"main done"&lt;&lt;endl;
return 0;

}
If I would get this code at my job, I would reject it. There is NO valid reason for using the pthread library directly to manage threads. Please use std::thread instead. Normally, I wouldn't even do the effort to read further. The same holds for the mutex, just use std::mutex, std::shared_mutex ... instead.

I see your usage of shared_integer, which raises a few questions:
 - Isn't this std::atomic&lt;int&gt;, less performant? (Yes, I know you don't want to get into it, though, I would still recommend looking into it if you don't expose the mutex)
 - Secondly, your implementation is flawed, as operator-- and display() don't use the lock
 - Thirdly, I would urge you to make this a template. It's easy to make mistakes into this, you only want to have that kind of code once.

Looking at your main-function, it looks like you have a memory leak.

The same code using the C++ standard library:

#include &lt;thread&gt;
#include &lt;iostream&gt;
#include &lt;chrono&gt;
#include &lt;atomic&gt;

int main(int argc , char ** argv) 
{ 
    std::atomic&lt;int&gt; workdonecount{0}; 

    auto workdone = [&amp;workdonecount]()
    {
        for (int i = 0; i &lt; 10; i++) {
            std::cout&lt;&lt;"thread "&lt;&lt;std::this_thread::get_id()&lt;&lt;std::endl;
            //Currently testing with only work done
            workdonecount++;
            std::cout &lt;&lt; "Value became:" &lt;&lt; workdonecount &lt;&lt; std::endl;
            std::this_thread::sleep_for(std::chrono::seconds{1});
            }
        std::cout&lt;&lt;"thread done "&lt;&lt;std::this_thread::get_id()&lt;&lt;std::endl;
    };


    std::cout&lt;&lt;"main After creating threads"&lt;&lt;std::endl;
    auto thread1 = std::thread(workdone);
    auto thread2 = std::thread(workdone);
    auto thread3 = std::thread(workdone);
    auto thread4 = std::thread(workdone);
    std::cout&lt;&lt;"main Before joining first therad"&lt;&lt;std::endl;
    std::cout&lt;&lt;"main Before joining second therad"&lt;&lt;std::endl;
    thread1.join();
    thread2.join();
    thread3.join();
    thread4.join();

    std::cout&lt;&lt;"main done"&lt;&lt;std::endl;
return 0;

}


Code at compiler explorer using c++17

From C++20, you could even use std::jthread and let the threads join automatically.

PS: This code contains the same bug that you have:

 workdonecount++;
 std::cout &lt;&lt; "Value became:" &lt;&lt; workdonecount &lt;&lt; std::endl;


Should become:

 auto newValue = ++workdonecount;
 std::cout &lt;&lt; "Value became: " &lt;&lt; newValue &lt;&lt; std::endl;