> For the complete documentation index, see [llms.txt](https://docs.xiwind-corp.com/tech/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.xiwind-corp.com/tech/python-library/queue-zhu-lie-tong-bu.md).

# queue 【佇列、同步】

## 簡介

***

queue module 為 threads 之間的通訊和協調提供了同步機制。它提供了各種 Class 和函數來實現不同類型的 queues (佇列)。它們可以用來在 threads 之間以 thread-safe 的方式共用資料，而不會遇到 race conditions 或資料損壞等問題。

常用於 threads 間通信和協調，其中一個 thread 將項目添加到 queue (producer)，另一個 thread 從 queue (consumer) 獲取項目。

例如: multi-producer (生產者)、multi-consumer (消費者) queue，這在 threaded 編程中特別有用。 該 module 允許您創建一個 queue，即使在 multi-threaded 環境中，也可以安全地用於放置和提取項目。

{% hint style="info" %}
由於 [Global Interpreter Lock (GIL)](/tech/python/gil-quan-yu-zhi-yi-qi-suo.md)，Python's threading 並不適合所有類型的任務。 如果您需要執行 CPU 密集型任務，您應該考慮 [multiprocessing](https://docs.python.org/zh-tw/3/library/multiprocessing.html) 或其他方法。
{% endhint %}

{% hint style="info" %}
您可以在 multiprocessing 設置中使用 queues，但應該使用 `multiprocessing.Queue` 而不是 `queue.Queue`。
{% endhint %}

## Queue Objects

***

{% code title="PYTHON" %}

```python
queue.Queue(maxsize = 0)     # 構建一個佇列容器 (先進先出)
queue.SimpleQueue()          # 構建一個佇列容器 (先進先出, 無佇列任務功能)
queue.LifoQueue(maxsize=0)   # 構建一個佇列容器 (後進先出)
```

{% endcode %}

當 `maxsize=0` or `maxsize<0` 時，佇列無窮大。 一旦達到 `maxsize` 大小時，存入資料將會阻塞。

{% code title="PYTHON" %}

```python
from queue import Queue

q = Queue()

for i in range(5):
    q.put(i)

while not q.empty():
    print(q.get())
```

{% endcode %}

{% code title="PYTHON" %}

```python
queue.PriorityQueue(maxsize=0) # 構建一個佇列容器 (最低的值先出)
```

{% endcode %}

回傳值等效 `list() ->sorted() ->list[0], list[1]..` 。 如果 `item` 為不可比較的，則使用 `@dataclasses` 解析。典型模式的資料格式為 `item = (priority_number, data)`。

{% code title="PYTHON" %}

```python
from queue import PriorityQueue

pq = PriorityQueue()

pq.put((3, 'Medium priority'))
pq.put((1, 'High priority'))
pq.put((2, 'Low priority'))

while not pq.empty():
    print(pq.get())
```

{% endcode %}

## Method

***

### put(), put\_nowait()

`put()` 將項目插入 queue。(存放資料)

{% code title="PYTHON" %}

```PYTHON
put(item, block=True, timeout = None)		
```

{% endcode %}

<table><thead><tr><th width="157">參數</th><th>說明</th></tr></thead><tbody><tr><td><strong>item</strong></td><td>要放入 queue 的數據。 它可以是任何資料類型。</td></tr><tr><td><strong>block</strong></td><td>如果 <code>block=True</code> 和 queue 已滿，將阻塞和等待，直到 queue 中出現可用的空閒槽。<br>如果 <code>block=False</code> 和 queue 已滿，將不會等待，立即引發 exception。</td></tr><tr><td><strong>timeout</strong></td><td>當 <code>block=True</code> 時，此參數才起作用。表示等待 queue 中空閒槽的最大秒數。 如果 <code>timeout=None</code> 將無限期地等待。<br>如果 <code>timeout</code> 正數，在這段時間內沒有可用的空閒槽，將等待 <code>timeout</code> 秒，然後才會引發 exception。</td></tr></tbody></table>

`put_nowait()` 向佇列存放資料，可以引發 `queue.Full`。 等效於 `put(item, block=False, timeout = None)`。

{% code title="PYTHON" %}

```python
put_nowait(item)	
```

{% endcode %}

#### 範例

***

{% code title="PYTHON" %}

```python
from queue import Queue
import queue

# Create queue
q = Queue(maxsize=2)

# Add items
q.put('item1')
q.put('item2')

# block=False: Try add item
try:
    q.put('item3', block=False)
except queue.Full:
    print("Queue is full")

# block=True, timeout=2: Try add item
try:
    q.put('item4', block=True, timeout=2)
except queue.Full:
    print("Timeout waiting for the queue to have a free slot")
```

{% endcode %}

**執行結果:**

```txt
Queue is full
Timeout waiting for the queue to have a free slot
```

### get(), get\_nowait()

***

`get()` 從 queue 中刪除一個項目並返回。(取出資料)

{% code title="PYTHON" %}

```python
get(block=True, timeout=None)
```

{% endcode %}

<table><thead><tr><th width="147">參數</th><th>說明</th></tr></thead><tbody><tr><td><strong>block</strong></td><td>如果該時間內沒有可用的佇列槽，則引發 <code>queue.Empty</code>。</td></tr><tr><td><strong>timeout</strong></td><td>當沒有空的佇列槽可用時，阻塞程序。<br>如果 <code>timeout</code> 為正數，則最多阻塞 <code>timeout</code> 秒。</td></tr><tr><td><strong>block</strong></td><td>如果 <code>block=True</code> 和 queue 為空，將阻塞和等待，直到 queue 可以刪除一個項目。<br>如果 <code>block=False</code> 和 queue 為空，將不會等待，立即引發 exception。</td></tr><tr><td><strong>timeout</strong></td><td>當 <code>block=True</code> 時，此參數才起作用。表示等待 queue 項目的最大秒數。 如果 <code>timeout=None</code> 將無限期地等待。<br>如果 <code>timeout</code> 正數，在這段時間內沒有可用的項目，將等待 <code>timeout</code> 秒，然後才會引發 exception。</td></tr></tbody></table>

<br>

`get_nowait()` 向佇列取出資料，不阻塞程序。 等效於`get(block=False, timeout=None)`。

{% code title="PYTHON" %}

```python
get_nowait()
```

{% endcode %}

#### 範例

***

{% code title="PYTHON" %}

```python
from queue import Queue, Empty

# Create queue
q = Queue()
q.put('item1')

# Get item
item = q.get()
print(f'Got {item} from the queue')

# block=False: Try get item
try:
    item = q.get(block=False)
    print(f'Got {item} from the queue')
except Empty:
    print('Queue is empty')

# block=True, timeout=2: Try get item
try:
    item = q.get(block=True, timeout=2)
    print(f'Got {item} from the queue')
except Empty:
    print('Timeout waiting for an item to become available')
```

{% endcode %}
