线程池 (2)--获取任务结果,提交任务

第二部分是关于线程池主要两个操作:  1.提交一个任务

                 2.获取已提交任务的结果

 

   提交任务函数----传入一个函数指针,一个参数void* ,以及是否需要查询返回值,如果不需要返回值效率会高些,如果选择要查询结果,但是任务完成后没有获取结果的话,会一直占用空间

   如果是不需要返回值返回1,否则返回key,失败返回0

  根据key值查询任务,如果存在任务,返回任务状态,否则返回NOSOCHWOCK,就是前篇枚举的值,当任务结果是完成时,销毁此结果

  

 1 int ThreadPool::PushTask(void *(*task)(void *),void *argc,bool ifneedRet=false)
 2 {
 3     Task_t Work;
 4     Work.arg = argc;
 5     Work.work = task;
 6     if (ifneedRet == true) {    //需要返回值的处理
 7         keyidLock.lock();        //①得到一个编号,超过42亿会有一次0,以后可以在管理者中管理,协同超时不取的结果销毁
 8         Work.key = keyid++;
 9         keyidLock.unlock();    
10     }
11     else {                        //不需要返回值
12         Work.key = 0;
13     }
14 
15     
16     TaskQLock.lock();        //放入任务
17     if (TaskQ->Push(Work)) {
18         TaskQLock.unlock();
19     }
20     else {                    //任务插入失败,比如队列满了
21         TaskQLock.unlock();    
22         return 0;            //返回0插入失败
23     }
24 
25     if (ifneedRet == true) {        //需要返回值的话先将其结果状态放到map里
26         Ret_t tmp = {
27             TODO,NULL
28         };
29 
30         RetTreeLock.lock();//以写方式独占
31         RetTree.insert(std::pair<int, Ret_t>(Work.key, tmp));
32         RetTreeLock.unlock();    //写锁释放
33     }
34     TaskCondVar.notify_one();        //唤醒一个线程去做任务,如果没阻塞的线程无效果
35 
36     return Work.key==0?1:Work.key;        //有返回返回key,无返回返回1代表成功
37 }
38 
39 Ret_t ThreadPool::GetResult(int key) {        //选择了有返回值却不Get会有空间浪费,日后可以加个限时销毁结果①
40     Ret_t ret;
41 
42 
43     RetTreeLock.lock();        //写锁定
44     auto it = RetTree.find(key);    //查找
45     if (it == RetTree.end()) {
46         ret.flag = NOSUCHWORK;    //无此元素
47     }
48     else {
49         ret = it->second;
50       if(ret->flag==OK)  RetTree.erase(it);        //查询到完成之后的结果销毁掉
51     }
52     RetTreeLock.unlock();
53 
54     return ret;
55 }

 

posted @ 2018-12-04 11:00  戳戳熊  阅读(735)  评论(0编辑  收藏  举报