Memory leaks using shared_mutex
Asked Answered
P

1

6

The following code leads into an increasing usage of memory:

#include <shared_mutex>

class foo
{
public:
   void bar()
   {
      std::unique_lock lock(m_mtx);
   }
   std::shared_mutex m_mtx;
};

int main()
{
   while (1)
   {
      foo obj;
      obj.bar();
   }
}

The following do not: (only changes the mutex type)

#include <mutex>

class foo
{
public:
   void bar()
   {
      std::unique_lock lock(m_mtx);
   }
   std::mutex m_mtx;
};

int main()
{
   while (1)
   {
      foo obj;
      obj.bar();
   }
}

I am using Windows 7 and using the task manager to track the memory consumption of my program.

I compile with mingw and this simple command line to compile:

g++.exe -std=c++17 -o mytest main.cpp

What i am doing wrong with the usage of shared_mutex ?

Perilymph answered 14/5, 2019 at 14:21 Comment(7)
You need to add more details than just that. In particular, how do you measure memory consumption, what's your platform, etcAnnettannetta
I added the informationsPerilymph
Doesn't look like MinGW even has standard threading library. How are you able to use it then? Are you using some external library? You should post this information too. Post FULL code you are using (you should have #include directives in your source).Hazelwood
@PlanteVerte I would try a C++ profiler Deleaker/Valgrind/whatever to understand the memory usage. But I just tried your code in Visual Studio 2019 and memory consumption is not growing, it's stable ~25 Mb.Might
@Artem Razin thanks for your participation, i will investigate around profiler, i never used one before.Perilymph
@StaceyGirl Mingw64, I imagine.Annettannetta
"Increasing usage of memory" -- how high have you measured it? What values/columns exactly?Denning
B
1

Found it! Quite an old post, don't known if it's still relevant for you.

The problem seems to be using g++, mingw64 and the std::shared_mutex (at least version 12-posix).

In fact, there is a memory leak in the C++ library using the standard header file, <shared_mutex>. The pthread_rwlock_destroy is not called when PTHREAD_RWLOCK_INITIALIZER is used to initialize the mutex. However, pthread_rwlock_destroy is called as expected when using the pthread_rwlock_init version.

I found a way around and a fix. The easy way is to "disable" the constant initializer PTHREAD_RWLOCK_INITIALIZER from your source code; this forces the C++ library to call the pthread_rwlock_init function, then the pthread_rwlock_destroy function. To do that, just insert an #undef between #include <pthread> and #include <mutex>:

#include <thread>
#undef PTHREAD_RWLOCK_INITIALIZER
#include <mutex>
#include <shared_mutex>

The proper way is to patch the <shared_mutex> header file of the C++ standard library and call the pthread_rwlock_destroy function in the shared_mutex destructor, even if the constant initializer PTHREAD_RWLOCK_INITIALIZER is used.

If I find the way to and the time, I will submit a regular patch for the standard <shared_mutex> header file.

Branny answered 20/11, 2023 at 10:25 Comment(2)
Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.Bipartisan
This seems like a bug in winpthreads. The INITIALIZER macro should not exist if destroying the mutex requires a function call. Either you need a function call to create it and destroy it, or you use the initializer macro and don't need to do anything to destroy it.Scratchy

© 2022 - 2024 — McMap. All rights reserved.