The problem is the following code:
for(i = 0; i < 10; i++) { params.id = i; if(pthread_create(&threads[i], NULL, hello, ¶ms)); }
Your params.id value is constantly updated in the main thread, while you are passing the same pointer to all threads.
Create a separate memory for the parameters, dynamically allocating it and passing it to different threads to solve the problem.
EDIT1: Using a mutex for protection is also a bad idea. Although your mutex, if it is used mainly when setting the identifier, can also make the update mutually exclusive, but you cannot get the desired result. Instead of getting values from 0 .. 9 in different threads, you can get all 9 or more threads that can print the same values.
Thus, using thread synchronization is not such a good idea for the output you expect. If you still need to use one parameter variable between all the threads and get an output from 0 to 9 from each of the threads, it is better to move pthread_join to the first loop. This ensures that each thread is created, prints the value, and then returns before the main one spawns the next thread. In this case, you also do not need a mutex.
EDIT2: Regarding the updated question, which asks that there is no need to print the numbers 0..9 in sequence, printing may be random, but only once the problem remains the same or less.
Now let's say that the value of params.id is the first 0 and stream 0 is created, now stream 0 must print it before it is updated in the main stream, otherwise, when stream 0 receives it, the value of params.id would become 1, and you will never get your unique set of values. So, how to ensure that thread 0 prints it before it is basically updated, Two ways for it:
- Make sure thread 0 completes execution and print before major updates value
- Use condition variables and alarms to ensure that the main thread waits for thread 0 to complete printing before it updates the value (see Arjun's answer below for more details)
In my honest opinion, you have chosen the wrong problem for learning synchronization and shared memory. You can try this with some good issues, such as Producer-Consumer, where you really need synchronization to work.