#include #include #include /* statically allocated mutex initialization */ pthread_mutex_t shared_region = PTHREAD_MUTEX_INITIALIZER; static int active = 0; typedef struct __thread_data { pthread_t thread_id; int thread_index; int thread_pause; int thread_exec; int thread_wait; int thread_run; } thread_data; #include /* STDIN_FILENO */ #include /* struct termios */ #define MASK_LFLAG (ICANON|ECHO|ECHOE|ISIG) int getch(void) { struct termios oldt, newt; int ch; tcgetattr(STDIN_FILENO, &oldt); newt = oldt; newt.c_lflag &= ~MASK_LFLAG; tcsetattr(STDIN_FILENO, TCSANOW, &newt); ch = getchar(); tcsetattr(STDIN_FILENO, TCSANOW, &oldt); return ch; } void* thread_exec(void* arg) { if(arg) { thread_data *pdata = (thread_data*) arg; pdata->thread_run = 1; while(pdata->thread_exec) { if(pdata->thread_pause) { if(pdata->thread_run) { printf("[Thread-%d] Thread Paused!\n",pdata->thread_index); pdata->thread_run = 0; } continue; } if(!pdata->thread_run) { printf("[Thread-%d] Thread Resumes\n",pdata->thread_index); pdata->thread_run = 1; } printf("[Thread-%d] Sleeping %d seconds\n",pdata->thread_index, pdata->thread_wait); sleep(pdata->thread_wait); /* something happened while you were sleeping */ if(!pdata->thread_exec) break; pthread_mutex_lock(&shared_region); printf("[Thread-%d] Changing active from %d to %d!\n", pdata->thread_index,active,pdata->thread_index); active = pdata->thread_index; pthread_mutex_unlock(&shared_region); } pthread_exit(0); } return 0x0; } int main(int argc, char *argv[]) { thread_data exec1, exec2; int not_done = 1, test; /* start random number generator */ srand(time(0x0)); /** initialize exec1 */ exec1.thread_index = 1; exec1.thread_pause = 1; exec1.thread_exec = 1; exec1.thread_wait = (rand()%10)+1; exec1.thread_run = 0; pthread_create(&exec1.thread_id,0x0,&thread_exec,(void*)&exec1); /** initialize exec2 */ exec2.thread_index = 2; exec2.thread_pause = 1; exec2.thread_exec = 1; exec2.thread_wait = (rand()%10)+1; exec2.thread_run = 0; pthread_create(&exec2.thread_id,0x0,&thread_exec,(void*)&exec2); /** main loop for main thread */ sleep(1); printf("[Main] Starting threads execution...\n"); exec1.thread_pause = 0; exec2.thread_pause = 0; while(not_done) { printf("[Main] Exit, Pause/Resume, andomize Sleep\n"); switch(test=getch()) { case 0x1B: /** ASCII ESC */ not_done = 0; break; case 0x20: /** ASCII SPACE */ exec1.thread_pause = !exec1.thread_pause; exec2.thread_pause = !exec2.thread_pause; break; case (int)'R': printf("[Main] Pause threads execution...\n"); exec1.thread_pause = 1; exec2.thread_pause = 1; printf("[Main] Waiting for threads to pause...\n"); while(exec1.thread_run||exec2.thread_run); printf("[Main] Randomizing Sleep Params...\n"); exec1.thread_wait = (rand()%10)+1; exec2.thread_wait = (rand()%10)+1; printf("[Main] Wait1=%d, Wait2=%d\n",exec1.thread_wait, exec2.thread_wait); printf("[Main] Resume threads execution...\n"); exec1.thread_pause = 0; exec2.thread_pause = 0; break; default: printf("[CHECK]=>'%02X'\n",test); } } /* stop threads */ printf("[Main] Stopping threads execution...\n"); exec1.thread_exec = 0; exec2.thread_exec = 0; /* wait threads to finish */ printf("[Main] Waiting for threads to finish...\n"); pthread_join(exec1.thread_id,0x0); pthread_join(exec2.thread_id,0x0); printf("[Main] Done!\n"); return 0; }