Why does my thread stop after printing one line on its second run?

Viewed 59

I'm using pthreads and I'm trying to run an infinite loop on the main thread. The loop is supposed to print out "Hello world!" 10 times, then create a separate thread that writes "Hello moon!" 10 times, and then start over.

For some reason the output of my program is (always):

Hello world!
Hello world!
Hello world!
Hello world!
Hello world!
Hello world!
Hello world!
Hello world!
Hello world!
Hello world!
Hello moon!
Hello moon!
Hello moon!
Hello moon!
Hello moon!
Hello moon!
Hello moon!
Hello moon!
Hello moon!
Hello moon!
Hello world!
Hello world!
Hello world!
Hello world!
Hello world!
Hello world!
Hello world!
Hello world!
Hello world!
Hello world!
Hello moon!

instead of running forever.

The code follows:

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

#define SEC_IN_NSEC(x) (x * 1000000000)

pthread_mutex_t mutex;

void *hello_moon(void *param);

int main(int argc, char **argv)
{
    pthread_t moon_tid;

    pthread_mutex_init(&mutex, NULL);

    while(1) {
        
        pthread_mutex_lock(&mutex);

        for(int i = 0; i < 10; i++) {
            printf("Hello world!\n");
            sleep(1);
        }

        pthread_mutex_unlock(&mutex);

        pthread_create(&moon_tid, NULL, hello_moon, NULL);
        pthread_join(moon_tid, NULL);
    }

    pthread_mutex_destroy(&mutex);
}

void* hello_moon(void *param)
{
    struct timespec ts;
    ts.tv_nsec = SEC_IN_NSEC(0.2); // 0.2 s in ns
    
    pthread_mutex_lock(&mutex);

    for(int i = 0; i < 10; i++) {
        printf("Hello moon!\n");
        nanosleep(&ts, NULL);
    }

    pthread_mutex_unlock(&mutex);
    pthread_exit(0);
}

Does anyone have a clue why this is happening?

UPDATE: I commented out the sleep and nanosleep calls and ran it, then it loops as expected. I still want the delay between prints, however.

1 Answers

As pointed out by @KamilCuk in comments, you forget to initialize the tv_sec member:

struct timespec ts;
ts.tv_sec = 0; // add this, otherwise the member can be initialized with garbage
ts.tv_nsec = SEC_IN_NSEC(0.2); // 0.2 s in ns

also, you miss a header, add this at the beginning of the file:

#define _POSIX_C_SOURCE 200809L
#include <time.h>
Related