threads

Hi pple,

I would like to learn frm you guys what is the best method to do this. I have a main process and a thread running. If i need the thread to run only when the main process tells it to, how do i go abt doing it? is it by message passing?

Thanks alot of your help

What exactly are you trying to acheive. Yes message passing would be an option. mutex/semaphores/pipes/FIFO/priority could be used as well.

i have a main process running a electrical drive system and a hydraulic drive system. I need a thread to monitor and maintain the position of the hydraulic joints at real time. However i only need the thread
to maintain the position only at certain conditions. And also the main process must not be blocked. I only want the thread to b ‘wait-blocked’ until the main process calls for it to maintain position.
Do u tink msgsendpulse will help in tis situation? becoz sending of pulse will not block my main process and also, receiving of pulse will allow the thread to wait for instruction before maintaining position.

THanks alot for your reply

sorry juz to add on… i also need the thread to b constantly maintaining the position until the main process tells it to stop…
so is ‘msgsendpulse’ the way to do it?

Sounds good to me.

There are many ways to skin this particular cat…

We do something a little differently, mostly because of the addition of many other threads to perform other tasks as well (comms, non-blocking logging, status monitoring, multiple controllers, etc.). Firstly, we implement a state machine (based on code from M. Samek’s “Practical Statecharts in C++”) so that all threads can access a threadsafe (mutex protected) method GetCurrentState(). Also implemented is a WaitForStateChange() which uses a pthread condition to block any threads until a state transition occurs. When the state machine makes a transition it calls a pthread broadcast on the condition to unblock all threads waiting on it.

Each thread performing stateful behaviours (while it is still running) checks to see if the system is currently in a state which requires it to operate. If it is in an operating state it performs whatever task is appropriate for that state, if it is not, it calls WaitForStateChange() to block pending a state transition.

The equivalent of your “main” thread (or any other source of an event which affects the state machine) then triggers the changes as required.

Depending on the complexity of the system this solution is very flexible, but may be unnecessarily complicated for your simple application described.

Yet another alternative would be to use a conditon and a state variable. You will need a mutex, a condition and a bool either in global memory (yuk!) or in a singleton object which can be owned by the two threads simultaneously. The child thread should look something like (we wrap the pthread calls into C++ classes for coding simplicity):

while( ThreadStillRunning ) // or something like this
{
sharedMemory.controllerMutex.Lock();
while( sharedMemory.controllerRunning == false ) // see the pthreads docs for details of why a while loop
{
sharedMemory.controllerCondition.Wait( sharedMemory.controllerMutex );
}
sharedMemory.controllerMutex.Unlock();

// do controlling stuff
}

The drawback is that you lock/unlock the mutex every time you pass through the control loop. You might consider only checking the controller status every n steps of the control loop, with the reduced checking of the status variable, but this will reduce the responsiveness of the controller to a stop signal (which may not be a problem for you). The controller will start as soon as the scheduler lets it once the condition has been signaled with the appropriate value for controllerRunning.

The main thread will then do the following to start the thread:

sharedMemory.controllerMutex.Lock();
sharedMemory.controllerRunning = true;
sharedMemory.controllerCondition.Signal();
sharedMemory.controllerMutex.Unlock();

and to stop it, simply changes the bool controllerRunning to false.

Caveat: unless I have screwed up with the ordering of the locks and unlocks this example should not deadlock - but I have been known to screw these up before :blush:

tks alot of all the suggestions!!! i will try out again and will update u guys!!

hie people, i am still having some problems with the synchronisation. Currently the situation is as such: I have a main process running the ‘user interface’, 1 thread constantly updating the hydraulic joint angles and 1 more thread to correct the position error of the hydraulic joints at real time.

however, the hydraulic joint angles which is constantly updated is not that stable. Does mutexes work for global variables that are constantly changing? Do i need to mutex if the thread is only reading ?

You don’t need mutext if the data is read only and can be handle atomicly.

but the output is erroreous if i never use mutex at all.
what’s the meaning of ‘handle atomicly’ ?

Let’s assume you data is containt within a structure, one thread write to it, the other reads. If the structures contains 10 variables, they can’t be written at the same time. Thus when the reader reads the first and second variable, it’s possible that in between the two writes that the writer thread has written to the second variable, hence the data read by the reader thread is invalid.

An atomic operation is one that is indivisable, like reading or writting an integer.

It’s possible to use queue for example to setup a writer/reader thread without mutex. The writer writes data in the queue and the reader pulls the data out.

Mutex don’t care about the type of variable, they actually protect part of code. Hence ALL code that access the share variable must be protected by mutex.

how do u queue ?

anyway i have a problem with resource allocation. I have a thread constantly reading encoder counts at real time and converting the serial data into some useful global variable. Also i have another thread constantly sending output to the maintain the position at a delay of 50ms. That however, cause the updating thread’s values to come in slower, probably because the output thread is taking up all the CPU?. Is there any way to rectify the problem??

Is it by scheduling algorithm?

how do you queue. I like to use a struct like this

struct queue {

int head;
int tail;

int *data; // use what ever type you need
}

head is the index where you write, tail is the index where you read. The reader reads until tail == head. By carefullying doing the increment of head and tail you can have one thread doing the write and one thread doing the read without the need for any sync method.

As the problem you have, if the read is slower then the writer, then there is no solution then somehow making the read faster or slow down the write. Scheduling algorithm will not make a slow or badly design software faster ;-) I can’t be more specific then that without seeing your code.

hihi hope u can gif me some pointers pls… joint2 is the global variable that is constantly updated and having problems. this is my updating thread…that will read from the encoders the current position of my hydraulic arm.

void* function( void* arg )
{

int done,j,dir,angle,phase,output;
float duty,perct,difference;  
double org1,org2,ini1,ini2,trial;
char RS232_Buffer[20],rx_msg[12];
struct	timespec start,stop;
int rx_index, size,i,pos1,pos2,k;
double accum; 
    
ThreadCtl(_NTO_TCTL_IO,0);
for(;;)
{
	if(1)					// state&_DEV_EVENT_INPUT)
	{    
		size = read(RS232_fd1 , RS232_Buffer , sizeof(RS232_Buffer)); 	
		for(i=0;i<size;i++)
		{
			rx_msg[rx_index++]=RS232_Buffer[i];
			if(rx_index==MSGLGTH)
			{ 
				if(rx_msg[0]=='m')
				{	
					clock_gettime(CLOCK_REALTIME,&stop);
					accum=(double)(stop.tv_sec-start.tv_sec)+(double)(stop.tv_nsec-start.tv_nsec)/BILLION;
					update(&rx_msg[0] , (float)accum);
					 start.tv_sec=stop.tv_sec;
					 start.tv_nsec=stop.tv_nsec;
				}
				tcflush(RS232_fd1,TCIOFLUSH);
				if(DEBUG) 
				rx_index=0;
			}
		}	
	}
}

}

int update(char*msg, float delta)
{
float range; int i; double j1,j2;
char msg1[5],msg2[5];

range=atof(msg);
*(shmptr +ALT) = range*100.0;
*(shmptr + ALT +1) = delta;

    for(i=0;i<4;i++)
{ msg1[i] = msg[i+1];  

   	}
msg1[4] = '\0';
    j1=atof(msg1); 
   
	if(j1<800)
{	joint1=(j1/800)*(-360)*0.45;
	state1=0;	
              
}
	else
{	j1=(j1-5535)*(-360)/800; joint1=j1*0.45;
	state1=1; 
}


for(i=0;i<4;i++)
{msg2[i]=msg[(i+5)];

}
msg2[4]='\0';
    j2=atof(msg2);	

if(j2<800)
{	pthread_mutex_lock(&mutex3);
	joint2=(j2/800)*(360);
	//printf("\njoint2=%2.3f\n",joint2);
	pthread_mutex_unlock(&mutex3);
	state2=0; 
}

else
{	pthread_mutex_lock(&mutex3);
	j2=((j2-5535)/800)*360; joint2=(j2);
	//printf("\njoint2=%2.3f\n",joint2);
	pthread_mutex_unlock(&mutex3);
	state2=1;
}


return(0);

}

this is the pulsing thread that actually output to maintain the position of the hydraulic arm. and i have a main process running to take in input from the user to move to desired location.

void* pulse( void* arg )
{

int counter1,done,j,dir,angle,phase,output,g=4;
float duty,perct,difference;  
double org1,org2,ini1,ini2,trial;


ThreadCtl(_NTO_TCTL_IO,0); 

for(;;)
{		
	pthread_mutex_lock(&mutex); //locking to do the checking
	while (x != y) 
	{            
		pthread_cond_wait (&condvar, &mutex); 
	}
	pthread_mutex_unlock(&mutex);
	// finish checking .. unlock all mutex to 'y'
	
	pthread_mutex_lock(&mutex3); 
	if(abs(joint2-hydangle[1])>0.1) //checking for joint 2's drop 
	{	
		pthread_mutex_unlock(&mutex3); 
		hydraulic(hydangle,g);//4 is pulsing mode and hydraulic() is for outputing
		delay(1);
	}
	pthread_mutex_unlock(&mutex3); 
}
exit(-1);

}