#include #include #include #include #include #include #include #define gettid() syscall(__NR_gettid) static bool end; static void __vdie(const char *fmt, va_list ap, int err) { int ret = errno; if (err && errno) perror("bmp-read"); else ret = -1; fprintf(stderr, " "); vfprintf(stderr, fmt, ap); fprintf(stderr, "\n"); exit(ret); } void pdie(const char *fmt, ...) { va_list ap; va_start(ap, fmt); __vdie(fmt, ap, 1); va_end(ap); } #define NR_THREADS 8 static int nr_threads = NR_THREADS; static pthread_t *threads; static pthread_barrier_t threads_started; struct t_info { int id; int interval; pthread_mutex_t lock; pthread_cond_t cond; }; static void *thread_func(void *arg) { struct t_info *t = arg; pthread_mutex_t *this_mutex = &t->lock; pthread_cond_t *this_cond = &t->cond; struct timespec ts; int cnt = 0; pthread_barrier_wait(&threads_started); while (true) { pthread_mutex_lock(this_mutex); printf("task %d running %d\n", t->id, ++cnt); if (end) break; clock_gettime(CLOCK_REALTIME, &ts); ts.tv_sec += t->id + 1; pthread_cond_timedwait(this_cond, this_mutex, &ts); pthread_mutex_unlock(this_mutex); } pthread_mutex_unlock(this_mutex); printf("Task %d finished\n", t->id); return NULL; } int main (int argc, char **argv) { struct t_info *infos; int ret; int i; infos = calloc(nr_threads, sizeof(*infos)); if (!infos) pdie("calloc"); threads = calloc(nr_threads, sizeof(*threads)); if (!threads) pdie("calloc"); pthread_barrier_init(&threads_started, NULL, nr_threads + 1); for (i = 0; i < nr_threads; i++) { infos[i].id = i; if (pthread_mutex_init(&infos[i].lock, NULL)) pdie("pthread_mutex_init"); ret = pthread_create(&threads[i], NULL, thread_func, &infos[i]); if (ret < 0) pdie("creating thread %d", i); } pthread_barrier_wait(&threads_started); sleep(30); end = true; for (i = 0; i < nr_threads; i++) { pthread_mutex_lock(&infos[i].lock); pthread_cond_signal(&infos[i].cond); pthread_mutex_unlock(&infos[i].lock); pthread_join(threads[i], NULL); } return 0; }