You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 00:08:14