线程池 (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 }