Shared counter variable among different threads
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;