timon_the_destroyer
timon_the_destroyer

Reputation: 108

How is this code in C about threads supposed to work?

I am taking an Operating Systems class, and the book provides this code.

#include <pthread.h>
#include <stdio.h>

void * mythread(void *arg) {
   int m = (int) arg;
   printf("%d\n", m);
   return (void*) (arg + 1);
}

int main(int argc, char *argv[]) {
    pthread_t p;
    int rc, m;
    pthread_create(&p, NULL, mythread, (void*) 100);
    pthread_join(p, (void**) &m);
    printf("returned %d\n", m);
    return 0;
}

The things I can't wrap my head around are: 1- How can you use "(void *) 100"? 2- Inside of the function mythread, is it possible to cast arg, which is a void pointer, into an int. Is that code supposed to work like that? If so, can you please explain how? Here's the link to the source: Chapter 27 page 5. Thanks in advance.

Upvotes: 0

Views: 112

Answers (2)

kaylum
kaylum

Reputation: 14046

The code is just passing a constant to the thread start_routine. As long as the start_routine does not dereference the pointer and casts it back to the original type (which the example does) then everything is fine.

The alternative to doing it this way is to create a variable, set it to the constant value and pass the address of the variable to the start_routine. In this example that can easily be done because any local variables declared in main will always stay in scope. But in the general it cannot be simply done using a local variable as the local variable can not be guaranteed to be in scope when the new thread gets to execute. A global variable, a function static variable or a dynamically allocated variable would need to be used. All of which are more complicated/expensive to use and manage.

One argument against the above code is that cast to/from pointers and integers is implementation specific (but not undefined behaviour). However, most compilers would do what you expect in this case. For example, gcc says:

A cast from pointer to integer discards most-significant bits if the pointer representation is larger than the integer type, sign-extends1 if the pointer representation is smaller than the integer type, otherwise the bits are unchanged.

A cast from integer to pointer discards most-significant bits if the pointer representation is smaller than the integer type, extends according to the signedness of the integer type if the pointer representation is larger than the integer type, otherwise the bits are unchanged.

(Emphasis mine).

Upvotes: 1

this
this

Reputation: 5290

Your code will cause undefined behavior in the line pthread_join. You are passing a pointer to int, yet the function requires a pointer to a void pointer: void**. The manual cast to ( void** ) will not make the code correct, under the C standard.

Ignoring that mistake, the conversion from an integer to a pointer is implementation defined, so you( since you didn't say which one ) must check how your implementation defines that.

Upvotes: 0

Related Questions