I have a small program with two threads sending signal to each other.
The program first works as expected but stop after various runs as the pthread_cond_timedwait run into a timeout.
For my test I stop the program if one thread is running into a timeout.
<code>#include <errno.h>
#include <pthread.h>
#include <signal.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <sys/time.h>
#include <time.h>
#include <unistd.h>
pthread_mutex_t mutex1;
pthread_cond_t cond1;
pthread_mutex_t mutex2;
pthread_cond_t cond2;
bool run = true;
void signal_handler(int sig_num) { run = false; }
void* thread1(void* arg) {
struct timespec ts;
struct timeval now;
uint32_t runs = 0;
while (run) {
pthread_mutex_lock(&mutex1);
gettimeofday(&now, NULL);
ts.tv_sec = now.tv_sec + 1;
ts.tv_nsec = now.tv_usec * 1000;
pthread_mutex_unlock(&mutex1);
pthread_mutex_lock(&mutex2);
int result = pthread_cond_timedwait(&cond2, &mutex2, &ts);
if (result == ETIMEDOUT) {
printf("Thread 1: Wait timed outn");
run = false;
} else if (result == 0) {
// printf("Thread 1: Signal received from Thread 2n");
if (pthread_cond_signal(&cond1) != 0) {
printf("Failed to signal cond1n");
}
runs++;
}
pthread_mutex_unlock(&mutex2);
}
printf("T1: runs=%dn", runs);
return NULL;
}
void* thread2(void* arg) {
struct timespec ts;
struct timeval now;
uint32_t runs = 0;
while (run) {
pthread_mutex_lock(&mutex2);
gettimeofday(&now, NULL);
ts.tv_sec = now.tv_sec + 1;
ts.tv_nsec = now.tv_usec * 1000;
// printf("Thread 2: Sending signal to Thread 1n");
if (pthread_cond_signal(&cond2) != 0) {
printf("Failed to signal cond2n");
}
pthread_mutex_unlock(&mutex2);
pthread_mutex_lock(&mutex1);
int result = pthread_cond_timedwait(&cond1, &mutex1, &ts);
if (result == ETIMEDOUT) {
printf("Thread 2: Wait timed outn");
run = false;
} else {
runs++;
}
pthread_mutex_unlock(&mutex1);
}
printf("T2: runs=%dn", runs);
return NULL;
}
int main() {
pthread_t tid1, tid2;
signal(SIGINT, signal_handler);
signal(SIGTERM, signal_handler);
pthread_mutex_init(&mutex1, NULL);
pthread_cond_init(&cond1, NULL);
pthread_mutex_init(&mutex2, NULL);
pthread_cond_init(&cond2, NULL);
pthread_create(&tid1, NULL, thread1, NULL);
pthread_create(&tid2, NULL, thread2, NULL);
pthread_join(tid1, NULL);
pthread_join(tid2, NULL);
pthread_mutex_destroy(&mutex1);
pthread_cond_destroy(&cond1);
pthread_mutex_destroy(&mutex2);
pthread_cond_destroy(&cond2);
return 0;
}
</code>
<code>#include <errno.h>
#include <pthread.h>
#include <signal.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <sys/time.h>
#include <time.h>
#include <unistd.h>
pthread_mutex_t mutex1;
pthread_cond_t cond1;
pthread_mutex_t mutex2;
pthread_cond_t cond2;
bool run = true;
void signal_handler(int sig_num) { run = false; }
void* thread1(void* arg) {
struct timespec ts;
struct timeval now;
uint32_t runs = 0;
while (run) {
pthread_mutex_lock(&mutex1);
gettimeofday(&now, NULL);
ts.tv_sec = now.tv_sec + 1;
ts.tv_nsec = now.tv_usec * 1000;
pthread_mutex_unlock(&mutex1);
pthread_mutex_lock(&mutex2);
int result = pthread_cond_timedwait(&cond2, &mutex2, &ts);
if (result == ETIMEDOUT) {
printf("Thread 1: Wait timed outn");
run = false;
} else if (result == 0) {
// printf("Thread 1: Signal received from Thread 2n");
if (pthread_cond_signal(&cond1) != 0) {
printf("Failed to signal cond1n");
}
runs++;
}
pthread_mutex_unlock(&mutex2);
}
printf("T1: runs=%dn", runs);
return NULL;
}
void* thread2(void* arg) {
struct timespec ts;
struct timeval now;
uint32_t runs = 0;
while (run) {
pthread_mutex_lock(&mutex2);
gettimeofday(&now, NULL);
ts.tv_sec = now.tv_sec + 1;
ts.tv_nsec = now.tv_usec * 1000;
// printf("Thread 2: Sending signal to Thread 1n");
if (pthread_cond_signal(&cond2) != 0) {
printf("Failed to signal cond2n");
}
pthread_mutex_unlock(&mutex2);
pthread_mutex_lock(&mutex1);
int result = pthread_cond_timedwait(&cond1, &mutex1, &ts);
if (result == ETIMEDOUT) {
printf("Thread 2: Wait timed outn");
run = false;
} else {
runs++;
}
pthread_mutex_unlock(&mutex1);
}
printf("T2: runs=%dn", runs);
return NULL;
}
int main() {
pthread_t tid1, tid2;
signal(SIGINT, signal_handler);
signal(SIGTERM, signal_handler);
pthread_mutex_init(&mutex1, NULL);
pthread_cond_init(&cond1, NULL);
pthread_mutex_init(&mutex2, NULL);
pthread_cond_init(&cond2, NULL);
pthread_create(&tid1, NULL, thread1, NULL);
pthread_create(&tid2, NULL, thread2, NULL);
pthread_join(tid1, NULL);
pthread_join(tid2, NULL);
pthread_mutex_destroy(&mutex1);
pthread_cond_destroy(&cond1);
pthread_mutex_destroy(&mutex2);
pthread_cond_destroy(&cond2);
return 0;
}
</code>
#include <errno.h>
#include <pthread.h>
#include <signal.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <sys/time.h>
#include <time.h>
#include <unistd.h>
pthread_mutex_t mutex1;
pthread_cond_t cond1;
pthread_mutex_t mutex2;
pthread_cond_t cond2;
bool run = true;
void signal_handler(int sig_num) { run = false; }
void* thread1(void* arg) {
struct timespec ts;
struct timeval now;
uint32_t runs = 0;
while (run) {
pthread_mutex_lock(&mutex1);
gettimeofday(&now, NULL);
ts.tv_sec = now.tv_sec + 1;
ts.tv_nsec = now.tv_usec * 1000;
pthread_mutex_unlock(&mutex1);
pthread_mutex_lock(&mutex2);
int result = pthread_cond_timedwait(&cond2, &mutex2, &ts);
if (result == ETIMEDOUT) {
printf("Thread 1: Wait timed outn");
run = false;
} else if (result == 0) {
// printf("Thread 1: Signal received from Thread 2n");
if (pthread_cond_signal(&cond1) != 0) {
printf("Failed to signal cond1n");
}
runs++;
}
pthread_mutex_unlock(&mutex2);
}
printf("T1: runs=%dn", runs);
return NULL;
}
void* thread2(void* arg) {
struct timespec ts;
struct timeval now;
uint32_t runs = 0;
while (run) {
pthread_mutex_lock(&mutex2);
gettimeofday(&now, NULL);
ts.tv_sec = now.tv_sec + 1;
ts.tv_nsec = now.tv_usec * 1000;
// printf("Thread 2: Sending signal to Thread 1n");
if (pthread_cond_signal(&cond2) != 0) {
printf("Failed to signal cond2n");
}
pthread_mutex_unlock(&mutex2);
pthread_mutex_lock(&mutex1);
int result = pthread_cond_timedwait(&cond1, &mutex1, &ts);
if (result == ETIMEDOUT) {
printf("Thread 2: Wait timed outn");
run = false;
} else {
runs++;
}
pthread_mutex_unlock(&mutex1);
}
printf("T2: runs=%dn", runs);
return NULL;
}
int main() {
pthread_t tid1, tid2;
signal(SIGINT, signal_handler);
signal(SIGTERM, signal_handler);
pthread_mutex_init(&mutex1, NULL);
pthread_cond_init(&cond1, NULL);
pthread_mutex_init(&mutex2, NULL);
pthread_cond_init(&cond2, NULL);
pthread_create(&tid1, NULL, thread1, NULL);
pthread_create(&tid2, NULL, thread2, NULL);
pthread_join(tid1, NULL);
pthread_join(tid2, NULL);
pthread_mutex_destroy(&mutex1);
pthread_cond_destroy(&cond1);
pthread_mutex_destroy(&mutex2);
pthread_cond_destroy(&cond2);
return 0;
}
This end in the following output:
<code>$ /tmp/test
Thread 2: Wait timed out
T2: runs=84498
Thread 1: Wait timed out
T1: runs=84499
$ /tmp/test
Thread 2: Wait timed out
T2: runs=148
Thread 1: Wait timed out
T1: runs=148
</code>
<code>$ /tmp/test
Thread 2: Wait timed out
T2: runs=84498
Thread 1: Wait timed out
T1: runs=84499
$ /tmp/test
Thread 2: Wait timed out
T2: runs=148
Thread 1: Wait timed out
T1: runs=148
</code>
$ /tmp/test
Thread 2: Wait timed out
T2: runs=84498
Thread 1: Wait timed out
T1: runs=84499
$ /tmp/test
Thread 2: Wait timed out
T2: runs=148
Thread 1: Wait timed out
T1: runs=148
But I expect it to run forever or until I kill it.
New contributor
paperwork is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.