You're passing in the address of i
to each of the threads, so they each read the current state of i
(and without synchronization, so the results are unpredictable if not undefined).
Instead, you need to pass a pointer to thread-specific data (that has a lifetime at least as long as the thread). For example:
#include <stdio.h>#include <stdlib.h>#include <pthread.h>void *foo(void *arg){ int *myid = (int*) arg; printf("Hello from thread %d\n",*myid); return NULL;}int main(void){ pthread_t tid[4]; int ids[4]; int i; for(i=0;i<4;i++){ ids[i] = i; pthread_create(&tid[i],NULL,(void*) foo, &ids[i]); } for(i=0;i<4;i++){ pthread_join(tid[i],NULL); } return 0;}