zoukankan      html  css  js  c++  java
  • 线程池模型

      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.
    ");
     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>线程失败! ",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===== "); 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' ",(long)arg,num); 107 } 108 else 109 { 110 printf("%dth thread num:%d not include '0' ",(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 }
  • 相关阅读:
    爬虫第二弹之http协议和https协议
    爬虫第一弹之py爬虫的相关概念
    Flask第十四篇- Flask-Session组件、WTForms组件、数据库连接池(POOL)
    Flask第十三篇- flask请求上下文源码解读、http聊天室单聊/群聊(基于gevent-websocket)
    Flask第十二篇- flask中的CBV、werkzeug+上下文初步解读、偏函数和线程安全
    Flask第十一篇装饰器的坑及解决办法、flask中的路由/实例化配置/对象配置/蓝图/特殊装饰器(中间件、重定义错误页面)
    Flask第十八篇 Flask-Migrate
    Flask第十七篇 Flask-Scrip
    Flask第十六篇 Flask-SQLAlchemy
    Flask第十篇 before_request after_request
  • 原文地址:https://www.cnblogs.com/edan/p/8964136.html
Copyright © 2011-2022 走看看