Armagadon
Armagadon

Reputation: 59

Questions about POSIX Threads in C

#include <pthread.h>
#define NUM_THREADS 4

void *work(void *i){
    printf("Hello, world from %i\n", pthread_self());
    pthread_exit(NULL); 
}

int main(int argc, char **argv){
    int i;
    pthread_t id[NUM_THREADS];
    for(i = 0; i < NUM_THREADS; ++i){
       if(pthread_create(&id[i], NULL, work, NULL)){
          printf("Error creating the thread\n"); exit(19);
       } 
    }
    printf("After creating the thread. My id is: %i\n",
    pthread_self());
    return 0;
}

i know the output is :

Hello, world from 2
Hello, world from 3
After creating the thread. My id is: 1
Hello, world from …

First of all this is not a homework. POSIX is not my field so I just want an explanation of the output (no need to explain functions used since I know what they do) some quick answers of:

  1. ARE the ids for pthreads (2 , 3 , 1) specified by the system??
  2. the ++i used ... did it affect the output somehow?
  3. why is it that there are only 4 threads in the end (3 + main) why not 5?!
  4. why is it that after main printed After creating .... another thread executed??!! how come??!!

Upvotes: 4

Views: 790

Answers (4)

pthread_self does not return a numeric type, but an opaque type pthread_t (which could be some opaque struct).

I suggest you to clear your array with

  memset(id, 0, sizeof(id));

Indeed, on GNU/Linux/Debian/Sid/x86-64, the internal include file /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h has

  typedef unsigned long int pthread_t;

But I don't think you should believe it is an identification for threads, just an opaque handle (like file descriptors are).

I suggest you to read a good tutorial on pthreads like e.g. this one by Blaise Barney

On today's multi-core machines threads [may] run really in parallel on different cores.

Upvotes: 0

Tudor
Tudor

Reputation: 62469

  1. They are the ids of the threads inside the current process.
  2. No, the i does not affect the output because you are not passing it to the threads as a parameter, nor accessing it from inside the thread code. As such, it's just a loop variable.
  3. I don't know how many outputs there are because you are not giving us the full output. I agree that normally there should be 5 threads. It's possible that some threads don't have time to print their message before the main thread exits. You should join them before exiting the main thread.
 for(i = 0; i < NUM_THREADS; i++)
 {
     pthread_join(id[i], NULL);
 }

4.Threads are launched in parallel to the main thread. Therefore, the code of each of the threads you are starting is executing simultaneously with the code of the main thread after they are started. This means that the main thread continues to execute the printf while the child threads are doing their work so the output is interleaved in a "random" way.

Upvotes: 1

Kevin
Kevin

Reputation: 56129

  1. I'm not sure whether it's specified, but I believe (nearly?) all thread ids are started at 1 (the main) and incremented from there.
  2. No, ++i has nothing to do with the output.
  3. Since you didn't pthread_join the threads, the main function (and therefore the program) exited before the last thread executed.
  4. I'm not sure precisely what you're trying to ask here, but the answer is concurrency. There's no guarantee of when or in what order the threads execute.

Upvotes: 4

Douglas Leeder
Douglas Leeder

Reputation: 53285

3 & 4: Threads are asynchronous: With pthreads, when you exit from the main function, all threads are terminated, regardless if they have finished or not.

So only 3 threads had printed before main exited the loop, 1 printed between main's print statement and the return, and one thread hadn't got that far.

Upvotes: 1

Related Questions