"vscode:/vscode.git/clone" did not exist on "fff1994eb1954e4a070a28223d2da4bc810c8d66"
task_queue.cpp 3.21 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
#include "task_queue.h"

/**
 * @brief 任务队列构造函数
 *
 * 初始化任务队列的互斥锁和条件变量,并将shutdown标志设为false。
 */
Task_Queue::Task_Queue() {
    pthread_mutex_init(&this->task_lock, NULL);
    pthread_cond_init(&this->task_cond, NULL);
    this->shutdown = false;
}

/**
 * @brief 销毁任务队列,释放互斥锁资源
 *
 * 析构函数负责销毁任务队列中使用的 pthread_mutex_t 互斥锁。
 * 应在对象生命周期结束时自动调用,确保资源正确释放。
 */
Task_Queue::~Task_Queue() { pthread_mutex_destroy(&this->task_lock); }

/**
 * @brief 向任务队列中添加一个新任务
 *
 * @param f 要执行的任务函数指针
 * @param arg 传递给任务函数的参数
 * @return true 任务添加成功
 *
 * 该函数是线程安全的,会使用互斥锁保护任务队列。
 * 当队列从空变为非空时,会发送条件变量信号通知等待的线程。
 */
bool Task_Queue::add_task(void* f(void*), void* arg) {
    Task current_task = {f, arg};
    pthread_mutex_lock(&this->task_lock);
    this->tasks.push(current_task);
    if(tasks.size() == 1)
        pthread_cond_signal(&this->task_cond);
    pthread_mutex_unlock(&this->task_lock);
    return true;
}

/**
 * 通知所有等待线程队列关闭,并广播条件变量以唤醒它们
 * 调用此方法后,任务队列将不再接受新任务
 */
void Task_Queue::destroy() {
    this->shutdown = true;
    pthread_cond_broadcast(&this->task_cond);
}

/**
 * @brief 从任务队列中提取一个任务
 *
 * 这是一个线程安全的操作,会阻塞直到队列中有任务或收到关闭信号。
 * 如果队列关闭且为空,返回一个无效任务和false。
 * 否则返回队列头部任务和true。
 *
 * @return std::pair<Task, bool> 返回的任务和是否成功的标志
 */
std::pair<Task, bool> Task_Queue::extract_task() {
    pthread_mutex_lock(&this->task_lock);
    while(this->tasks.size() == 0 && !shutdown)
        pthread_cond_wait(&this->task_cond, &this->task_lock);
    if(shutdown) {
        pthread_mutex_unlock(&this->task_lock);
        return std::make_pair(Task(), false);
    }
    // task must be greater than one
    auto temp = this->tasks.front();
    this->tasks.pop();
    pthread_mutex_unlock(&this->task_lock);
    return {temp, true};
}

/**
 * @brief 尝试从任务队列中提取一个任务
 *
 * 该函数线程安全地从任务队列中取出一个任务。如果队列为空,则返回空任务和false;
 * 否则返回取出的任务和true。
 *
 * @return std::pair<Task, bool> 返回一个pair,第一个元素是任务对象,第二个元素表示是否成功取出任务
 */
std::pair<Task, bool> Task_Queue::try_extract_task() {
    pthread_mutex_lock(&this->task_lock);
    if(this->tasks.size() == 0) {
        pthread_mutex_unlock(&this->task_lock);
        return std::make_pair(Task(), false);
    } else {
        auto tmp = this->tasks.front();
        this->tasks.pop();
        pthread_mutex_unlock(&this->task_lock);
        return std::make_pair(tmp, true);
    }
}

/**
 * 获取任务队列中当前的任务数量
 * @return 返回任务队列的大小(无符号整型)
 */
unsigned int Task_Queue::size() { return this->tasks.size(); }