线程池模型

  1 /*
  2  * 2.创建4个调用线程,然后主线程每次负责向全局变量box填一个数据,数据填好后4个线程中某个线程将数据
  3  *     取出并分析是否包含数字'0'  最后主线程分配完成后 通过取消机制取消取数据的线程
  4 */
  5 
  6 #include <stdio.h>
  7 #include <pthread.h>
  8 
  9 #define         NR       4
 10 
 11 static pthread_mutex_t mm   =PTHREAD_MUTEX_INITIALIZER;
 12 static pthread_cond_t  empty=PTHREAD_COND_INITIALIZER;
 13 static pthread_cond_t  fully=PTHREAD_COND_INITIALIZER;
 14 
 15 static  int   box=0;
 16 
 17 void *doWork(void *arg);
 18 int checkNum(int num,int n);
 19 void safeExit(void);
 20 
 21 int main(void)
 22 {
 23     long  i,num,ret;
 24     pthread_t  tid[NR];
 25 
 26     for(i=0;i<NR;i++)
 27     {
 28        ret=pthread_create(&tid[i],NULL,doWork,(void *)i);
 29        if(ret!=0)
 30        {
 31            fprintf(stderr,"create thread failed.\n");
 32            return 1;
 33        }
 34     }
 35     //分配任务(填装数据)
 36     for(num=1;num<=1000;num++)
 37     {
 38         pthread_mutex_lock(&mm);
 39         while(box!=0)
 40         {
 41            pthread_cond_wait(&empty,&mm);  //等待empty信号,没有则睡眠并释放锁,唤醒持有锁,没锁则等待
 42         }
 43         box=num;
 44        pthread_mutex_unlock(&mm); //释放锁
 45        pthread_cond_signal(&fully); //发信号
 46     }
 47 
 48 
 49     pthread_mutex_lock(&mm);  //此处加锁是保证最后一个数据取完以后再开始执行下面的取消请求,
                      防止次线程拿到数据还没来的及处理就被取消,造成数据丢失
50 while(box!=0) 51 { 52 pthread_cond_wait(&empty,&mm); 53 } 54 pthread_mutex_unlock(&mm); 55 56 //sleep(3); 57 //任务分发完成 取消结束任务线程 58 for(i=0;i<NR;i++) 59 { 60 ret=pthread_cancel(tid[i]); 61 if(ret!=0){ 62 fprintf(stderr,"发送取消请求<%dth>线程失败!\n",i); 63 i--;//再次重试 64 } 65 } 66 67 //阻塞等待任务线程结束 68 for(i=0;i<NR;i++) 69 { 70 pthread_join(tid[i],NULL); 71 } 72 printf("====work over=====\n"); 73 74 return 0; 75 } 76 void *doWork(void *arg) 77 { 78 int num; 79 80 //设定线程退出清理程序 用于线程持有锁被取消而未解锁 81 pthread_cleanup_push(safeExit,NULL); 82 83 while(1) 84 { 85 pthread_mutex_lock(&mm); 86 while(box==0) 87 { 88 /* 89 cancel请求到来 唤醒此处休眠的线程 但是此线程醒来必须持有锁mm,然后响应 cancel, 90 如果某个线程被cancel唤醒而又无法获取到锁mm 则再次阻塞等锁 此时无法取消 91 */ 92 pthread_cond_wait(&fully,&mm); 93 } 94 95 //确保被取消时任务完整完成 96 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE,NULL); 97 num=box;//取走数据 98 box=0;//清空数据盒子 99 pthread_mutex_unlock(&mm); 100 pthread_cond_signal(&empty); 101 102 103 //再慢慢去处理数据 104 if(checkNum(num,0)) 105 { 106 printf("%dth thread num:%d include '0'\n",(long)arg,num); 107 } 108 else 109 { 110 printf("%dth thread num:%d not include '0'\n",(long)arg,num); 111 } 112 pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,NULL); 113 pthread_testcancel();//设置取消点 114 } 115 116 return (void *)0; 117 pthread_cleanup_pop(0); 118 } 119 int checkNum(int num,int n) 120 { 121 do{ 122 if(num%10==n) 123 return 1; 124 num/=10; 125 usleep(20000);//模拟分析数据需要一定的时间 126 }while(num!=0); 127 128 return 0; 129 } 130 void safeExit(void)  //保证  锁有加才有减,谁加谁减 131 { 132 //测试是否持有锁 133 pthread_mutex_trylock(&mm); 134 135 pthread_mutex_unlock(&mm); 136 }

 

posted @ 2018-04-27 19:42  edan  阅读(613)  评论(0编辑  收藏  举报