-1

My program needs to create some threads, but I'm stuck at pthread_join, as it always goes into the error case, because the return ( safe ) is 3, instead of 0, which I assume is the correct number in case everything goes okay.

Edit: To better explain myself, the error is that the code is entering the error handling area, when it is not supposed to, which translates for me getting a "Error waiting: Successful" message.

int main() {    

  pthread_t tids[NUM_THREADS];
  int a, i, resultado, safe ;
  char *f ;

  f = (char *)malloc(sizeof(SIZEFICHEIRO));
  a = randomnum(4);
  f = pickfile(a, f);

  for ( i=0; i<NUM_THREADS ; i++ )
  {
    safe = pthread_create( &tids[i] , NULL , (void *)verificador , (void *) f) ;
    if ( safe != 0 )
        perror ("Error creating threads");
  }

  for ( i=0; i<NUM_THREADS ; i++ )
  {
    safe = pthread_join( tids[i], (void **)&resultado ) ;
    if ( safe != 0 )     // Error here
        perror ("Error waiting");

    printf("Result(0:Works ; -1:error) =  %d\n", resultado);
  }

}
TJacob
  • 123
  • 1
  • 3
  • 10
  • 1
    What is this `error` that you're printing? It doesn't appear anywhere else in your code. What does the code output exactly? Do you see "Error waiting"? – David Schwartz Nov 06 '14 at 23:07
  • It says: "Error waiting: Successful", which means it is going into the error handling area, when it's not supposed to. – TJacob Nov 06 '14 at 23:17

2 Answers2

0
safe = pthread_join( tids[i], (void **)&resultado ) ;
printf("%d", error );
if ( safe != 0 )     // Error here
    perror ("Error waiting");

If pthread_join stashed the error in errno, as most calls do, the problem would be that your call to printf can change the error code stashed by pthread_join. If you're going to call perror to print the error, you need to call it immediately after the function that generated the error returns.

However, pthread_join doesn't stash the error in errno, it returns the error. So calling perror won't work. You could do this:

if ( safe != 0 )     // Error here
{
    errno = safe;
    perror ("Error waiting");
}

or

if ( safe != 0 )
    printf ("Error waiting: %s\n", strerror (safe));
David Schwartz
  • 179,497
  • 17
  • 214
  • 278
  • This: `if ( safe != 0 ) { errno = safe; perror ("Error waiting"); } ` failed. This: ` safe = errno ; if ( safe != 0 ) { perror ("Error waiting"); } ` worked. But I keep reading that both pthread_create and pthread_join should return an int = 0 if everything worked properly. This means that there is an error still happening. – TJacob Nov 07 '14 at 00:04
  • @TJacob I never suggested `safe = errno`, which makes no sense. Saying "failed" is 100% useless. How *precisely* did it fail? – David Schwartz Nov 07 '14 at 00:05
  • pthread_create is working just fine, with safe returning zero. In the above case I commented that worked, I don't get an error, so it is for, all that matters, working. But I'm still reading that pthread_join should return zero as well. – TJacob Nov 07 '14 at 00:08
  • Right, and I told you how to fix it. You have the same bug in both the `pthread_create` and the `pthread_join` case. Did you try my suggestion? And if so, what happened when you tried it? – David Schwartz Nov 07 '14 at 00:08
  • Did exactly as in your solution. This is what I got: " Error waiting: Success Result(0:Works ; -1:error) = 0 Error waiting: Success Result(0:Works ; -1:error) = 0 Error waiting: No such process Result(0:Works ; -1:error) = 0 Error waiting: No such process Result(0:Works ; -1:error) = 0 Error waiting: No such process Result(0:Works ; -1:error) = 0 Error waiting: No such process Result(0:Works ; -1:error) = 0 " – TJacob Nov 07 '14 at 00:15
  • "No such process" means that either the thread was detached or something else joined it. (Can you paste the code you actually tested? Something seems odd about that output.) – David Schwartz Nov 07 '14 at 00:23
  • @TJacob See my comment above. You got them both wrong. In any event, I can tell from the output that the main problem is that either you're detaching the threads or you're joining them elsewhere. Audit all other calls to `pthread_join` or `pthread_detach`. – David Schwartz Nov 07 '14 at 05:26
0

Tested this code:

int main() 

{   

  pthread_t tids[NUM_THREADS];
  int a, i, resultado, safe ;
  char *f ;

  f = (char *)malloc(sizeof(SIZEFICHEIRO));
  a = randomnum(4);
  f = pickfile(a, f);

  for ( i=0; i<NUM_THREADS ; i++ )
  {
    safe = pthread_create( &tids[i] , NULL , (void *)verificador , (void *) f) ;
    if ( safe != 0 )
        perror ("Error creating threads");
  }

  for ( i=0; i<NUM_THREADS ; i++ )
  {
    safe = pthread_join( tids[i], (void **)&resultado ) ;
    if ( error != 0 )
        errno = safe;
        perror ("Error waiting");

    printf("Result(0:Works ; -1:error) =  %d\n", resultado);
  }
}

Result was:

Error waiting: Success
Result(0:Works ; -1:error) = 0
Error waiting: Success
Result(0:Works ; -1:error) = 0
Error waiting: No such process
Result(0:Works ; -1:error) = 0
Error waiting: No such process
Result(0:Works ; -1:error) = 0
Error waiting: No such process
Result(0:Works ; -1:error) = 0
Error waiting: No such process
Result(0:Works ; -1:error) = 0
TJacob
  • 123
  • 1
  • 3
  • 10
  • You broke both of them! In the first one, you still call `perror`, even though `errno` is not set. In the second one, you left out the braces, so the `perror` line runs no matter what. – David Schwartz Nov 07 '14 at 05:25