multiple threads NOT being destroyed?

Hello,

I have a program which receives a pulse every 1kHz. Each time the process receives a pulse, it starts a thread which inputs values from the parallel port and does some minor calculations (<<1msec, more like 0.001msec). The process appears to crash after a certain point and when I open another terminal window, and type ‘pidin’, I find that my process has something like 30,000 threads. The terminal window in which it was created freezes also, and I cannot seem to kill/slay the process. Any ideas?

Here is the code I am using to start the threads:

while(1)
{
rcvID = MsgReceive( chID, &mMessage, sizeof(msg), NULL );
if ( rcvID==0 )
{
if ( mMessage.pulse.code==ReadPP )
{
if ( FLAG_CheckPP==0 )
pthread_create( NULL, NULL, &ReadPP, NULL );
else
MISSED_LOOPS++;
}
}
}

void *CheckPP( void *nu )
{
FLAG_CheckPP=1;

…do some calculations with in8()…

FLAG_CheckPP=0;
}

Thanks,
Matt

You start a thread every 1ms, really not advisable. Instead have a thread waiting for a request to read and process the data.

If there is 30000 threads then it means that you are not terminating the thread. You are most likely running out of resources.

Why don’t you post the code of your thread.

Here is the code for the thread:

void *CheckPP( void *notused )
{
FLAG_wkTh_CheckPP = 1;

AB = in8( data_port );
if ( AB!=ABp )
{
    if ( (AB&Asensor)>0 )   A=1;  else A=0;
    if ( (AB&Bsensor)>0 )   B=1;  else B=0;
    if ( A!=Ap )
    {
        if ( A==1 && B==0 ) dir=1;
        else if ( A==1 && B==1 ) dir= -1;
        else if ( A==0 && B==0 ) dir= -1;
        else if ( A==0 && B==1 ) dir= 1;
    }
    else
    {
        if ( B==1 && A==0 ) dir=-1;
        else if ( B==1 && A==1 ) dir=1;
        else if ( B==0 && A==0 ) dir=1;
        else if ( B==0 && A==1 ) dir=-1;
    }
    pos+=dir;
    if ( dir==1 ) printf("CCW"); else printf("CW");
    printf(" with pos %i\r",pos); fflush(stdout);
    
    ABp=AB;
    Ap=A;
    Bp=B;
}

FLAG_wkTh_CheckPP = 0;

}

If I create a thread that blocks until it receives a message to do the above work, and while it is doing that work, it receives another pulse to start again, how can i prevent this from happening? I don’t want there to be a queue of pulses waiting, but rather, i want this executed every, say 1msec.

Thanks again,
Matt.

Lots of ways:

  • At the end of the thread consume all pulses with while ( MsgReceivePulse() != -1 ).
  • At the start of the thread check the time and if it’s less then 1ms just return.
  • Raise the priority of the pulse to make sure this gets executed in less then 1ms.

The way you’ve done it doesn’t privent multiple thread from running at the same time, because when pthread_create is called there is no way to tell how long it will take for the thread to start. So upon receiving the next pulse it’s very possible that FLAG_CheckPP (or is it FLAG_wkTh_CheckPP) has not yet been set to 1.

General programming tips if I may.

  • Don’t give variable a name with just one letter. Rather meaningless, makes search and/or search and replacce a nightmare. Makes it hard to understand.

  • If possible avoid using global variable, put all the variables in a structures and pass it as an argument to the thread. That’s very object oriented, very modular ;-)

If you actually want your operation to happen only every 1ms, then I don’t see why you use multiple threads. Just one thread, receiving the pulse, doing what it has to do, and go back to wait for the next pulse. If you think your thread takes more than 1ms, or if higher pri threads delay your threads, you can do as suggested by mario and drain the pulse queue. This would have the advantage that you know how much pulses you actually didn’t receive on time.

If you really need multiple threads, don’t create them when the pulse arrives - this delays the execution of your calculation, because first the thread needs to be created. Instead, use pre-created threads, e.g. a thread pool, so when ever a pulse arrives a thread is there to serve it.

Thanks guys, I will implement your suggestions, they are more than reasonalble.

A while back I used this exact method (create a thread everytime a pulse arrives) to control a 1000W laser to melt metal. It appeared to work fine. I guess I was lucky.

Matt.

It’s not that it doesn’t work, it’s just that it used way more CPU cycles then it has too.