1 /* Creates several daemon threads and non-daemon threads. 2 Tests that the process can exit even if the daemon threads are still running, 3 as per thr_create(3C). */ 4 5 #include <pthread.h> 6 #include <stdio.h> 7 #include <stdlib.h> 8 #include <string.h> 9 #include <thread.h> 10 #include <unistd.h> 11 12 #define DAEMON_THREADS 5 13 #define NON_DAEMON_THREADS 6 14 #define SLEEP_100_MS usleep(100 * 1000) 15 16 static pthread_barrier_t barrier; 17 18 void *daemon_thread_func(void *arg) { 19 size_t index = (size_t) arg; 20 printf("DAEMON thread #%zu running\n", index); fflush(stdout); 21 pthread_barrier_wait(&barrier); 22 23 /* Give the non-daemon threads enough time to exit. */ 24 sleep(10); 25 printf("DAEMON thread #%zu still running?!\n", index); fflush(stdout); 26 return NULL; 27 } 28 29 void *normal_thread_func(void *arg) { 30 size_t index = (size_t) arg; 31 printf("non-daemon thread #%zu running\n", index); fflush(stdout); 32 pthread_barrier_wait(&barrier); 33 34 sleep(2); 35 return NULL; 36 } 37 38 int main(void) { 39 size_t i; 40 int ret = pthread_barrier_init(&barrier, NULL, 41 DAEMON_THREADS + NON_DAEMON_THREADS + 1); 42 if (ret != 0) { 43 fprintf(stderr, "pthread_barrier_init failed: %s\n", strerror(ret)); 44 return 1; 45 } 46 47 for (i = 0; i < DAEMON_THREADS; i++) { 48 ret = thr_create(NULL, 0, daemon_thread_func, (void *) i, 49 THR_DAEMON, NULL); 50 if (ret != 0) { 51 fprintf(stderr, "thr_create failed: %s\n", strerror(ret)); 52 return 1; 53 } 54 SLEEP_100_MS; 55 } 56 57 for (i = 0; i < NON_DAEMON_THREADS; i++) { 58 ret = thr_create(NULL, 0, normal_thread_func, (void *) i, 0, NULL); 59 if (ret != 0) { 60 fprintf(stderr, "thr_create failed: %s\n", strerror(ret)); 61 return 1; 62 } 63 SLEEP_100_MS; 64 } 65 66 pthread_barrier_wait(&barrier); 67 68 printf("MAIN thread exiting\n"); 69 /* Exit only the main thread, not whole process. 70 That is, do not exit(0) or return(0). */ 71 thr_exit(NULL); 72 } 73