// pthread_test.cpp : Defines the entry point for the console application. // #ifndef __GNUC__ #include "stdafx.h" #else #include #endif #include #ifndef set_timespec #define set_timespec(ABSTIME,SEC) \ {\ struct timeval tv;\ gettimeofday(&tv,0);\ (ABSTIME).tv_sec=tv.tv_sec+(time_t) (SEC);\ (ABSTIME).tv_nsec=tv.tv_usec*1000;\ } #endif /* !set_timespec */ void *condwait_start_func(void *); void *condtimedwait_start_func(void *); pthread_mutex_t g_mutex; pthread_cond_t g_cond; pthread_cond_t g_cond_ping_main; static int g_active_threads_ct[20]; static int g_finished_threads_ct[20]; static int g_timedout_threads_ct[20]; struct s_param { int i; int j; }; #ifndef __GNUC__ int _tmain(int argc, _TCHAR* argv[]) #else int main(int argc, char *argv[]) #endif { //win_pthread_init(); my_init(); memset(g_active_threads_ct, 0, 20*sizeof(int)); memset(g_finished_threads_ct, 0, 20*sizeof(int)); memset(g_timedout_threads_ct, 0, 20*sizeof(int)); pthread_t condwait_thread[20][100]; pthread_t condtimedwait_thread[20][100]; pthread_attr_t condwait_attr; pthread_attr_init(&condwait_attr); pthread_attr_setstacksize(&condwait_attr, 4098); pthread_mutex_init(&g_mutex, NULL); pthread_cond_init(&g_cond, NULL); pthread_cond_init(&g_cond_ping_main, NULL); struct s_param condwait_param[20][100]; struct s_param condtimedwait_param[20][100]; for (int j= 0; j< 20; j++) { // Start one thread which times out condtimedwait_param[j][0].i= 0; condtimedwait_param[j][0].j= j; pthread_create(&condtimedwait_thread[j][0], &condwait_attr, &condtimedwait_start_func, &condtimedwait_param[j][0]); sleep(2); pthread_mutex_lock(&g_mutex); pthread_cond_broadcast(&g_cond); pthread_cond_signal(&g_cond); pthread_mutex_unlock(&g_mutex); // Start 100 thread on cond timed wait for (int i= 1; i< 100; i++) { condtimedwait_param[j][i].i= i; condtimedwait_param[j][i].j= j; pthread_create(&condwait_thread[j][i], &condwait_attr, &condtimedwait_start_func, &condtimedwait_param[j][i]); } // wait for all threads to start while (true) { pthread_mutex_lock(&g_mutex); if (g_active_threads_ct[j] == 100) { pthread_mutex_unlock(&g_mutex); break; } pthread_mutex_unlock(&g_mutex); } // broadcast threads pthread_mutex_lock(&g_mutex); pthread_cond_broadcast(&g_cond); pthread_mutex_unlock(&g_mutex); } for (int i= 0; i<20; i++) printf("active threads batch %u: %u finished threads: %u, timeout: %u\n", i, g_active_threads_ct[i], g_finished_threads_ct[i], g_timedout_threads_ct[i]); return 0; } void *condtimedwait_start_func(void *param) { struct timespec waittime; struct s_param params= *(struct s_param *)param; int id= params.i; int batch= params.j; printf("Timed condwait thread %u starts (batch %u).\n", id, batch); pthread_mutex_lock(&g_mutex); g_active_threads_ct[batch]++; if (id == 0) { set_timespec(waittime, 10); } else { set_timespec(waittime, 30); } int result= pthread_cond_timedwait(&g_cond, &g_mutex,&waittime); if (result == ETIMEDOUT) { printf("Thread %u timed out.\n", id); g_timedout_threads_ct[batch]++; pthread_cond_signal(&g_cond_ping_main); } g_finished_threads_ct[batch]++; pthread_mutex_unlock(&g_mutex); return NULL; } void *condwait_start_func(void *param) { int id= *(int *)param; printf("Condwait thread %u starts.\n", id); pthread_mutex_lock(&g_mutex); int result= pthread_cond_wait(&g_cond, &g_mutex); pthread_cond_broadcast(&g_cond_ping_main); pthread_mutex_unlock(&g_mutex); return NULL; }