Before using a pthread_mutex_t pthread_mutex_init() should be called, and after it's not longer required it should be destroyed using pthread_mutex_destroy().
My question is, what happens if my process terminates before it can call pthread_mutex_destroy(), for example a SIGKILL, SIGINT or SIGABORT? Is it possible that some resource will leak?
Same question goes to pthread_cond_init/destroy as well.
Not on any platform you're likely to use. Objects like mutexes and condition variables are just chunks of memory in the process' address space. When a process terminates, its address space ceases to exist. So it's not possible for any resources to leak.
Process-shared resources are more complex. While the resources won't leak, they may still exist and may even still be in use by other processes.
Related
It is expected that threads, on which pthread_detach() was not called, should be pthread_join()ed before the main thread returns from main() or calls exit().
However, what happens when this requirement is not met? What happens when a process terminates when it still contains unjoined and not detached threads?
I would find it odd to learn that these other threads’ resources will not be reclaimed until system reboot. However, if these resources will be reclaimed, then there may be little need to bother about joining or detaching, mightn’t it?
It is up to the operating system. Typical modern operating systems will indeed reclaim the memory and descriptors (handles) used by abandoned threads. This is similar to how dynamically allocated memory works: typical modern systems will reclaim it when a process exits, even if the process never explicitly freed the memory. For certain unusual programs, this can be a meaningful performance optimization, because freeing lots of small resources takes time and the OS may be able to do it more quickly.
However, what happens when this requirement is not met? What happens when a process terminates when it still contains unjoined and not detached threads?
On any system with POSIX threads that is not ancient, the non-joined threads simply "evaporate" into space when the SYS_exit system call is performed by the main thread.
I would find it odd to learn that these other threads’ resources will not be reclaimed until system reboot.
They will be.
However, if these resources will be reclaimed, then there may be little need to bother about joining or detaching, mightn’t it?
It depends on what these threads do. The danger is at-exit data races.
In C++, global variables are destructed (usually via atexit or equivalent registration mechanism), FILE handles are deleted, etc. etc.
If non-joined thread tries to access any such resource, it will likely crash with SIGSEGV, possibly producing core dump, and an unclean process exit code, both of which are often quite undesirable.
In my program written with C and C++, I will new an object to fulfill the task, then delete the object.
At the moment after new object but before delete object, if the user presses ctrl+c to break the process, that will cause delete not to be called and a memory leak occurs.
What should I do to avoid this situation?
Also, if the memory was reclaimed by the OS, what about the opened files? Are they closed by the OS or should I close them manualy?
In a virtual-memory-based system, all memory is returned to the OS when a process is terminated, regardless of whether it was freed explicitly in the application code. The same might not be true of other resources, however, which you may want to free cleanly. In which case, you need to provide a custom signal handler for the SIGINT signal (which is received on Ctrl+C), see e.g. http://linux.die.net/man/2/sigaction.
Pressing CtrlC will send a SIGINT to the process, which by default does a mostly-orderly shutdown, including tearing down the memory manager and releasing all allocated heap and stack. If you need to perform other tasks then you will need to install a SIGINT handler and perform those tasks yourself.
If you allocated any SYSV Shared Memory Segments using shmget(2) then you must clean up after yourself with shmctl(2).
If you allocated any POSIX Shared Memory Segments using shm_open(3) then you must clean up after yourself with shm_unlink(3).
Both SYSV and POSIX shared memory segments persist past process termination. You can see what persists using the ipcs(1) tool.
Of course, if you haven't used any SYSV or POSIX shared memory segments, then this is all just noise. :)
You are subscribing to a rather common misconception that heap blocks that are not freed, but still accessible at the time a program exists are leaks. This is not true. Leaked blocks are those which no pointer still references, hence they can't be freed.
Through the years of playing with (and breaking) lots of perfectly good kernels, I have never managed to sufficiently break a virtual memory manager to the point where it no longer reclaimed the entire address space of a process once it exited. Unless you are working with a kernel clearly marked as 'new and experimental', you will have better luck winning the lottery than finding a system that doesn't employ an effective virtual memory manager.
Don't put cruft in your code just to get a perfect score in Valgrind. If you have no real clean up tasks to do other than freeing memory that still has valid references, you don't need to bother. If someone throws a kill -9 to your program, you won't be able to handle it and will see the old behavior repeat.
If you have file descriptors to clean up, shared locks to relinquish, streams to flush or whatever else must happen so other processes don't miss you when you're gone, by all means take care of that. Just don't go adding code that does nothing to solve a non-problem, it just seems silly to do so.
Note
This was originally going to be a comment, but is far too long and SO frowns on writing a novel one comment at a time.
When CTRL+C is pressed in a Linux console, the SIGINT signal is sent to the application which, if the signal has no handler, will terminate the program, returning all memory to the OS. This of course would make it pointless to do any freeing of memory, since all memory will freed once the program exists. However, if you would like to handle the CTRL+C SIGINT signal (maybe to write out some last data to a file or do some other cleanup), you can use the function signal() to install a function to be called when the signal is received. Check out the man page for this function if you want to learn more.
If the process quits, a memory leak will NOT normally occur.
Most of the memory you allocate will be freed on Ctrl+C. If you see memory usage not return to its prior level, it is almost certainly caused by buffered filesystem blocks.
However, you should definitely clean things up, in particular if you have used any other types of resources:
Files created in temporary directories won't be deleted. This includes /dev/shm, leaving such a file could be considered a "memory leak".
System V or posix shared memory segments won't get thrown away when your process quits. If this bothers you, clean them up specifically. Alternatively, clean them up on a subsequent run.
Normally a leak (of a persistent or semi-persistent object e.g. file) doesn't matter if a subsequent run doesn't leak more memory. So cleaning up on a future run is good enough.
Imagine a process running every 5 minutes from "cron", if it crashes on each run and leaves some mess, it's still ok provided each run cleans up the mess from the previous crash.
The OS will reclaim the memory allocated by the process when the process exits as a result of Ctrl-C or any other means.
On linux, pthread (linux threads),
what does happen to the running threads when returning from main (before the threads are finished)?
When returning from main, the memory is dis-allocated so the threads should access unallocated memory. Does this cause the threads to exit?
I'm sure the threads are killed, but how does this actually happen?
I'm sure the threads are killed, but how does this actually happen?
Returning from main is the same as calling exit(). This means handlers established by atexit(), and any system cleanup handlers are run. Finally the kernel is asked to terminate the entire process(i.e. all threads).
(Note that this might cause issues if you have other threads running at that point, e.g. another thread accessing a global C++ objects right after the runtime calls their destructors.)
Well, threads operate under the process of main application (or other process but I assume you do not create another process, just threads). They share memory with it, and are the same process, so is system kills the process it automatically kills all threads. There is nothing more to it. A thread cannot exists without a process, so there is no option of accessing some disallocated memory, it just stops executing, and the memory is cleaned up on a process clean-up level.
And how it happens is obviously system dependent. E.g. Windows 95 did not free memory after a process ended, so if application had a memory leak, killing it didn't help. This had changed since then. Every system can handle it differently.
I experience some memory allocation problems and try to detect possible reasons for these problems.
There are many possible reasons, and lots of hours must be spent to check each of them.
One of the possible reasons is that there is a memory buffer, that is allocated within a thread, and this buffer is used after the thread terminates.
So, if there is a chance that thread termination causes memory deallocation, then many hours of debugging may be avoided.
Thank you very much in advance.
I don't think it does, although it of course might depend on your particular details.
Generally, memory allocation from the operating system's point of view is a per-process activity, while threads exist inside the process. So if one thread allocates memory and then dies, the operating system doesn't clean that up since the process is still alive. Memory is shared inside the process, so the OS can't know that the memory no longer is used and can be cleaned up.
No, threads that 'die' do not deallocate any memory.
When a thread ends, the thread itself vanishes from memory, like a function does once it's done executing. It will take all the 'stack' objects with it, but all the memory you allocated yourself (i.e. malloc) will still be there.
As such, before you end your thread, you should make sure that all dynamic memory that was used by the thread and is not needed any more is freed properly.
Anything on the thread's stack (a local variable, for example) becomes invalid when the thread ends. However, if the data is in the heap, then the memory is still valid as long as the process is running. Of course, you'll need to save the pointer to that heap allocation somewhere outside that thread.
Memory allocated by a thread behaves like memory allocated by a method call:
variables on the stack will be dealocated when the method returns (thread terminates)
variables on the heap will continue to be allocated unless explicitly deallocated.
In addition to all answers, I'd like to make a note that pthread has a TLS keys which are registered with pthread_key_create which accepts key ID and destructor functions. On pthread_exit a static pthread_key_clean_all() is called that iterates through the keys and invokes assigned destructors that may perform memory deallocation (by application design).
So, to understand that - search in your code all pthread_key_create invocations, check if a destructor assigned and the put breakpoints to all of them to check what and in which order is destroyed.
I have a thread function which allocates memory using malloc(). I kill the thread using pthread_kill without freeing the dynamically allocated memory.Will it be freed automatically once i call pthread_kill or there will be a leak?
Memory you are allocating in one thread doesn't "belong" to that thread. It is allocated from the same global heap all the other threads are using your program. So you have to free all the memory you have allocated otherwise you end up with a leak.
As vicatcu says, there will be a leak.
I wouldn't ever recommending using pthread_kill unless you absolutely have to. Instead, you should create a signaling mechanism to let the thread know when it should be finished, and then join on the thread. And the thread function should poll that value occasionally, and if it gets a terminate signal, it should clean up its own resources and exit.
The other option, of course, is to try not to allocate memory in threads. But I guess you don't always get that luxury. :-)
there will be a leak. how would pthreads kill function possibly know the names of variables that have been assigned via malloc? There is no garbage collection in C, if you call malloc somewhere, you better make sure that you call free somewhere else.
[Edit]
Maybe you should just set a global flag variable associated with your thread, and have your thread poll that variable occasionally to know if and when it should terminate itself.
Yes, assuming you don't install a signal handler for the signal you use and the default action for the signal is process termination.
That's because pthread_kill does not kill a thread, it sends a signal to the thread. If the action of that signal is to terminate the process, then the whole process ceases to exist, and with it, any dynamic memory allocated by any thread in the process.
There is no way to kill a thread.