I want to implement a very simple design with pthreads:
From this image you only need to know that I have one thread that is created with start() and is destroyed with stop(), and inside the thread, there is a function that loops infinitely until stop() is called.
This what I have (mutexes are omitted):
int running = 0;
pthread_t thread;
void* fn (){
while (1){
if (!running) break;
if (foo ()){
//Error, how should I handle it?
//The main thread is still not waiting with join()
}
}
pthread_exit (0);
}
int start (){
running = 1;
if (pthread_create (&thread, 0, fn, 0)){
return -1;
}
return 0;
}
int stop (){
running = 0;
if (pthread_join (thread, 0)){
return -1;
}
return 0;
}
Usage:
start ();
//At this point the infinite loop is running
//Let's say that in the second 1 something fails inside the loop
//How can I handle the error if join() is still not called?
sleep (3);
stop ();
One solution to this problem is to use a callback. The error is passed to the main thread via a function passed as paramater to the secondary thread. The big problem with this is that I'm converting the program into an asynchronous model, which I'd like to avoid for now.
I can save the error in a global variable and check it when stop() is called. More solutions?
I am not really sure that I understand your problem correctly, but for pthread_join your thread must not necessarily be running anymore. It is perfectly legal to join a dead thread. The only constraint is that you can only call join once for any thread.
You should then transfer the information why your thread stop through the return argument of the thread function, that is what it is meant for, and your stop thread will receive that through the second parameter of join.
Also
your thread function has an incorrect interface, this leads to undefined behavior. modern ABIs transfer function arguments in registers, and here the two sides may have a different vision of which registers are safe to use
you only need pthread_exit when you return from another function than the thread function itself. a normal return would do.
Related
The nanosleep implementation of winpthreads, which is a port of POSIX threads to Windows, calls pthread_testcancel multiple times in its implementation.
nanosleep in [nanosleep.c] calls pthread_delay_np_ms which is not exported and does the actual sleeping. This is the code of pthread_delay_np_ms in [thread.c].
int
pthread_delay_np_ms (DWORD to)
{
struct _pthread_v *s = __pthread_self_lite ();
if (!to)
{
pthread_testcancel ();
Sleep (0);
pthread_testcancel ();
return 0;
}
pthread_testcancel ();
if (s->evStart)
WaitForSingleObject (s->evStart, to);
else
Sleep (to);
pthread_testcancel ();
return 0;
}
You can see pthread_testcancel is called multiple times for some reason.
What is the reason for the additional code while I think this could be as simple as follows?
int
pthread_delay_np_ms (DWORD to)
{
Sleep (to);
return 0;
}
What does pthread_testcancel achieve? Also, a side question is why is WaitForSingleObject preferred over Sleep when a dummy event handle is available?
Another thread can call pthread_cancel in which case WaitForSingleObject will return immediately and the thread will be killed while your simple Sleep would keep a now pointless thread around for an unknown amount of time.
Why they are calling pthread_testcancel before Sleep(0) and if (s->evStart), I don't know. Maybe you should ask the authors directly if you care that much about it. I assume they are there for a reason...
I have a problem about main threads and other threads in the same process. When the main function returns, do the other threads exit too? I am confused about this.
Consider the following test code:
void* test1(void *arg)
{
unsigned int i = 0;
while (1){
i+=1;
}
return NULL;
}
void* test2(void *arg)
{
long double i = 1.0;
while (1){
i *= 1.1;
}
return NULL;
}
void startThread ( void * (*run)(void*), void *arg) {
pthread_t t;
pthread_attr_t attr;
if (pthread_attr_init(&attr) != 0
|| pthread_create(&t, &attr, run, arg) != 0
|| pthread_attr_destroy(&attr) != 0
|| pthread_detach(t) != 0) {
printf("Unable to launch a thread\n");
exit(1);
}
}
int main()
{
startThread(test1, NULL);
startThread(test2, NULL);
sleep(4);
printf("main thread return.\n");
return 0;
}
When the "main thread return." prints out, thread test1 and test2 also exit, can anyone tell me why?
You should use pthread_join() on each of the new threads, to inform the calling thread to wait on the sub-threads, suspending execution - and process exit - until those threads terminate.
Calling pthread_detach on the created threads won't keep them around after a process exits. From the linux man page:
The detached attribute merely determines the behavior of the system when the thread terminates; it does not prevent the thread from being terminated if the process terminates using exit(3) (or equivalently, if the main thread returns).
You'll sometimes see a pthread_exit in main used instead of explicit pthread_join calls, the intent being that exiting main in this way will allow other threads to continue running. In fact, the linux man page states this explicitly:
To allow other threads to continue execution, the main thread should terminate by calling pthread_exit() rather than exit(3).
But I don't know if this is expected behavior on all platforms, and I've always stuck to using pthread_join.
pthread_join requires the pthread_t for the target thread, so your code will need to change a bit since you need to create both threads before calling pthread_join to wait for them both. So you can't call it in startThread. You'll need to return a pthread_t, or pass a pointer to a pthread_t to your startThread function.
When the main thread returns (i.e., you return from the main function), it terminates the entire process. This includes all other threads. The same thing happens when you call exit. You can avoid this by calling pthread_exit.
The purpose of pthread_detach is to make it so you don't need to join with other threads in order to release their resources. Detaching a thread does not make it exist past process termination, it will still be destroyed along with all the other threads.
All the threads in your process will be terminated when you return from main().
The libc library is the one responsible for implementing this behavior by calling exit() when the main() function returns. In turn, the exit() function will end up calling a thin-wrapper function named _exit() which (starting from libc v2.3) will finally invoke the exit_group system call and end up your process and also terminate all its threads.
This last system call is the one responsible for the behavior you noticed.
We can see this subtle note in the _exit() manual here:
C library/kernel differences
In glibc up to version 2.3, the _exit() wrapper function invoked
the kernel system call of the same name. Since glibc 2.3, the
wrapper function invokes exit_group(2), in order to terminate all
of the threads in a process.
If your intention is to avoid this behavior, the only option is to call pthread_exit which will end your main thread and prevent you from returning to the libc's __libc_start_main() function.
If I have the following kernel thread function:
int thread_fn() {
printk(KERN_INFO "In thread1");
return 0;
}
Do I still need to use kthread_stop() function here?
Will return in the thread function make the kernel thread stop and exit?
If you look at how kthread() is implemented, at line 209 it calls threadfn(data) and stores the exit code in ret; then it calls do_exit(ret).
So a simple return from your threadfn is sufficient.
If you look at the documentation of kthread_stop, it says that it:
sets kthread_should_stop to return true;
wakes the thread;
waits for the thread to exit.
This means that kthread_stop() should be only called from outside a thread to stop the thread. Since it waits for the thread to finish, you must not call this inside the thread or you might deadlock!
Moreover, the documentation says that it only informs the thread that it should exit, and that the thread should call kthread_should_stop to find out about this. So a long-lived threadfn might do this:
int thread_fn() {
printk(KERN_INFO "In thread1");
while (!kthread_should_stop()) {
get_some_work_to_do_or_block();
if (have_work_to_do())
do_work();
}
return 0;
}
But if your function is not long-lived, calling kthread_should_stop is not necessary.
I have a question about pthreads whith this little C source:
int calc = 0;
void func(void* data){
calc = 2 * 2;
return NULL;
}
int main(){
pthread_t t;
if(0==pthread_create(&t,NULL,func,NULL)){
if(0==pthread_join(t,NULL)){
printf("Result: %d\n",calc); // 4 ?
}
}
}
If pthread_join return success, is "func" always executed entirely ? (calc always equal 4 on printf ?).
The function pthread_join returns zero on success.
The documentation says that pthread_join blocks until the thread ends, so, with some applied logic one can easily conclude that the thread has ended.
On the other side, pthread_join fails in different ways:
When the handle is invalid: EINVAL
When a deadlock has been detected: EDEADLK
There is another possible error (recommended by the open group, but depending on the implementation): ESRCH, when it detects that the thread handle is being used past the end of the thread.
If you want to know more you may want to take a look at the documentation.
I cant terminate the thread, it keeps sending things even after I close the terminal...
void *RTPfun(void * client_addr);
int main(int argc, char *argv[])
{
pthread_t RTPthread;
pthread_create(&RTPthread, NULL, &RTPfun, (void*)client_addr);
...
...
pthread_exit(&RTPfun);
return 0;
}
void *RTPfun(void * client_addr)
{
...
...
return 0;
}
Can someone tell me what am I doing wrong?
Thanks!
pthread_exit kills your current thread.
Notice, that if you kill the main thread as you do, it does not terminate the process. Other threads keep running.
You probably want to use pthread_cancel.
More generally though, killing threads is a bad idea. Correct way is to ask your threads politely to terminate and wait till they do.
If you call exit() from main, it will terminate main thread with all other thread.
If you call the method pthread_exit() from your main it will terminate main thread and let other thread will run continuously.
In your case you are calling pthread_exit() from main so your main thread get terminated, and other thread running until thread gets finish the job.
To cancel thread Add Below in RTPfun and add pthread_cancel in main.
/* call this when you are not ready to cancel the thread */
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
/* call this when you are ready to cancel the thread */
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
Working sample code:
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
void *RTPfun(void * client_addr);
int main(int argc, char *argv[])
{
pthread_t RTPthread;
int client_addr;
pthread_create(&RTPthread, NULL, &RTPfun, (void*)client_addr);
sleep(2);
pthread_cancel(RTPthread);
pthread_join(RTPthread, NULL);
return 0;
}
void *RTPfun(void * client_addr)
{
int count = 0;
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
while(1) {
if(count > 10) {
printf("thread set for cancel\n");
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
}
sleep(1);
printf("count:%d\n", count);
count ++;
}
return 0;
}
Used sleep in code for just understanding.
My understanding:
From "man pthread_exit" clearly talks about the description and rational behavior.
we will need to clean-up all respected resource that are been used in the thread created.
" The pthread_exit() function shall terminate the calling thread and make the value value_ptr available to any successful join with the terminating thread."
we shall pass "value_ptr" to exit(value_ptr) --> this will help to analyse what was the results of exit process.
obviously exit() - call exiting from the process, will release resources that used for.
In other way, you can create pthread in detached state, this attribute will reclaim the resources implicitly when pthread_exit . Refer "man pthread_detach".
We don't need to use pthread_join .. either go for pthread_detach again its simple go ahead set attribute .
/* set the thread detach state */
ret = pthread_attr_setdetachstate(&tattr,PTHREAD_CREATE_DETACHED);
Thanks.
Sankar
Your pthread_exit() exits the current thread. The parameter is used to pass a return value to any thread that then wants to join with it - and not to specify which thread to exit, as your code is implying.
The nicest way to do what you want is to use pthread_cancel() from your main thread. It takes the thread to cancel as a parameter, and then sends a cancellation request to that thread. Notice though, that by default cancellation is deferred, so your thread will keep on running until it hits a function that is a cancellation point - if you don't use any of those functions, you can insert an explicit cancellation point with a call to pthread_testcancel().
If you need to do some cleanup (for instance to free allocated memory, unlock mutexes, etc), you can insert a cleanup handler that is automatically called when canceling the thread. Have a look at pthread_cleanup_push() for this.
You can also set your thread to use asynchronous cancellation - your thread can then be canceled immediately, without hitting a cancellation point. However, asynchronous cancellation should only be used if you aren't using any system calls at all (that is, it's okay if you're purely doing calculations on already available data - but not if you're for instance using printf, file I/O, socket communication or similar), as otherwise you'll risk your system ending up in an inconsistent state.
After calling pthread_cancel(), your main thread should call pthread_join() on the canceled thread, to make sure all thread resources are cleaned up (unless you create the thread as detached).
You can of course also just have a shared doExit flag between the two threads, that the main thread can set, and which the other thread looks at from time to time. It's basically a manual way of using pthread_cancel().