-1

I'm trying to write a code that prints "Hello World!" 10 times with "sleep" for a second, then the program should print "Hello Moon!" 10 times with "sleep" for 0.2 seconds. This process must be repeated forever. The problem is that the program only prints "Hello World!" 10 times. I do not really understand how to get the next thread to run!

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "wrapper.h"
#include <pthread.h>

#define MAX 10


void* HelloMoonFunction(void* tid){

   long t_id;
   t_id = (long)tid;
   sleep(tid);
   printf("%d. Hello Moon! \n", tid+1);

   return NULL;
}


void* HelloWorldFunction(void* tid){

    int value = (int) (intptr_t) tid;
    sleep(value);
    printf("%d. Hello World!\n", value + 1);

    return NULL;
}


int main(int ac, char * argv){

    pthread_t hej,moon;


    while(1){

        for (int a = 0; a < MAX; a++){

             pthread_create(&hej, NULL, HelloWorldFunction, (void*)(intptr_t) a);
        }
        for (int b = 0; b < MAX; b++){

             pthread_join(&hej, NULL);
        }


        for (int i = 0; i < MAX; i++){

             pthread_create(&moon, NULL, HelloMoonFunction, (void*)(intptr_t) i);
        }
        for (int j = 0; j < MAX; j++){

             pthread_join(moon, NULL);
        }  
    }


    pthread_exit(NULL);
    return(0);
}

1 Answers1

0

The most important issue in your code is that the 10 thread IDs are stored in the same variable so the 10 pthread_joins are all called for the last thread ID.

Secondly, the data passed to the thread functions is an integer encoded into a pointer. This is not guaranteed to go well. A more portable approach would be to save the argument and pass a pointer to the saved value. However, your approach does simplify the code, so I have kept it below. Just be warned.

The 0.2 seconds difference in sleep times that you would like in the HelloMoonFunction() cannot be accomplished with sleep (sleep for n seconds), but the Posix usleep (sleep for n microseconds) is probably available even though it is obsoleted by Posix.

A modified version doing what I understand you want to accomplish could be the following:

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

#define MAX 10


void* HelloMoonFunction(void* tid){

   int value = (intptr_t)tid;
   usleep(value*200000);
   printf("%d. Hello Moon! \n", value+1);

   return NULL;
}


void* HelloWorldFunction(void* tid){

    int value = (intptr_t)tid;
    usleep(value*1000000);
    printf("%d. Hello World!\n", value + 1);

    return NULL;
}


int main(void){

    pthread_t hej[MAX], moon[MAX];

    while(1){

        for (int a = 0; a < MAX; a++){
            pthread_create(&hej[a], NULL, HelloWorldFunction, (void *)(intptr_t)a);
        }
        for (int b = 0; b < MAX; b++){
            pthread_join(hej[b], NULL);
        }


        for (int i = 0; i < MAX; i++){
            pthread_create(&moon[i], NULL, HelloMoonFunction, (void *)(intptr_t)i);
        }
        for (int j = 0; j < MAX; j++){
            pthread_join(moon[j], NULL);
        }  
    }

    return(0);
}
nielsen
  • 5,641
  • 10
  • 27
  • `(int)tid;` is largely [incorrect](https://stackoverflow.com/questions/8618637/what-does-it-mean-to-convert-int-to-void-or-vice-versa). The `(u)intptr_t` approach was [more-or-less correct](https://stackoverflow.com/a/52185868/2505965) ([possible issues](https://stackoverflow.com/a/9492910/2505965) with bit width). Best approach would be passing pointers to objects that share a lifetime with `main`. Additionally, like the code in the question, there is technically no guarantee that these threads will run in order. – Oka Feb 01 '22 at 21:12
  • @oka Yes, I was not aware of the use of `intptr_t`, I have updated accordingly. Thanks again. I agree that passing pointers to data is a safer solution which is why I noted that in the original answer. It is true there is no guarantee about the timing between the threads, but normally I think starting the threads will be fast compared to the delays. In any case the output will show the order so I understand this as an investigation exercise. – nielsen Feb 01 '22 at 21:36