Thread: passing pointers

  1. #1
    Registered User
    Join Date
    Dec 2005
    Location
    german border
    Posts
    72

    passing pointers

    Hi,

    I'm looking up pthreads and it's going ok, but I'm getting a little confused with the (void *) casting, so I was hoping sombody could explain what exactly the variable t is when it is passed to the PrintHello function below. From my understanding, t holds as an example, 0 on the first run through the loop; it's then cast as type (void *) which makes it a pointer, but it's value is taken literally in the function when it is recast as an int, it isn't dereferenced, does this mean that the address t points to is 0? Isn't that usually a bad idea as that memory address could be reserved or whatever? Is this just a workaround for pthread's need for void* types?

    Code:
    void *PrintHello(void *threadid)
    {
       int tid;
       tid = (int)threadid;
       printf("Hello World! It's me, thread #%d!\n", tid);
       pthread_exit(NULL);
    }
    
    int main (int argc, char *argv[])
    {
       pthread_t threads[NUM_THREADS];
       int rc, t;
       for(t=0; t<NUM_THREADS; t++){
          printf("In main: creating thread %d\n", t);
          rc = pthread_create(&threads[t], NULL, PrintHello, (void *)t);
          if (rc){
             printf("ERROR; return code from pthread_create() is %d\n", rc);
             exit(-1);
          }
       }
       pthread_exit(NULL);
    }

  2. #2
    Registered User
    Join Date
    Dec 2005
    Location
    german border
    Posts
    72
    sorry excuse my laziness, I realised I just needed a few printf statements to find out what's happening. So it uses pointers with whatever value t has at that point, which is necessary because that's the way the pthread library is written. I'm guessing it's a bad idea otherwise.

  3. #3
    Registered User
    Join Date
    Sep 2007
    Posts
    1,012
    It's a bad idea anyway. While C allows for the conversion between an int and a pointer, it doesn't guarantee that the result will be valid. I would guess that on most, if not all POSIX systems, it will do what you would expect. But it's still dodgy code.

    Unfortunately, doing it properly is somewhat more annoying, because you have to pass the address of something. You can get away with passing the address of a local variable if that variable does not go out of scope while your thread is running. Otherwise, you'll have to malloc() some space, which is even more annoying. But it is the proper way to do it.

  4. #4
    Registered User
    Join Date
    Dec 2005
    Location
    german border
    Posts
    72
    So would the following code be ok?

    Code:
    #include<stdio.h>
    #include<stdlib.h>
    
    void doStuff( void *sock );
    
    int main()
    {
        int *sock = malloc(sizeof(sock));
        *sock = 3;
        doStuff( (void *)sock );
        free(sock);
        return 0;
    }
    
    void doStuff( void *sock )
    {
        int *socket = (int *)sock;
        printf("&#37;d\n", *socket);
    }
    I'm just wondering if you could make that more efficient? It seems a waste to declare a whole new variable just to change the type.

  5. #5
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,666
    Well your original code might look like this, with a pointer to some data
    Code:
    void *PrintHello(void *threadid)
    {
       int *tid = threadid;
       printf("Hello World! It's me, thread #&#37;d!\n", *tid);
       pthread_exit(NULL);
    }
    
    int main (int argc, char *argv[])
    {
       static int params[NUM_THREADS];
       pthread_t threads[NUM_THREADS];
       int rc, t;
       for(t=0; t<NUM_THREADS; t++){
          printf("In main: creating thread %d\n", t);
          params[t] = t;
          rc = pthread_create(&threads[t], NULL, PrintHello, &params[t]);
          if (rc){
             printf("ERROR; return code from pthread_create() is %d\n", rc);
             exit(-1);
          }
       }
       pthread_exit(NULL);
    }
    You need to make sure that whatever pointer you pass to your thread, it has a lifetime which is guaranteed for the life of the thread (and not the life of the caller). That's why it's a static.

    Using malloc is another good way (and is generally preferred) since the thread can just take ownership of the pointer and just use it for as long as it needs it.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Passing a string array to a function using pointers
    By asofaihp in forum C++ Programming
    Replies: 2
    Last Post: 04-13-2009, 11:31 AM
  2. Passing Pointers by reference
    By Bladactania in forum C Programming
    Replies: 10
    Last Post: 02-13-2009, 10:14 AM
  3. passing pointers outside of functions
    By thomas41546 in forum C Programming
    Replies: 6
    Last Post: 01-26-2008, 06:00 PM
  4. Passing pointers
    By cyberCLoWn in forum C++ Programming
    Replies: 6
    Last Post: 04-14-2004, 12:17 PM
  5. Pointers and reference passing
    By Denis Itchy in forum C++ Programming
    Replies: 4
    Last Post: 12-13-2002, 01:36 AM