0

Here is my situation

global var n;
global var result;
void* solve_for_n(void *arguments)
{    does_something;
     put value calculated in result;
}
function main
{    for(n=1;n<30000;n++)
     {   set value of n;
         create pthread with address of function solve_for_n;
         wait for reply from pthread;
         if 5 seconds have passed tell pthread to exit;
     }
}

n is variable set by main .
Similiarly result is set by solve_for_n
I want to give 5 seconds maximum to pthread for solving else it should exit .
There are many more n values waiting in line .

Now , here is my code

#include<stdio.h>
#include<pthread.h>
#include<sys/time.h>
#define micro_second_multiplier 1000000

float interval;
unsigned long long int m;
unsigned int done,length,n;
int bye;
pthread_mutex_t timeisup;
void * solveforn(void *arguments)
{   
    unsigned long long int multiplicant,sum,quotient,divisor,product,multiplicantincremented,multiplicantdivisor;
    unsigned int flag,lenofn,maxnumofdigitinproduct,lenmultiplicant,digit;
    struct timeval begin, end;

    gettimeofday(&begin, NULL);
    printf("\nPthread begins");
    lenofn=0;
    divisor=10ll;
    do
    {   quotient=((unsigned long long)n)/divisor;
        divisor=divisor*(10ll);
        lenofn++;
    }while(quotient!=(0ll));
for(multiplicant=multiplicantincremented=1ll,flag=0,lenmultiplicant=1,multiplicantdivisor=10ll;flag!=1;multiplicant++,multiplicantincremented++)
    {   if((multiplicant%(2ll)==(0ll))&&(n%5==0))
        {   multiplicant++;
            if(multiplicantincremented==multiplicantdivisor)
            {   lenmultiplicant++;
                multiplicantdivisor=multiplicantdivisor*(10ll);
            }
            multiplicantincremented++;
        }
        else if(multiplicantincremented==multiplicantdivisor)
            {   lenmultiplicant++;
                multiplicantdivisor=multiplicantdivisor*(10ll);
            }
        maxnumofdigitinproduct=lenmultiplicant+lenofn;
        m=((unsigned long long)n)*multiplicant;
        length=0;
        sum=0ll;
        product=1ll;
        divisor=10ll;
        do
        {   quotient=m/divisor;
            length++;
            digit=(m%divisor)/(divisor/(10ll));
            divisor=divisor*(10ll);
            if(digit==0)
            {   product=0ll;
                break;
            }
            else
            {   
                sum=sum+((unsigned long long)digit);
                product=product*((unsigned long long)digit);
                if( (sum<product) && (sum+((unsigned long long)maxnumofdigitinproduct)-((unsigned long long)length)<product) )
                {
                    product=0ll;
                    break;
                }
            }
        }while(quotient!=(0ll));
        if((sum>=product)&&(product!=(0ll)))
            flag=1;
        pthread_mutex_lock(&timeisup);
        if(bye==1)
        {   pthread_mutex_unlock(&timeisup);
            pthread_exit(NULL);
        }
        else
            pthread_mutex_unlock(&timeisup);
    }
    gettimeofday(&end, NULL);
    interval=(float)(end.tv_sec*micro_second_multiplier+end.tv_usec - begin.tv_sec*micro_second_multiplier-begin.tv_usec);
    done=1;
    printf("\nn=%d m=%llu length=%d %.f millisecond = %.f second done=%d",n,m,length,interval,interval/1000,done);
}

int main(void)
{   pthread_t sa;
    int err_pthread,count;
    FILE *fi;
    fi=fopen("log.txt","a+");
    for(n=1;n<=30000;n++)
    {   if(n%10==0)
            n++;
        printf("\nTrying n=%d",n);
        done=0;
        bye=0;
        err_pthread=pthread_create(&sa,NULL,&solveforn,NULL);
        if(err_pthread!=0)
                {   printf("\nError while creating pthread for n=%d",n);
        }
        else
        {   printf("\npthread created");
            pthread_join(sa,NULL);
            count=0;
            do
            {   sleep(1);
                printf("\n1 second gone");
                count++;
            }while((done!=1) && (count<5));
            if(done==1)
            {   fprintf(fi,"\nn=%d m=%llu length=%d %.f millisecond = %.f second",n,m,length,interval,interval/1000);
                printf("\nThread finished in < 5 seconds");
            }
            else
            {   fprintf(fi,"\nTIME LIMIT EXCEEDED IN N=%d",n);
                printf("\nTIME LIMIT EXCEEDED IN N=%d",n);
                pthread_mutex_lock(&timeisup);
                bye=1;
                pthread_mutex_unlock(&timeisup);
            }
        }
    }
    fclose(fi);
}

The points to note are
(1)mutex timeisup locked then data passing between main and solveforn is done.
Hope - i am able to explain my situation .
The problem is -
output is as follows
Trying n=1
pthread created
Pthread begins
n=1 m=1 length=1 28 millisecond = 0 second done=1
1 second gone
Thread finished in < 5 seconds
Trying n=2
pthread created
nothing


Second 'pthread begins' did not appear . Thanks.

user1371666
  • 445
  • 1
  • 5
  • 18

1 Answers1

1

There are some solutions like pthread_cancel or pthread_kill, but non of them are stright forward as you want. you must implement handlers and ...

There is no safe way for killing a thread created by pthread (you asked about exit), you should implement exit logic inside you thread function. Also you can wait for 5 second, if all threads exited (changed a flag with appropriate mutex) you can go away.

For pthread, How to kill child thread from the main thread

cancelling or killing a pthread

Also there is an asymmetry in lock/unlock calls, in your code, you have locked pthread_mutex_lock and checked for bye==1, if it was the mutex will be unlocked, but if bye != the mutex never be unlocked and in next iteration you will be blocked by mutex_lock which isn't right.

Community
  • 1
  • 1
e.jahandar
  • 1,715
  • 12
  • 30
  • thanks for replying . In my code - I have a global variable 'bye' which is set to zero before thread creation . After 5 seconds if thread hasn't finished its work then main locks mutex 'time is up' and sets bye to 1 . Thread checks bye value in every loop of processing . Can't figure out - why the code does not run even a little ? – user1371666 Dec 19 '16 at 06:43
  • @user1371666 it seems ok, you have to post smaller version of your code – e.jahandar Dec 19 '16 at 07:01
  • edited my code and corresponding output . If you use gcc then please save it as something.c $gcc something.c -lpthread – user1371666 Dec 19 '16 at 07:02
  • edited my code and corresponding output .
    If you use gcc
    then please save it as something.c
    $gcc something.c -lpthread
    $./a.out
    To see for yourself .
    Thanks.
    – user1371666 Dec 19 '16 at 07:04
  • sorry for formatting above . seems carriage return in comments is an issue . – user1371666 Dec 19 '16 at 07:04
  • in your code, you have locked pthread_mutex_lock and checked for bye==1, if it was the mutex will be unlocked, but if bye != the mutex never be unlocked and in next iteration you will be blocked by mutex_lock. In simple words, you have asymmetry in you lock/unlock calls – e.jahandar Dec 19 '16 at 07:13
  • thanks e.jahandar . I modified to - if(bye==1) {unlock;exit;}else{unlock;} Now, it works well . Thanks for persisting . – user1371666 Dec 20 '16 at 08:22
  • One more thing . I have updated code above . Now if you run it - it will go well till n=54 then hang up at n=55 . I know that n=55 will take time >55 seconds . Then my logic should gracefully exit pthread and move on . Can't figure - why it didn't happen . – user1371666 Dec 20 '16 at 09:23
  • @user1371666 so what about pthread_exit() .. ? does it called really? – e.jahandar Dec 20 '16 at 09:50
  • if time is over and done is not modified by pthread which meant it is still processing , so main sets bye to 1 . then pthread reads value of bye and exits . I could add sleep after setting bye in main so that pthread gets time to exit before new pthread with new n gets created . Don't think that is cause of problem . Currently program gets stuck at Trying n=55 pthread created – user1371666 Dec 20 '16 at 13:30
  • actually , it will get flagged as 'not general' . So , nobody will reply . – user1371666 Dec 21 '16 at 11:36
  • be sure to use proper flags, your question is just flaged in pthread, i think if you flag it in C and pthread too, you will get more view – e.jahandar Dec 21 '16 at 11:39