Pthread_create () and memory leaks

This question seems to require a lot. I had some kind of inherited production code that seemed great until it started getting many more connections per day. Each connection started a new thread. In the end, it would run out of memory and failure.

I am returning through pthread (and C sockets), which I have not dealt with for years. The tutorial I had was informative, but I see the same when I use the top. All threads exit, but there is still some sort of virtual memory. Valgrind tells me that calling pthread_create () may result in memory loss. The simplest code example below.

The scariest part is that pthread_exit (NULL) seems to leave about 100 meters in VIRT missing when all threads terminate. If I comment on this line, it is much more acceptable for life, but still there. On my system, this starts at 14k and ends at 47k.

If the number of threads is up to 10,000, VIRT reaches 70+ concerts, but ends somewhere around 50 thousand, assuming I comment on pthread_exit (NULL). If I use pthread_exit (NULL), it ends with approximately 113 m in VIRT. Are they acceptable? Are not everyone telling me upstairs?

void* run_thread( void* id ) { int thread_id = *(int*)id; int count = 0; while ( count < 10 ) { sleep( 1 ); printf( "Thread %d at count %d\n", thread_id, count++ ); } pthread_exit( NULL ); return 0; } int main( int argc, char* argv[] ) { sleep( 5 ); int thread_count = 0; while( thread_count < 10 ) { pthread_t my_thread; if ( pthread_create( &my_thread, NULL, run_thread, (void*)&thread_count ) < 0 ) { perror( "Error making thread...\n" ); return 1; } pthread_detach( my_thread ); thread_count++; sleep( 1 ); } pthread_exit( 0 ); // added as per request return 0; } 
+6
source share
2 answers

Before you edit to add pthread_exit(0) to the end of main() your program will exit before all threads have finished. valgrind thus reported resources that were still supported by threads that were still active at the time the program ended, making it look like your memory leak.

Calling pthread_exit(0) on main() calls the main thread, waiting for all other spawned threads to complete before it exits. This allows valgrind observe a clean run in terms of memory usage.

(I assume Linux is your operating system below, but it looks like you are using some UNIX from your comments.)

The extra virtual memory you see is just linux, which assigns some pages to your program, since it was a large memory user. As long as the usage of your resident memory is low and constant, when you reach a state of inactivity, and the virtual use is relatively constant, you can assume that your system is behaving well.

By default, each thread receives 2 MB of stack space in linux. If each thread stack does not require so much space, you can adjust it by initializing pthread_attr_t and setting it with a smaller stack size using pthread_attr_setstacksize() . What size of the stack is appropriate depends on how much your function call stack grows and how much space the local variables for these functions take.

 #define SMALLEST_STACKSZ PTHREAD_STACK_MIN #define SMALL_STACK (24*1024) pthread_attr_t attr; pthread_attr_init(&attr); pthread_attr_setstacksize(&attr, SMALL_STACK); /* ... */ pthread_create(&my_thread, &attr, run_thread, (void *)thread_count); /* ... */ pthread_attr_destroy(&attr); 
+4
source

I know this is a pretty old question, but I hope others benefit. This is really a memory leak. A stream is created with default attributes. By default, the stream is joinable. Connecting threads retain their basic financial statements until it is finished ... and joined. If the thread never connects, set the Detached attribute. All (streaming) resources will be freed after the stream ends. Here is an example:

 pthread_attr_t attr; pthread_t thread; pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, 1); pthread_create(&thread, &attr, &threadfunction, NULL); pthread_attr_destroy(&attr); 
+2
source

Source: https://habr.com/ru/post/973348/


All Articles