1

I am using pthread_t to print out the pid of a thread that I manually create in C. However, I print it before I create my new thread (passing it by ref as a parameter) and it prints a different value (presumably the thread that my main function is executing on). I would have expected it to default to be 0 or unitialised. Any ideas? Thanks,

#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>

struct thread_info {    /* Used as argument to thread_start() */
    pthread_t thread_id;/* ID returned by pthread_create() */
};

static void *thread_1_start(void *arg) {
    struct thread_info *myInfo = arg;
    printf("Started thread id: %d\n", myInfo->thread_id);
    pthread_exit(0);
}

int main() {
    struct thread_info tinfo;

    int s;
    printf("Main thread id: %d\n", tinfo.thread_id);
    s = pthread_create(&tinfo.thread_id,
        NULL, // was address of attr, error as this was not initialised.
        &thread_1_start,
        &tinfo);
    pthread_join(tinfo.thread_id,NULL);
}

Actual output:

Main thread id: 244580352
Started thread id: 245325824

Expected output:

Main thread id: // 0 or undefined
Started thread id: 245325824
Sam Heather
  • 1,493
  • 3
  • 19
  • 42
  • also have a look at [this](http://stackoverflow.com/questions/19676071/understanding-pthreads) for better understanding of thread ids. – Raju Kunde Nov 01 '13 at 12:33

4 Answers4

3

The problem is you are not initialising tinfo structure.

In local variables (as opposed to global/heap variables), values are not initialised in C Programming Language.

So, if you do something like:

int c;
printf("%d", c);

You should not expect a coherent value since it will depend on what's on that memory location in that moment.

You need to initialize tinfo variable. Using memset or assigning tinfo.thread_id = 0 explicitly.

Pablo Santa Cruz
  • 176,835
  • 32
  • 241
  • 292
  • I am not sure that is what is going on though, as if it were 'just what happens to be in memory at that space', are the two PID's so close to each other all the time? For example, Main thread id: 170115072 Started thread id: 170860544 and run 2 Main thread id: 221585408 Started thread id: 222330880 – Sam Heather Oct 30 '13 at 19:25
3

There is no thread-specific logic to initialize tinfo; it is just a regular C struct. It will have whatever data was in that memory address at the initialization. You need to explicitly initialize it.

You can initialize the value to zero by:

struct thread_info tinfo = { 0 };
yan
  • 20,644
  • 3
  • 38
  • 48
  • You provide the thread id, and future ones get incremented from that. What happened was you provided an initialized value as a thread ID and that was used to create the next one. For example, set the value to `1234` and see what the next one becomes. – yan Oct 30 '13 at 19:32
  • So I added 'tinfo.thread_id=1234;', and re-ran. The output was: Main thread id: 1234 Started thread id: 215781376 Weren't you implying that the started thread id: would be much less? 1234 + a small pid? – Sam Heather Oct 30 '13 at 19:36
  • I was perhaps wrong about the small offset, but is your first case repeatable? Do you get values that are close to one another over say, 10 executions? – yan Oct 30 '13 at 19:57
  • Tried on 10 executions, on all numbers are similar difference to above - very close to each other. – Sam Heather Oct 30 '13 at 21:22
2

Declare struct thread_info tinfo; global and see what happens.

fvdalcin
  • 1,047
  • 1
  • 8
  • 26
0

There's a number of important things you need to know.

First, pthread_t is opaque. You can't reliably print it with printf because nowhere in the POSIX standard is pthread_t specified as beinban into, struct or whatever. By definition you can't print it and get a meaningful output.

Second, if a thread needs to know it's pthread_t ID it can call pthread_self(). You don't need to tell the thread what its ID is externally like you're trying to do.

But never mind that! The condition you describe where the printed output is close to what you're expecting is because you have a race between the thread printing out and pthread_create assigning the pthread_t to thread_info.thread_id, and due to pthread_t actually being an integer type on Linux (so it's likely that they're allocated sequentially, and you're just getting an old value).

bazza
  • 7,580
  • 15
  • 22
  • re: second - so is the point here that I pass a reference to a pthread_t for it's internal use and that I don't ever have to care about the contents of this pthread_t or use it? Why not just make this under the hood then? Why do I pass a reference to pthread_t when I run pthread_create()? – Sam Heather Oct 30 '13 at 21:26
  • @SamHeather, you do that so that the thread calling pthread_create() can have the ID of the thread that gets started. This allows it to call functions like pthread_join() later on. If that's not necessary in the program (maybe it never needs to quit!) you can just discard the value returned by pthread_create(). Normally you would store the pthread_t given back by pthread_create in some local variable (which is not shared with the thread) for use in pthread_join() just before the program quits. – bazza Oct 30 '13 at 22:47