Is it possible for a thread to clean up itself when it exits? I have the problem, that my thread calls some binary blob (via a function pointer) where I have no control about the resources it may allocate and I need some way to clean up everything as soon as the thread exits. Including memory, open file descriptors, created X-windows etc. Basically what exit() does, just that I don't want the main thread to exit.
I am currently using pthread and intercept all calls to malloc(), mmap(), open() and atexit() from inside the thread. When the thread finishes I then call the functions registered by atexit and call free(), munmap() and close() for the allocated resources.
This doesn't work however, because apparently there is a lot more going on. For example, naively closing FDs from a connection to X11 will crash the whole app.
I would like the OS to handle my thread exit as if it would be a normal process. Is that possible with pthread? If not, is there maybe another threading library that could do this?
Related
I'm writing code to save text to a binary file, which includes a function to auto-save text to the binary file, as well as a function to print from the binary file, and I need to incorporate pthread locks and join. We were given
pthread_mutext_t mutex;
pthread_t autosavethread;
as global variables, although the instructor didn't talk about what pthread or mutex actually do, so I'm confused about that.
Also, I understand that I need to use locks whenever shared variables are changed or read (in my case it would be the binary file). But at the end of the file I am supposed to use pthread_join, and I don't know what it does or what arguments are supposed to be used in it. I'm guessing mutex and autosavethread are supposed to be closed, or something along the lines of that, but I don't know how to write it. Can anyone help better my understanding?
There are two types of pthread - joinable thread & detached thread.
If you want to let a thread just take a task and go away once the task is done, you need the detached thread;
If you want to have the communication with the created thread when that thread is done with the assigned job, you have to use joinable thread. Basically it's needed when the parent & its created thread need to communicate after the thread is done.
It's very to google what exactly you need to call the pthread APIs and what can be communicated.
But one thing i want to mention here is, for the joinable thread, you have to explicitly call the pthread_join against the created thread. Otherwise, there will be serious memory leaks. When the joinable thread completes its task, the thread seems to exit (On linux, you can check the /proc/PID/task/ folder and once the thread completes, the entry under it will go away), but the resource allocated for this joinable thread, i.e. stack, is still there in the process memory space. As more and more joinable threads created and completing their tasks, the stacks for each thread are just left in process space, unless you explicitly call the pthread_join. Hope that helps, even a bit
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 am wondering, what can happen if we do a pthread_create without a pthread_join?
Who will "clean" all the memory of the "non-joined" thread.
When the process terminates, all resources associated with the process cease to exist. (This of course does not include shared resources the process created, like files in the filesystem, shared memory segments, etc.) Until then, unjoined threads will continue to consume resources, potentially calling future calls to pthread_create or even malloc to fail.
Well, assuming that it's an app-lifetime thread that does not need or try to explicitly terminate, the OS will do it when its process is terminated, (on all non-trivial OS).
If the thread is created without using pthread_join then when the main thread completes execution all other threads created in main function will be stopped and hence will not complete executing the whole statements in it.
Look at the documentation of Pthread_join.
It will make the main thread to suspend until the spawned thread completes execution.
i am using posix threads my question is as to whether or not a thread can cancel itself by passing its own thread id in pthread_cancel function?
if yes then what are its implications
also if a main program creates two threads and one of the thread cancels the other thread then what happens to the return value and the resources of the cancelled thread
and how to know from main program as to which thread was cancelled ..since main program is not cancelling any of the threads
i am using asynchronous cancellation
kindly help
Q1: Yes, a thread can cancel itself. However, doing so has all of the negative consequences of cancellation in general; you probably want to use pthread_exit instead, which is somewhat more predictable.
Q2: When a thread has been cancelled, it doesn't get to generate a return value; instead, pthread_join will put the special value PTHREAD_CANCELED in the location pointed to by its retval argument. Unfortunately, you have to know by some other means that a specific thread has definitely terminated (in some fashion) before you call pthread_join, or the calling thread will block forever. There is no portable equivalent of waitpid(..., WNOHANG) nor of waitpid(-1, ...). (The manpage says "If you believe you need this functionality, you probably need to rethink your application design" which makes me want to punch someone in the face.)
Q2a: It depends what you mean by "resources of the thread". The thread control block and stack will be deallocated. All destructors registered with pthread_cleanup_push or pthread_key_create will be executed (on the thread, before it terminates); some runtimes also execute C++ class destructors for objects on the stack. It is the application programmer's responsibility to make sure that all resources owned by the thread are covered by one of these mechanisms. Note that some of these mechanisms have inherent race conditions; for instance, it is impossible to open a file and push a cleanup that closes it as an atomic action, so there is a window where cancellation can leak the open file. (Do not think this can be worked around by pushing the cleanup before opening the file, because a common implementation of deferred cancels is to check for them whenever a system call returns, i.e. exactly timed to hit the tiny gap between the OS writing the file descriptor number to the return-value register, and the calling function copying that register to the memory location where the cleanup expects it to be.)
Qi: you didn't ask this, but you should be aware that a thread with asynchronous cancellation enabled is officially not allowed to do anything other than pure computation. The behavior is undefined if it calls any library function other than pthread_cancel, pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED), or pthread_setcancelstate(PTHREAD_CANCEL_DISABLE).
Q1. Yes,thread can cancel itself.
Q2. If one thread cancel another thread , its resources are hang around until main thread
join that thread with pthread_join() function(if the thread is joinable). And if the canceled
thread is not join in main thread resources are free with program ends/terminate.
Q3. I am not sure, but main program don't know which thread was canceled.
thread can cancel any other thread (within the same process) including itself
threads do not have return values (in general way, they can have return status only), resources of the thread will be freed upon cancellation
main program can store thread's handler and test whether it valid or not
I am writing an API that uses sockets. In the API, I allocate memory for various items. I want to make sure I close the sockets and free the memory in case there is a signal such as Ctrl-C. In researching this, it appears free() is not on the safe function list (man 7 signal) thus, I can't free the memory inside a signal handler. I can close the socket just fine though. Does any have any thoughts on how I can free the memory? Thank you in advance for your time.
Alternatively, don't catch the signal and just let the OS handle the cleanup as it's going to do during process cleanup anyway. You're not releasing any resources that aren't tied directly to the process, so there's no particular need to manually release them.
One technique (others exist too):
Have your program run a main processing loop.
Have your main processing loop check a flag to see if it should "keep running".
Have your signal handler simply set the "keep running" flag to false, but not otherwise terminate the program.
Have your main processing loop do the memory cleanup prior to exiting.
This has the benefit of placing both the allocation and de-allocation in blocks of code which are called with a known sequence. Doing so can be a godsend when dealing with webs of interrelated objects, and there is not going to be race condition between two processing flows trying to mess with the same object.
Don't free in the handler. Instead, indicate to your program that something needs to be freed. Then, detect that in you program, so you can free from the main context, instead of the signal context.
Are you writing a library or an application? If you're writing a library, you have no business installing signal handlers, which would conflict with the calling application. It's the application's business to handle such signals, if it wants to, and then make the appropriate cleanup calls to your library (from outside a signal-handler context).
Of course even if you're writing an application, there's no reason to handle SIGINT to close sockets and free memory. The only reasons to handle the signal are if you don't want to terminate, or if you have unsaved data or shared state (like stuff in shared memory or the filesystem) that needs to be cleaned up before terminating. Freeing memory or closing file descriptors that are used purely by your own process are not tasks you need to perform when exiting.