# 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 %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.xiwind-corp.com/tech/python-library/queue-zhu-lie-tong-bu.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
