LinuxQuestions.org
Download your favorite Linux distribution at LQ ISO.
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 12-02-2012, 08:10 AM   #1
nontas.v
Member
 
Registered: Jan 2012
Posts: 32

Rep: Reputation: Disabled
Question multithreaded programming with C, canceling some random threads fails sometimes


Hello everyone, again:P

I asked before some days something about pthreads and got some useful information so you might be able to help me again cause I'm stuck :/

I need to create a number of threads. There are 2 types of a thread. Let's say, type1 will be doing some work (e.g. doing a simple dummy loop) and type2 choses one random thread and cancels it.

I'll give a code to describe what I'm trying to do.
Code:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>

#define THREAD_NUM 20

pthread_t threads[THREAD_NUM];
pthread_attr_t pta[THREAD_NUM];

struct thread_data{
	int thread_id;
	int thread_type;
	int work; //when the thread is running it work will be set to "1" else "0"
};

struct thread_data tdata[THREAD_NUM]; 

int main(){
	for( i=0; i<THREAD_NUM; i++ ){
		tdata[i].thread_id=i;
		tdata[i].thread_type = //this will be 1 or 2 chosed by another function

		rc=pthread_attr_init(&pta[i]);
		rc=pthread_create(&threads[i], &pta[i], thread_fun, (void *)&tdata[i]);
		//error check
		if(rc){
			exit(-1);
		}
	}
	for( j=0; j<THREAD_NUM; j++ ){
		pthread_join(threads[j], NULL);
	}
	return 0;
}

void *thread_fun(void *threadarg){
	struct thread_data *uniquedata;
	uniquedata = (struct thread_data *) threadarg;

	uniquedata->work = 1; //set 1 as long it is working. When finished will set back to 0 again

	int taskid = uniquedata->thread_id;
	int tasktype = uniquedata->thread_type;
	
	//set cancelstate so it will be able for a thread to be deleted immediately
	pthread_setcancelstate(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
	
	if(tasktype==1){
		//do some work here (e.g. loop for some time more than 1 min to ensure that it can be canceled before it has finished)
	}
	else if(tasktype==2){
		//a random thread chosen to be deleted might have been ended or already canceled so we need some checking first
		int done=0;
		while(!done){
			//pick a random thread. (this is done by calling another function not needed here)
			//this random number (lets say dstr) will be between 0-THREAD_NUM ()
			//so now I will check if this thread is running
			if( tdata[dstr].work == 1 ){
				//report tdata and set done=1
				tdata[dstr].work=0;
				done=1;
				pthread_attr_destroy(&pta[dstr]); //destroy the attributes of the random thread chosen
				pthread_cancel(threads[dstr]); //cancel the chosen thread
				printf("Thread %d has been deleted succesfully!!!!!!\n", dstr);
			}
			else{
				printf("The random chosen thread %d has already been deleted or terminated. Chosing another..\n", dstr);
			}
		}
	}
	uniquedata->work = 0;
	pthread_exit(NULL); //not sure if I need this here
}
The problem is that when I run this program, some threads (not all!) will not be canceled for some weird reason (it seems like, in the "if( tdata[dstr].work == 1 )" line gets 0 instead of 1 :/

I understand that if a type2 thread wants to cancel some other type2 may not succeed because it has already done its work and exited, but this happens also with type1 threads.

I tried also to use mutexes but had the same problem again..
I hope this code is undestanable though :P

any help would be appreciated, I'm stuck here for 4 days and can't figure out what's happening.
If I said something silly excuse me but it's my first time writing multithreaded code :P

Thanks for your time, n.v

Last edited by nontas.v; 12-02-2012 at 08:38 AM.
 
Old 12-02-2012, 08:19 AM   #2
johnsfine
LQ Guru
 
Registered: Dec 2007
Distribution: Centos
Posts: 5,286

Rep: Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197
I think the thing making your post too wide to read is your choice to use a PHP block rather than a CODE block for your code. Try editing the first post an fixing that. Meanwhile, I'm not sure whether it is worth struggling to read whatever it is you asked.
 
Old 12-02-2012, 08:22 AM   #3
nontas.v
Member
 
Registered: Jan 2012
Posts: 32

Original Poster
Rep: Reputation: Disabled
Thought it would be easier this way, no problem i'm gonna edit it. thanks
 
Old 12-02-2012, 08:27 AM   #4
johnsfine
LQ Guru
 
Registered: Dec 2007
Distribution: Centos
Posts: 5,286

Rep: Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197
I see an ugly looking race condition, but I can't guess whether that is a significant part of your problem:
Code:
if( tdata[dstr].work == 1 ){
	//report tdata and set done=1
	tdata[dstr].work=0;
 
Old 12-02-2012, 08:29 AM   #5
nontas.v
Member
 
Registered: Jan 2012
Posts: 32

Original Poster
Rep: Reputation: Disabled
Well I also think that this is where it goes all wrong but I'm not able to find a solution though :/
 
Old 12-02-2012, 08:35 AM   #6
johnsfine
LQ Guru
 
Registered: Dec 2007
Distribution: Centos
Posts: 5,286

Rep: Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197
Also, I don't understand the lock in the partial code you posted. There doesn't seem to be anything that stops you from canceling the thread that holds the lock. IIUC, once you do that, no other thread can get the lock. So threads might wait indefinitely before the step that sets work to 1.

Code:
pthread_mutex_lock(&lock);
uniquedata->work = 1; //set 1 as long it is working. When finished will set back to 0 again
pthread_mutex_unlock(&lock);

Last edited by johnsfine; 12-02-2012 at 08:36 AM.
 
Old 12-02-2012, 08:38 AM   #7
nontas.v
Member
 
Registered: Jan 2012
Posts: 32

Original Poster
Rep: Reputation: Disabled
oops this was some testing I did with no success :P I forgot to delete these lines. Sorry I'm just a bit tired -.-
(i'll edit and remove that)
 
Old 12-03-2012, 02:48 PM   #8
nontas.v
Member
 
Registered: Jan 2012
Posts: 32

Original Poster
Rep: Reputation: Disabled
Well I found the problem. The threads that wouldn't be deleted were not started yet...so dummy!
I just say it cause, who knows, if sometime somebody has a similar problem
 
  


Reply

Tags
pthread



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
multithreaded programming - monitoring applications emge1 Programming 13 10-02-2006 10:00 AM
new to multithreaded programming... why is TLS needed? chlimouj Linux - Kernel 1 08-30-2006 06:56 AM
multithreaded programming and TLS chlimouj Programming 2 08-29-2006 01:00 AM
Closing Socket in MultiThreaded Application Fails laalitseth Red Hat 0 04-21-2004 12:44 AM

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

All times are GMT -5. The time now is 12:06 AM.

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