The goal is to output the string bar 4 times with a one second delay between each output:
bar
bar
bar
bar
In JavaScript:
let count = 0
function foo() {
  if (++count >= 4) clearInterval(interval)
  console.log('bar')
}
const interval = setInterval(foo, 1000) // every second
To replicate this in C we turn to pthread a library that handle the lifecycle of pthreads.
To compile the setInterval.c file with pthread:
gcc -Wall setInterval.c -lpthread -o setInterval.out
#include <stdio.h>   // printf
#include <pthread.h> // pthread_t
#include <unistd.h>  // sleep
void *foo(void *vargp) {
  int count = 0;
  while(count++ < 4) {
    printf("bar\n");
    sleep(1); // one second
  }
  return NULL;
}
int main() {
  pthread_t thread_foo;
  pthread_create(&thread_foo, NULL, foo, NULL);
  pthread_join(thread_foo, NULL);
  return 0;
}
In the main function is where the main process kicks off. In that process we create a pthread to execute the foo function. Since we do not want the main process to exit right away we use the function pthread_join function to pause the calling thread, here the main process so it lets the pthread finish its work.
#include <stdio.h>   // printf
#include <pthread.h> // pthread_t
#include <unistd.h>  // sleep
void *foo(void *vargp) {
  int count = 0;
  while(1) {
    if (count++ >= 4) pthread_exit(NULL);
    printf("bar\n");
    sleep(1); // one second
  }
  return NULL;
}
int main() {
  pthread_t thread_foo;
  pthread_create(&thread_foo, NULL, foo, NULL);
  pthread_join(thread_foo, NULL);
  return 0;
}
Here we call the pthread_exit function before the foo function actually return. The pthread can exit itself.
#include <stdio.h>   // printf
#include <pthread.h> // pthread_t
#include <unistd.h>  // sleep
void *foo(void *vargp) {
  while(1) {
    printf("bar\n");
    sleep(1); // one second
  }
  return NULL;
}
int main() {
  pthread_t thread_foo;
  pthread_create(&thread_foo, NULL, foo, NULL);
  sleep(4);
  pthread_cancel(thread_foo);
  return 0;
}
In this example the main process is cancelling the pthread after waiting for 4 seconds with the pthread_cancel function.
#include <stdio.h>   // printf
#include <pthread.h> // pthread_t
#include <unistd.h>  // sleep
int RUNNING = 1;
void *foo(void *vargp) {
  while(RUNNING) {
    printf("bar\n");
    sleep(1); // one second
  }
  return NULL;
}
int main() {
  pthread_t thread_foo;
  pthread_create(&thread_foo, NULL, foo, NULL);
  sleep(4);
  RUNNING = 0;
  pthread_join(thread_foo, NULL);
  return 0;
}
We use the RUNNING global variable to communicate with the thread. On one hand that is considered bad practice. On the other hand it compiles and it has some upsides:
For clarity purposes we removed all error handling in C:
  if(pthread_join(thread_foo, NULL) > 0) {
    printf("ERROR -> the pthread can not join");
    return 1;
  }