Why are my threads I created not printed in order?





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}







0















I have this program:



void *func(void *arg) {
pthread_mutex_lock(&mutex);
int *id = (int *)arg;

printf("My ID is %dn" , *id);
pthread_mutex_unlock(&mutex);
}

int main() {
int i;
pthread_t tid[3];

// Let us create three threads
for (i = 0; i < 3; i++) {
pthread_create(&tid[i], NULL, func, (void *)&i);
}

for (i = 0; i < 3; i++) {
pthread_join(tid[i], NULL);
}

pthread_exit(NULL);
return 0;
}


I expected it to output this:



My ID is 0
My ID is 1
My ID is 2


But instead I get random output, such as this:



My ID is 0
My ID is 0
My ID is 2


Since I already added mutex lock, I thought it would solve the problem. What else did I do wrong? Is this related to race condition?










share|improve this question































    0















    I have this program:



    void *func(void *arg) {
    pthread_mutex_lock(&mutex);
    int *id = (int *)arg;

    printf("My ID is %dn" , *id);
    pthread_mutex_unlock(&mutex);
    }

    int main() {
    int i;
    pthread_t tid[3];

    // Let us create three threads
    for (i = 0; i < 3; i++) {
    pthread_create(&tid[i], NULL, func, (void *)&i);
    }

    for (i = 0; i < 3; i++) {
    pthread_join(tid[i], NULL);
    }

    pthread_exit(NULL);
    return 0;
    }


    I expected it to output this:



    My ID is 0
    My ID is 1
    My ID is 2


    But instead I get random output, such as this:



    My ID is 0
    My ID is 0
    My ID is 2


    Since I already added mutex lock, I thought it would solve the problem. What else did I do wrong? Is this related to race condition?










    share|improve this question



























      0












      0








      0








      I have this program:



      void *func(void *arg) {
      pthread_mutex_lock(&mutex);
      int *id = (int *)arg;

      printf("My ID is %dn" , *id);
      pthread_mutex_unlock(&mutex);
      }

      int main() {
      int i;
      pthread_t tid[3];

      // Let us create three threads
      for (i = 0; i < 3; i++) {
      pthread_create(&tid[i], NULL, func, (void *)&i);
      }

      for (i = 0; i < 3; i++) {
      pthread_join(tid[i], NULL);
      }

      pthread_exit(NULL);
      return 0;
      }


      I expected it to output this:



      My ID is 0
      My ID is 1
      My ID is 2


      But instead I get random output, such as this:



      My ID is 0
      My ID is 0
      My ID is 2


      Since I already added mutex lock, I thought it would solve the problem. What else did I do wrong? Is this related to race condition?










      share|improve this question
















      I have this program:



      void *func(void *arg) {
      pthread_mutex_lock(&mutex);
      int *id = (int *)arg;

      printf("My ID is %dn" , *id);
      pthread_mutex_unlock(&mutex);
      }

      int main() {
      int i;
      pthread_t tid[3];

      // Let us create three threads
      for (i = 0; i < 3; i++) {
      pthread_create(&tid[i], NULL, func, (void *)&i);
      }

      for (i = 0; i < 3; i++) {
      pthread_join(tid[i], NULL);
      }

      pthread_exit(NULL);
      return 0;
      }


      I expected it to output this:



      My ID is 0
      My ID is 1
      My ID is 2


      But instead I get random output, such as this:



      My ID is 0
      My ID is 0
      My ID is 2


      Since I already added mutex lock, I thought it would solve the problem. What else did I do wrong? Is this related to race condition?







      c multithreading pthreads race-condition






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 26 '18 at 23:51









      ruakh

      128k14206260




      128k14206260










      asked Nov 26 '18 at 23:43









      CSDUGCSDUG

      596




      596
























          2 Answers
          2






          active

          oldest

          votes


















          4














          Here id points to the same variable i in main for all the threads.



          int *id = (int *)arg;

          printf("My ID is %dn" , *id);


          But the variable i is constantly being update by the two for-loops in main behind the threads back. So before the thread reaches the point of printf, the value of i, and therefore also the value of *id, may have changed.



          There are a few ways to solve this. The best way depends on the use case:




          1. Wait in main until the thread signals that it has made a copy of *id before modifying i or letting it go out of scope.

          2. Declare and initialize an array, int thread_id, and create the threads like this:
            pthread_create(&tid[i], NULL, func, &thread_id[i]);


          3. malloc some memory and and initialize it with a copy of i:



            int *thread_id = malloc(sizeof(*thread_id));
            *thread_id = i
            pthread_create(&tid[i], NULL, func, thread_id);


            Just don't forget to free your memory int the thread when you are finished using it. Or in main if the thread fails to start.




          4. If i fits in a void * can pass its content directly as a parameter to the thread. To make sure it fits, you can declare it as intptr_t rather than int
            (We basicly abuse the fact that pointers are nothing more than magic integers) :



            void *func(void *arg) {
            pthread_mutex_lock(&mutex);
            // Here we interpret a pointer value as an integer value
            intptr_t id = (intptr_t )arg;

            printf("My ID is %dn" , (int)id);
            pthread_mutex_unlock(&mutex);
            }

            int main() {
            intptr_t i;
            pthread_t tid[3];

            // Let us create three threads
            for (i = 0; i < 3; i++) {
            // Here we squeeze the integer value of `i` into something that is
            // supposed to hold a pointer
            pthread_create(&tid[i], NULL, func, (void *)i);
            }

            for (i = 0; i < 3; i++) {
            pthread_join(tid[i], NULL);
            }

            // This does not belong here !!
            // pthread_exit(NULL);
            return 0;
            }







          share|improve this answer































            1














            Nope, no race conditions involved. (my b) There can be a race condition on i because all threads access it. Each thread gets started with a pointer to i. However, the main problem is that there is no guarantee that the thread will start and run the critical section while i holds the value you expect, in an order that you expect.



            I'm assuming you declared the variable mutex globally and called pthread_mutex_init() somewhere to initialize it.



            Mutexes are great to allow only one thread to access a critical section of code at a time. So the code as you've written creates all three threads to run in parallel, but only lets one thread at a time run the following code.



            int *id = (int *)arg;

            printf("My ID is %dn" , *id);





            share|improve this answer





















            • 1





              There is, in fact, a race condition: main()'s local variable i is incremented (by the for-loops in main()) without first locking the mutex. The threads read the current value of i while holding the mutex locked, but in order to avoid race conditions, all reads and writes of the shared variable must be serialized -- serializing only the reads is not sufficient.

              – Jeremy Friesner
              Nov 27 '18 at 1:21














            Your Answer






            StackExchange.ifUsing("editor", function () {
            StackExchange.using("externalEditor", function () {
            StackExchange.using("snippets", function () {
            StackExchange.snippets.init();
            });
            });
            }, "code-snippets");

            StackExchange.ready(function() {
            var channelOptions = {
            tags: "".split(" "),
            id: "1"
            };
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function() {
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled) {
            StackExchange.using("snippets", function() {
            createEditor();
            });
            }
            else {
            createEditor();
            }
            });

            function createEditor() {
            StackExchange.prepareEditor({
            heartbeatType: 'answer',
            autoActivateHeartbeat: false,
            convertImagesToLinks: true,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: 10,
            bindNavPrevention: true,
            postfix: "",
            imageUploader: {
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            },
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            });


            }
            });














            draft saved

            draft discarded


















            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53490737%2fwhy-are-my-threads-i-created-not-printed-in-order%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown

























            2 Answers
            2






            active

            oldest

            votes








            2 Answers
            2






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            4














            Here id points to the same variable i in main for all the threads.



            int *id = (int *)arg;

            printf("My ID is %dn" , *id);


            But the variable i is constantly being update by the two for-loops in main behind the threads back. So before the thread reaches the point of printf, the value of i, and therefore also the value of *id, may have changed.



            There are a few ways to solve this. The best way depends on the use case:




            1. Wait in main until the thread signals that it has made a copy of *id before modifying i or letting it go out of scope.

            2. Declare and initialize an array, int thread_id, and create the threads like this:
              pthread_create(&tid[i], NULL, func, &thread_id[i]);


            3. malloc some memory and and initialize it with a copy of i:



              int *thread_id = malloc(sizeof(*thread_id));
              *thread_id = i
              pthread_create(&tid[i], NULL, func, thread_id);


              Just don't forget to free your memory int the thread when you are finished using it. Or in main if the thread fails to start.




            4. If i fits in a void * can pass its content directly as a parameter to the thread. To make sure it fits, you can declare it as intptr_t rather than int
              (We basicly abuse the fact that pointers are nothing more than magic integers) :



              void *func(void *arg) {
              pthread_mutex_lock(&mutex);
              // Here we interpret a pointer value as an integer value
              intptr_t id = (intptr_t )arg;

              printf("My ID is %dn" , (int)id);
              pthread_mutex_unlock(&mutex);
              }

              int main() {
              intptr_t i;
              pthread_t tid[3];

              // Let us create three threads
              for (i = 0; i < 3; i++) {
              // Here we squeeze the integer value of `i` into something that is
              // supposed to hold a pointer
              pthread_create(&tid[i], NULL, func, (void *)i);
              }

              for (i = 0; i < 3; i++) {
              pthread_join(tid[i], NULL);
              }

              // This does not belong here !!
              // pthread_exit(NULL);
              return 0;
              }







            share|improve this answer




























              4














              Here id points to the same variable i in main for all the threads.



              int *id = (int *)arg;

              printf("My ID is %dn" , *id);


              But the variable i is constantly being update by the two for-loops in main behind the threads back. So before the thread reaches the point of printf, the value of i, and therefore also the value of *id, may have changed.



              There are a few ways to solve this. The best way depends on the use case:




              1. Wait in main until the thread signals that it has made a copy of *id before modifying i or letting it go out of scope.

              2. Declare and initialize an array, int thread_id, and create the threads like this:
                pthread_create(&tid[i], NULL, func, &thread_id[i]);


              3. malloc some memory and and initialize it with a copy of i:



                int *thread_id = malloc(sizeof(*thread_id));
                *thread_id = i
                pthread_create(&tid[i], NULL, func, thread_id);


                Just don't forget to free your memory int the thread when you are finished using it. Or in main if the thread fails to start.




              4. If i fits in a void * can pass its content directly as a parameter to the thread. To make sure it fits, you can declare it as intptr_t rather than int
                (We basicly abuse the fact that pointers are nothing more than magic integers) :



                void *func(void *arg) {
                pthread_mutex_lock(&mutex);
                // Here we interpret a pointer value as an integer value
                intptr_t id = (intptr_t )arg;

                printf("My ID is %dn" , (int)id);
                pthread_mutex_unlock(&mutex);
                }

                int main() {
                intptr_t i;
                pthread_t tid[3];

                // Let us create three threads
                for (i = 0; i < 3; i++) {
                // Here we squeeze the integer value of `i` into something that is
                // supposed to hold a pointer
                pthread_create(&tid[i], NULL, func, (void *)i);
                }

                for (i = 0; i < 3; i++) {
                pthread_join(tid[i], NULL);
                }

                // This does not belong here !!
                // pthread_exit(NULL);
                return 0;
                }







              share|improve this answer


























                4












                4








                4







                Here id points to the same variable i in main for all the threads.



                int *id = (int *)arg;

                printf("My ID is %dn" , *id);


                But the variable i is constantly being update by the two for-loops in main behind the threads back. So before the thread reaches the point of printf, the value of i, and therefore also the value of *id, may have changed.



                There are a few ways to solve this. The best way depends on the use case:




                1. Wait in main until the thread signals that it has made a copy of *id before modifying i or letting it go out of scope.

                2. Declare and initialize an array, int thread_id, and create the threads like this:
                  pthread_create(&tid[i], NULL, func, &thread_id[i]);


                3. malloc some memory and and initialize it with a copy of i:



                  int *thread_id = malloc(sizeof(*thread_id));
                  *thread_id = i
                  pthread_create(&tid[i], NULL, func, thread_id);


                  Just don't forget to free your memory int the thread when you are finished using it. Or in main if the thread fails to start.




                4. If i fits in a void * can pass its content directly as a parameter to the thread. To make sure it fits, you can declare it as intptr_t rather than int
                  (We basicly abuse the fact that pointers are nothing more than magic integers) :



                  void *func(void *arg) {
                  pthread_mutex_lock(&mutex);
                  // Here we interpret a pointer value as an integer value
                  intptr_t id = (intptr_t )arg;

                  printf("My ID is %dn" , (int)id);
                  pthread_mutex_unlock(&mutex);
                  }

                  int main() {
                  intptr_t i;
                  pthread_t tid[3];

                  // Let us create three threads
                  for (i = 0; i < 3; i++) {
                  // Here we squeeze the integer value of `i` into something that is
                  // supposed to hold a pointer
                  pthread_create(&tid[i], NULL, func, (void *)i);
                  }

                  for (i = 0; i < 3; i++) {
                  pthread_join(tid[i], NULL);
                  }

                  // This does not belong here !!
                  // pthread_exit(NULL);
                  return 0;
                  }







                share|improve this answer













                Here id points to the same variable i in main for all the threads.



                int *id = (int *)arg;

                printf("My ID is %dn" , *id);


                But the variable i is constantly being update by the two for-loops in main behind the threads back. So before the thread reaches the point of printf, the value of i, and therefore also the value of *id, may have changed.



                There are a few ways to solve this. The best way depends on the use case:




                1. Wait in main until the thread signals that it has made a copy of *id before modifying i or letting it go out of scope.

                2. Declare and initialize an array, int thread_id, and create the threads like this:
                  pthread_create(&tid[i], NULL, func, &thread_id[i]);


                3. malloc some memory and and initialize it with a copy of i:



                  int *thread_id = malloc(sizeof(*thread_id));
                  *thread_id = i
                  pthread_create(&tid[i], NULL, func, thread_id);


                  Just don't forget to free your memory int the thread when you are finished using it. Or in main if the thread fails to start.




                4. If i fits in a void * can pass its content directly as a parameter to the thread. To make sure it fits, you can declare it as intptr_t rather than int
                  (We basicly abuse the fact that pointers are nothing more than magic integers) :



                  void *func(void *arg) {
                  pthread_mutex_lock(&mutex);
                  // Here we interpret a pointer value as an integer value
                  intptr_t id = (intptr_t )arg;

                  printf("My ID is %dn" , (int)id);
                  pthread_mutex_unlock(&mutex);
                  }

                  int main() {
                  intptr_t i;
                  pthread_t tid[3];

                  // Let us create three threads
                  for (i = 0; i < 3; i++) {
                  // Here we squeeze the integer value of `i` into something that is
                  // supposed to hold a pointer
                  pthread_create(&tid[i], NULL, func, (void *)i);
                  }

                  for (i = 0; i < 3; i++) {
                  pthread_join(tid[i], NULL);
                  }

                  // This does not belong here !!
                  // pthread_exit(NULL);
                  return 0;
                  }








                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Nov 27 '18 at 1:16









                HAL9000HAL9000

                27217




                27217

























                    1














                    Nope, no race conditions involved. (my b) There can be a race condition on i because all threads access it. Each thread gets started with a pointer to i. However, the main problem is that there is no guarantee that the thread will start and run the critical section while i holds the value you expect, in an order that you expect.



                    I'm assuming you declared the variable mutex globally and called pthread_mutex_init() somewhere to initialize it.



                    Mutexes are great to allow only one thread to access a critical section of code at a time. So the code as you've written creates all three threads to run in parallel, but only lets one thread at a time run the following code.



                    int *id = (int *)arg;

                    printf("My ID is %dn" , *id);





                    share|improve this answer





















                    • 1





                      There is, in fact, a race condition: main()'s local variable i is incremented (by the for-loops in main()) without first locking the mutex. The threads read the current value of i while holding the mutex locked, but in order to avoid race conditions, all reads and writes of the shared variable must be serialized -- serializing only the reads is not sufficient.

                      – Jeremy Friesner
                      Nov 27 '18 at 1:21


















                    1














                    Nope, no race conditions involved. (my b) There can be a race condition on i because all threads access it. Each thread gets started with a pointer to i. However, the main problem is that there is no guarantee that the thread will start and run the critical section while i holds the value you expect, in an order that you expect.



                    I'm assuming you declared the variable mutex globally and called pthread_mutex_init() somewhere to initialize it.



                    Mutexes are great to allow only one thread to access a critical section of code at a time. So the code as you've written creates all three threads to run in parallel, but only lets one thread at a time run the following code.



                    int *id = (int *)arg;

                    printf("My ID is %dn" , *id);





                    share|improve this answer





















                    • 1





                      There is, in fact, a race condition: main()'s local variable i is incremented (by the for-loops in main()) without first locking the mutex. The threads read the current value of i while holding the mutex locked, but in order to avoid race conditions, all reads and writes of the shared variable must be serialized -- serializing only the reads is not sufficient.

                      – Jeremy Friesner
                      Nov 27 '18 at 1:21
















                    1












                    1








                    1







                    Nope, no race conditions involved. (my b) There can be a race condition on i because all threads access it. Each thread gets started with a pointer to i. However, the main problem is that there is no guarantee that the thread will start and run the critical section while i holds the value you expect, in an order that you expect.



                    I'm assuming you declared the variable mutex globally and called pthread_mutex_init() somewhere to initialize it.



                    Mutexes are great to allow only one thread to access a critical section of code at a time. So the code as you've written creates all three threads to run in parallel, but only lets one thread at a time run the following code.



                    int *id = (int *)arg;

                    printf("My ID is %dn" , *id);





                    share|improve this answer















                    Nope, no race conditions involved. (my b) There can be a race condition on i because all threads access it. Each thread gets started with a pointer to i. However, the main problem is that there is no guarantee that the thread will start and run the critical section while i holds the value you expect, in an order that you expect.



                    I'm assuming you declared the variable mutex globally and called pthread_mutex_init() somewhere to initialize it.



                    Mutexes are great to allow only one thread to access a critical section of code at a time. So the code as you've written creates all three threads to run in parallel, but only lets one thread at a time run the following code.



                    int *id = (int *)arg;

                    printf("My ID is %dn" , *id);






                    share|improve this answer














                    share|improve this answer



                    share|improve this answer








                    edited Nov 27 '18 at 13:08

























                    answered Nov 27 '18 at 0:05









                    GandhiGandhiGandhiGandhi

                    1045




                    1045








                    • 1





                      There is, in fact, a race condition: main()'s local variable i is incremented (by the for-loops in main()) without first locking the mutex. The threads read the current value of i while holding the mutex locked, but in order to avoid race conditions, all reads and writes of the shared variable must be serialized -- serializing only the reads is not sufficient.

                      – Jeremy Friesner
                      Nov 27 '18 at 1:21
















                    • 1





                      There is, in fact, a race condition: main()'s local variable i is incremented (by the for-loops in main()) without first locking the mutex. The threads read the current value of i while holding the mutex locked, but in order to avoid race conditions, all reads and writes of the shared variable must be serialized -- serializing only the reads is not sufficient.

                      – Jeremy Friesner
                      Nov 27 '18 at 1:21










                    1




                    1





                    There is, in fact, a race condition: main()'s local variable i is incremented (by the for-loops in main()) without first locking the mutex. The threads read the current value of i while holding the mutex locked, but in order to avoid race conditions, all reads and writes of the shared variable must be serialized -- serializing only the reads is not sufficient.

                    – Jeremy Friesner
                    Nov 27 '18 at 1:21







                    There is, in fact, a race condition: main()'s local variable i is incremented (by the for-loops in main()) without first locking the mutex. The threads read the current value of i while holding the mutex locked, but in order to avoid race conditions, all reads and writes of the shared variable must be serialized -- serializing only the reads is not sufficient.

                    – Jeremy Friesner
                    Nov 27 '18 at 1:21




















                    draft saved

                    draft discarded




















































                    Thanks for contributing an answer to Stack Overflow!


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid



                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.


                    To learn more, see our tips on writing great answers.




                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function () {
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53490737%2fwhy-are-my-threads-i-created-not-printed-in-order%23new-answer', 'question_page');
                    }
                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    Popular posts from this blog

                    Wiesbaden

                    Marschland

                    Dieringhausen