C语言众包系统任务队列实现:区分任务类型的技术问询
解决众包系统任务队列的实现方案
核心思路
通过三个队列+任务状态标记实现需求:
- 总队列:存储所有任务,维护全局"先到先服务"的顺序
- 类型专属队列:分别存储图像标注、文档翻译任务,维护各自类型的FIFO顺序
- 任务状态标记:给任务添加已分配标记,解决不同出队操作之间的同步问题,避免重复分配任务
数据结构定义
任务类型枚举
typedef enum { TASK_LABELING, // 图像标注任务 TASK_TRANSLATION, // 文档翻译任务 TASK_OTHER // 其他类型任务 } TaskType;
任务结构体(扩展类型与状态字段)
typedef struct { char* task_name; // 任务名称 long timestamp; // 创建时间戳 TaskType type; // 任务类型 int is_dequeued; // 分配状态:0=未分配,1=已分配 } Task;
众包系统队列集合
// 封装所有需要的队列 typedef struct { Queue* total_queue; // 全局任务队列 Queue* labeling_queue; // 图像标注任务队列 Queue* translation_queue; // 文档翻译任务队列 } CrowdsourcingSystem;
核心操作实现
1. 初始化众包系统
void init_crowdsourcing_system(CrowdsourcingSystem* system) { system->total_queue = init_queue(); system->labeling_queue = init_queue(); system->translation_queue = init_queue(); }
2. 入队任务(enqueueTask)
将任务同时加入全局队列和对应类型的专属队列(其他类型仅加入全局队列)
void enqueueTask(CrowdsourcingSystem* system, Task* task) { // 初始化任务状态为未分配 task->is_dequeued = 0; // 加入全局队列 enqueue(system->total_queue, task); // 根据类型加入对应专属队列 switch(task->type) { case TASK_LABELING: enqueue(system->labeling_queue, task); break; case TASK_TRANSLATION: enqueue(system->translation_queue, task); break; case TASK_OTHER: // 其他类型无需加入专属队列 break; default: // 处理无效任务类型 break; } }
3. 取出全局最久任务(dequeueTask)
先清理全局队列中已被分配的任务,再取出头部未分配任务,同步更新对应类型队列的状态
Task* dequeueTask(CrowdsourcingSystem* system) { // 清理全局队列中已分配的任务 while (!is_empty(system->total_queue)) { Task* front_task = first(system->total_queue); if (front_task->is_dequeued) { dequeue(system->total_queue); } else { break; } } if (is_empty(system->total_queue)) { return NULL; // 无任务可分配 } Task* task = dequeue(system->total_queue); task->is_dequeued = 1; // 标记为已分配 // 同步清理对应类型队列的已分配任务 switch(task->type) { case TASK_LABELING: while (!is_empty(system->labeling_queue)) { Task* label_front = first(system->labeling_queue); if (label_front->is_dequeued) { dequeue(system->labeling_queue); } else { break; } } break; case TASK_TRANSLATION: while (!is_empty(system->translation_queue)) { Task* trans_front = first(system->translation_queue); if (trans_front->is_dequeued) { dequeue(system->translation_queue); } else { break; } } break; default: break; } return task; }
4. 取出图像标注最久任务(dequeueLabeling)
先清理标注队列中已被分配的任务,再取出头部未分配任务并标记状态
Task* dequeueLabeling(CrowdsourcingSystem* system) { // 清理标注队列中已分配的任务 while (!is_empty(system->labeling_queue)) { Task* front_task = first(system->labeling_queue); if (front_task->is_dequeued) { dequeue(system->labeling_queue); } else { break; } } if (is_empty(system->labeling_queue)) { return NULL; // 无图像标注任务可分配 } Task* task = dequeue(system->labeling_queue); task->is_dequeued = 1; // 标记为已分配 return task; }
5. 取出文档翻译最久任务(dequeueTranslation)
逻辑与dequeueLabeling一致,针对翻译队列处理
Task* dequeueTranslation(CrowdsourcingSystem* system) { // 清理翻译队列中已分配的任务 while (!is_empty(system->translation_queue)) { Task* front_task = first(system->translation_queue); if (front_task->is_dequeued) { dequeue(system->translation_queue); } else { break; } } if (is_empty(system->translation_queue)) { return NULL; // 无文档翻译任务可分配 } Task* task = dequeue(system->translation_queue); task->is_dequeued = 1; // 标记为已分配 return task; }
注意事项
- 任务内存管理:任务出队后,使用完毕需手动释放
task->task_name和task本身,避免内存泄漏 - 异常处理:可根据需求扩展无效任务类型、空队列等场景的错误提示逻辑
内容的提问来源于stack exchange,提问作者User
相关产品推荐
相关产品推荐

