1# 线程安全阻塞队列
2
3## 概述
4
5#### 简介
6
7​线程安全阻塞队列SafeBlockQueue类,提供阻塞和非阻塞版的入队入队和出队接口,并提供可最追踪任务完成状态的的SafeBlockQueueTracking类。
8
9`#include <safe_block_queue.h>`
10## 涉及功能
11
12### 接口说明
13
14### OHOS::SafeBlockQueue
15
16| 返回值       | 名称                                                         |
17| ------------ | ------------------------------------------------------------ |
18|              | **SafeBlockQueue**(int capacity)<br/>构造函数                |
19|              | virtual **~SafeBlockQueue**()<br/>析构函数                   |
20| void         | virtual **Push**(T const& elem)<br/>入队操作(阻塞版)         |
21| bool         | virtual **PushNoWait**(T const& elem)<br/>入队操作(非阻塞版) |
22| T            | **Pop**()<br/>出队操作(阻塞版)                               |
23| bool         | **PopNotWait**(T& outtask)<br/>出队操作(非阻塞版)            |
24| unsigned int | **Size**()<br/>获取队列容量                                  |
25| bool         | **IsEmpty**()<br/>队列判空                                   |
26| bool         | **IsFull**()<br/>队列判满                                    |
27
28
29### OHOS::SafeBlockQueueTracking
30#### class SafeBlockQueueTracking : public SafeBlockQueue
31
32| 返回值   | 名称                                                         |
33| -------- | ------------------------------------------------------------ |
34| explicit | **SafeBlockQueueTracking**(int capacity)<br/>构造函数        |
35|          | virtual **~SafeBlockQueueTracking**()<br/>析构函数           |
36| void     | virtual **Push**(T const& elem)<br/>入队操作(阻塞版)         |
37| bool     | virtual **PushNoWait**(T const& elem)<br/>入队操作(非阻塞版) |
38| bool     | **OneTaskDone**()<br/>一个任务完成时的响应函数               |
39| void     | **Join**()<br/>等待未完成队列                                |
40| int      | **GetUnfinishTaskNum**()<br/>获取未完成任务数                |
41
42
43## 使用示例
44
451. 示例代码(伪代码)
46
47- SafeBlockQueue的示例代码
48
49```c++
50#include <thread>
51#include <functional>
52#include <iostream>
53#include "../include/safe_block_queue.h"
54
55using namespace OHOS;
56using namespace std;
57
58constexpr int SIZE = 10;
59
60class ProductsLine
61{
62public:
63    ProductsLine(int maxSize) : que(maxSize) {}
64
65    void Produce()
66    {
67        for (int i = 0; i < SIZE + 1; i++) {
68            que.Push(i);
69            cout << "Add " << i << " to the line" << endl;
70        }
71    }
72
73    void Consume()
74    {
75        for (int i = 0; i < SIZE + 1; i++) {
76            int out = que.Pop();
77            cout << "Get " << out << " from the line" << endl;
78        }
79    }
80
81    int remains()
82    {
83        return que.Size();
84    }
85
86private:
87    SafeBlockQueue<int> que;
88};
89
90int main()
91{
92    ProductsLine line(SIZE);
93
94    thread producer(bind(&ProductsLine::Produce, ref(line)));
95    this_thread::sleep_for(chrono::milliseconds(1));
96
97    thread consumer(bind(&ProductsLine::Consume, ref(line)));
98    this_thread::sleep_for(chrono::milliseconds(1));
99
100    producer.join();
101    consumer.join();
102
103    if (line.remains()==0) {
104         cout << line.remains() << " elements remains in the queue. Synchronizing success." <<endl;
105    }
106}
107```
108
109- SafeBlockQueueTracking的示例代码
110
111```c++
112#include <thread>
113#include <functional>
114#include <iostream>
115#include "../include/safe_block_queue.h"
116
117using namespace OHOS;
118using namespace std;
119
120constexpr int SIZE = 10;
121
122class ProductsLine
123{
124public:
125    ProductsLine(int maxSize) : que(maxSize) {}
126
127    void Produce()
128    {
129        for (int i = 0; i < SIZE + 1; i++) {
130            que.Push(i);
131            cout << "Add " << i << " to the line" << endl;
132        }
133    }
134
135    void Consume()
136    {
137        for (int i = 0; i < SIZE + 1; i++) {
138            int out = que.Pop();
139            cout << "Get " << out << " from the line" << endl;
140            que.OneTaskDone();
141        }
142    }
143
144    void Join()
145    {
146        que.Join();
147    }
148
149    int UnfinishTaskNum()
150    {
151        return que.GetUnfinishTaskNum();
152    }
153
154private:
155    SafeBlockQueueTracking<int> que;
156};
157
158int main()
159{
160    ProductsLine line(SIZE);
161
162    thread producer(bind(&ProductsLine::Produce, ref(line)));
163    this_thread::sleep_for(chrono::milliseconds(1));
164
165    thread consumer(bind(&ProductsLine::Consume, ref(line)));
166    this_thread::sleep_for(chrono::milliseconds(1));
167
168    line.Join();
169
170    producer.join();
171    consumer.join();
172
173    if (line.UnfinishTaskNum()==0) {
174         cout << line.UnfinishTaskNum() << " elements remains in the queue. Synchronizing success." <<endl;
175    }
176}
177```
178
1792. 测试用例编译运行方法
180
181- 测试用例代码参见base/test/unittest/common/utils_safe_block_queue_test.cppbase/test/unittest/common/utils_safe_block_queue_tracking.cpp
182
183- 使用开发者自测试框架,使用方法参见:[开发自测试执行框架-测试用例执行](https://gitee.com/openharmony/testfwk_developer_test#%E6%B5%8B%E8%AF%95%E7%94%A8%E4%BE%8B%E6%89%A7%E8%A1%8C)
184
185- 使用以下具体命令以运行`safe_block_queue.h`对应测试用例
186```bash
187run -t UT -tp utils -ts UtilsSafeBlockQueueTest
188
189# or
190
191run -t UT -tp utils -ts UtilsSafeBlockQueueTrackingTest
192
193```
194
195## 常见问题
196