LinuxQuestions.org
Visit Jeremy's Blog.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 04-04-2008, 02:06 PM   #1
lali.p
Member
 
Registered: Jan 2007
Distribution: Slackware 11.0
Posts: 141

Rep: Reputation: 16
How to cancel a thread


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;
}
I compiled withe the following option in Linux

g++ -ansi -pedantic-errors -Wall -lpthread thread_cancel.cpp



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
 
Old 04-04-2008, 04:55 PM   #2
abolishtheun
Member
 
Registered: Mar 2008
Posts: 183

Rep: Reputation: 31
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...
 
Old 04-05-2008, 09:48 AM   #3
ta0kira
Senior Member
 
Registered: Sep 2004
Distribution: FreeBSD 9.1, Kubuntu 12.10
Posts: 3,078

Rep: Reputation: Disabled
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

Last edited by ta0kira; 04-05-2008 at 09:50 AM.
 
Old 04-05-2008, 01:24 PM   #4
lali.p
Member
 
Registered: Jan 2007
Distribution: Slackware 11.0
Posts: 141

Original Poster
Rep: Reputation: 16
Quote:
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
 
Old 04-07-2008, 09:22 AM   #5
ta0kira
Senior Member
 
Registered: Sep 2004
Distribution: FreeBSD 9.1, Kubuntu 12.10
Posts: 3,078

Rep: Reputation: Disabled
Here is an example:
Code:
#include <pthread.h>
#include <time.h>
#include <stdio.h>
 
 
static void *thread(void *aArgument)
{
    //Always disable cancelability up front to control it
    if (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 applicable
    if (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 points
    if (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 thread
    if (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.)

Last edited by ta0kira; 04-07-2008 at 11:39 AM.
 
Old 04-07-2008, 02:04 PM   #6
lali.p
Member
 
Registered: Jan 2007
Distribution: Slackware 11.0
Posts: 141

Original Poster
Rep: Reputation: 16
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.


Regards
lali.cpp
 
Old 04-07-2008, 05:02 PM   #7
ta0kira
Senior Member
 
Registered: Sep 2004
Distribution: FreeBSD 9.1, Kubuntu 12.10
Posts: 3,078

Rep: Reputation: Disabled
Quote:
Originally Posted by lali.p View Post
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
 
Old 04-08-2008, 08:55 AM   #8
lali.p
Member
 
Registered: Jan 2007
Distribution: Slackware 11.0
Posts: 141

Original Poster
Rep: Reputation: 16
Wink

thanks for all your patience in helping me.
Would go by your way(since it's working )



Regards
lali.cpp
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
How do I cancel my id? dickd LQ Suggestions & Feedback 7 10-08-2006 10:50 AM
Cancel printing jobs Imerion Linux - Software 3 01-12-2005 03:07 PM
Can't cancel a print job........ soujrnr Linux - Software 0 10-03-2004 08:52 PM
Cancel All Scheduled Jobs? Rv5 Programming 1 09-17-2004 08:39 PM
cancel shutdown kc8tbe Linux - General 3 06-02-2003 08:39 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 09:34 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration