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;
}