ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
Hi i am writing a simple program that i have run on Linux and i am totally confused in the idea of thread cancellation.
Here is the code :
Code:
#include<iostream>
#include<pthread.h>
#include<unistd.h>
using std::cout;
using std::cin;
using std::endl;
void *f(void *);
int main()
{
pthread_t thread_id;
pthread_create(&thread_id,NULL,f,(void *)NULL);
sleep(10);
if(pthread_cancel(thread_id)==0) // Does the return value of 0 mean that the thread has been cancelled or does it mean only that a cancellation point has been set ????????
{
cout<<"\n**************The thread has been cancelled*********************\n";
}
while(true)
{
cout<<"\nHi i am in main"<<endl;
}
return 0;
}
void *f(void *ptr)
{
while(true)
{
int a=5;
int b=4;
int c;
c=a+b;
//Line no. 38 //cout<<"\nHi i am in the thread function."<<endl;
/* Really stupid thing happens here when i compile and run this program in Linux.*/
/* What happens is that when i uncomment the line number 38 the program ends abruptly after sometime and gives the following output:
Continuoulsy prints "Hi i am in the thread function" for 10 seconds(i guess) and then the following output
FATAL:Exception not rethrown
Hi i am in the thread function
prints
Aborted*/
/* However when i comment the line 38 as i have done that now, programs just works fine and continuously prints " Hi i am in main "
*/
pthread_testcancel();
}
return 0;
}
However my expected output is that first this program should print "Hi i am in thread function for 10 seconds"
Then this thread should be cancelled and then main should continously print "Hi i am in main"
Here is the most interesting part. If i just replace line 38 with printf rather than cout it works as expected WOW !!!.
So i guess it's something related to cout that is throwing exception that is not being caught and causing abort to be called
And when i am cancelling the thread it's *corruting*(i don't know what word i shd use) cout and making it unfit for use
Please give some expert guidance (@ ta0kira)
Here is something, try following permutations :
Let's call int a=5;
in b=4;
int c;
c=a+b; as trivial work
Run the program on ur *nix machine and in thread function
* Remove the trivial work to print a line
*now run again with trivial work included and cout to print a line after trivial work.
* now again run with printf instead of cout in thread function and trivial work included
Please some one help me. The default thread is i guess created with PTHREAD_CANCEL_ENABLE and PTHREAD_CANCEL_DEFERRED
Correct me if i am wrong and please gimme some link on "How to cancel a thread"
The program that i am writing is much more complex than the above naive version and i want to *know* cancellability before proceeding.
Thanks & Regards
lali.cpp
This is too trivial a program but wanna learn thread cancellation
pthread_cancel returns 0 upon success. it does not wait for the thread to end, it merely sets the cancellation point. So yes, the cout statement in the main thread could run while the thread's cout statement is running and butt heads. But I'm really not sure how cout behaves in threads so can't really help you. I suspect it has something to do with the way it buffers...
pthread_cancel rarely works for me unless I explicitly enable and disable cancelability. Normally I disable at the first line of the thread and only enable it where I have a blocking system call, then disable it right after. If you have no blocking system calls in your thread, I'd add pthread_testcancel at the beginning of the loop and enable cancelation right before and disable right after. You also need to either pthread_join or pthread_detach to free the memory after you cancel it. Joining will probably freeze your program if you don't isolate cancelability. Joining also sometimes delays execution "arbitrarily", so unless you have a good reason I'd detach instead. It seems like you need to join here, so it shouldn't be a problem, but with very complexly threaded systems it sometimes causes delays.
ta0kira
pthread_cancel rarely works for me unless I explicitly enable and disable cancelability. Normally I disable at the first line of the thread and only enable it where I have a blocking system call, then disable it right after. If you have no blocking system calls in your thread, I'd add pthread_testcancel at the beginning of the loop and enable cancelation right before and disable right after. You also need to either pthread_join or pthread_detach to free the memory after you cancel it. Joining will probably freeze your program if you don't isolate cancelability. Joining also sometimes delays execution "arbitrarily", so unless you have a good reason I'd detach instead. It seems like you need to join here, so it shouldn't be a problem, but with very complexly threaded systems it sometimes causes delays.
ta0kira
What is a blocking system call ?( Do you mean calls like pthread_mutex_lock(&m_mymutex)) ??? Sorry i am newbie just trying my hands.
My code doesn't use any blocking system calls, i guess.
What i fail to figure out is what is problem in the code i mean why such an odd behaviour when i am using "cout" and normal behaviour with printf ?
I could get little from above reply as i really don't have any idea about thread cancellation and how cleanup happens.
Could you post some code(if you have some time).
I would read thread cancellation from the book "Programming on Posix threads" by D.R Butenhof and then would try to understand the above reply
I guess there ain't much on internet to give details about thread cancellation, i mean every 1 says it's tricky and should be done carefully but no one mentions a detail procedure to show how to do it with some real code.
Thanks for all your replies. Would revert if i have any queries
#include <pthread.h>#include <time.h>#include <stdio.h>
static void *thread(void *aArgument)
{
//Always disable cancelability up front to control itif (pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL) != 0) return NULL;
char input[256] = { 0x00 };
//Cancelation at a point such as this will probably cause an error
printf("starting thread...\n");
while (1)
{
//Use the lines below if you have no implicit cancelation points //Implicit cancelation points are noted in glibc docs as applicableif (pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL) != 0) break;pthread_testcancel();if (pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL) != 0) break;
fprintf(stderr, "input> ");
//Always enable cancelability when the thread might block//Most functions that block are implicit cancelation pointsif (pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL) != 0) break;
if (!fgets(input, 256, stdin)) break;
if (pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL) != 0) break;
fprintf(stderr, "you typed: %s", input);
}
//You don't need to enable cancelation here since the thread is exiting
printf("stopping thread...\n");
return NULL;
}
int main()
{
pthread_t new_thread = (pthread_t) NULL;
if (pthread_create(&new_thread, NULL, &thread, NULL) != 0) return 1;
printf("waiting 10s for thread...\n");
struct timespec delay = { 10, 0 };
nanosleep(&delay, NULL);
printf("canceling thread...\n");
//Always join or detach after canceling a threadif (pthread_cancel(new_thread) == 0)
{
#ifdef JOIN//This waits for the thread to exit
printf("joining thread...\n");
pthread_join(new_thread, NULL);#else//This doesn't wait for the thread to exit
printf("detaching thread...\n");
pthread_detach(new_thread);#endif
}
printf("program exit\n");
return 0;
}
ta0kira
PS pthread_join and pthread_detach can be used independently of pthread_cancel. Also, pthread_join is the only way to get the return value of the thread (as far as I know.)
Hi thanks for your reply.
I made the changes in my code and it's working fine. I also read cancellation from Butenhof.
However i have a very serious doubt now.
Consider the below code in the thread to be cancelled :
Code:
while(1)
{
pthread_testcancel();
cout<<"\nHi"<<endl;
int a=3;
int b=90;
int c=a+b;
}
I think that the above code should be safe if the thread executing the above code is cancelled from main. But why it is not ? Consider the fact that threads are by default cancelable and are deferred. It means that whenever we call pthread_cancel, the thread will be cancelled at cancellation point(which i have set as pthread_testcancel())
So why is the need to do this :
Code:
while(1)
{
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,NULL);
pthread_testcancel();
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE,NULL);
cout<<"\nHi"<<endl;
int a=3;
int b=90;
int c=a+b;
}
Sorry, i am bit confused. pthread_testcancel function sets a cancellation point it returns immediately if no cancel request is pending. However if any cancellation is pending, the function would do cleanup and terminate the thread.
So why is it unsafe in first code considering that the thread will only be cancelled at pthread_testcancel() cancellation point and not at any other point as rest of the code doesn't have any cancellation point (is cout cancellation point ??? i don't know may be ??, i am confused ).
I am confused . I have read a lot on net really yaar(friend) but just can't figure out how your code is working and mine not working.
I think that the above code should be safe if the thread executing the above code is cancelled from main. But why it is not ? Consider the fact that threads are by default cancelable and are deferred. It means that whenever we call pthread_cancel, the thread will be cancelled at cancellation point(which i have set as pthread_testcancel())
Theoretically you are right, but that's not how it works in reality. I learned the hard way, and disabling cancelability except for right before cancelation points was the only thing that removed strange bugs I received from canceling threads. If I had to guess, I'd say it has something to do with cleanup handlers, but I'm not sure.
ta0kira
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.