Python 대기열: FIFO, LIFO 예

⚡ 스마트 요약

Python 큐는 항목을 저장하고 정의된 순서대로 방출하는 선형 데이터 구조입니다. 큐 모듈은 작업 관리, 데이터 버퍼링, 스레드 간 작업 조정을 안전하게 수행하기 위해 FIFO, LIFO 및 우선순위 기반 방식을 제공합니다.

  • 🔢 선입선출: Queue 클래스는 가장 오래된 항목부터 먼저 제거하므로 작업 스케줄링 및 버퍼링에 적합합니다.
  • 🔁 LIFO: LifoQueue 클래스는 스택처럼 동작하여 가장 최근 항목부터 먼저 제거합니다.
  • 📦 핵심 방법: put(), get(), qsize(), empty(), full() 함수는 항목을 관리하고 큐 상태를 보고합니다.
  • 🧵 스레드 안전: 큐 모듈은 잠금을 처리하므로 여러 스레드가 하나의 큐를 안전하게 공유할 수 있습니다.
  • 🎯 우선 순위 : PriorityQueue는 항목을 삽입 순서가 아닌 우선순위에 따라 해제합니다.
  • 🤖 AI 도움말: AI 비서는 간단한 질문만으로 대기열 코드를 생성하고 FIFO와 LIFO의 장단점을 설명합니다.

Python 대기열 FIFO LIFO

Python 대기줄?

큐는 데이터를 보관하는 컨테이너입니다. 먼저 입력된 데이터가 먼저 제거되므로 대기열을 FIFO(선입선출)라고도 합니다. 대기열에는 앞뒤로 두 개의 끝이 있습니다. 항목은 후면에서 입력되고 전면에서 제거됩니다.

어떻게 Python 대기열 작업?

대기열은 티켓 카운터에서 줄을 서서 기다리는 사람들의 줄, 먼저 서있는 사람이 먼저 티켓을 받고 다음 사람이 순서대로 진행되는 실제 사례와 쉽게 비교할 수 있습니다. 대기열 데이터 구조에도 동일한 논리가 적용됩니다.

다음은 대기열을 도식적으로 표현한 것입니다.

Python 대기열 작업

The 후방 항목이 대기열 내부에 삽입되는 지점을 나타냅니다. 이 예에서는 7이 해당 값입니다.

The 대기열의 항목이 제거되는 지점을 나타냅니다. 그림에 표시된 대로 대기열에서 항목을 제거하면 얻게 되는 첫 번째 요소는 1입니다.

항목 1은 대기열에 가장 먼저 삽입된 항목이고, 항목을 제거하는 동안 가장 먼저 나오는 항목입니다. 따라서 대기열을 FIRST IN FIRST OUT(FIFO)이라고 합니다.

Python 대기열 작업

대기열에 있는 항목은 순서대로 제거되며 그 사이에는 제거할 수 없습니다. 대기열에서 항목 5를 무작위로 제거할 수는 없습니다. 그렇게 하려면 5 이전의 모든 항목을 제거해야 합니다. 대기열에 있는 항목은 삽입된 순서대로 제거됩니다.

대기열 유형 Python

대기열에는 주로 두 가지 유형이 있습니다. Python:

  • 선입 선출 대기열: 이를 위해 먼저 나가는 요소가 가장 먼저 나옵니다. FIFO를 사용하려면 다음을 호출해야 합니다. 대기줄() 대기열 모듈의 클래스입니다.
  • 후입선출 대기열: 여기에서는 마지막에 입력된 요소가 가장 먼저 나옵니다. LIFO를 사용하려면 다음을 호출해야 합니다. 리포큐() 대기열 모듈의 클래스입니다.

Python 대기열 설치

파이썬에서 큐를 사용하는 것은 매우 쉽습니다. 코드에서 대기열을 활용하기 위해 따라야 할 단계는 다음과 같습니다.

단계 1) 아래와 같이 대기열 모듈을 가져오기만 하면 됩니다.

import queue

이 모듈은 기본적으로 Python에서 사용할 수 있으며 대기열 작업을 시작하기 위해 추가 설치가 필요하지 않습니다. 대기열에는 FIFO(선입선출)와 LIFO(후입선출)의 두 가지 유형이 있습니다.

단계 2) FIFO 대기열을 사용하려면 아래와 같이 가져온 대기열 모듈을 사용하여 Queue 클래스를 호출하세요.

import queue
q1 = queue.Queue()

단계 3) LIFO 대기열을 사용하려면 아래와 같이 LifoQueue() 클래스를 호출하십시오.

import queue
q1 = queue.LifoQueue()

Queue 및 LifoQueue 클래스 내에서 사용 가능한 메서드

다음은 Queue와 LifoQueue 클래스 내부에서 사용 가능한 중요한 메서드입니다.

  • 넣다(항목): 그러면 항목이 대기열에 추가됩니다.
  • 얻다(): 그러면 대기열에서 항목이 반환됩니다.
  • 비어 있는(): 대기열이 비어 있으면 true를 반환하고 항목이 있으면 false를 반환합니다.
  • q크기(): 대기열의 크기를 반환합니다.
  • 가득한(): 큐가 가득 찼으면 true를 반환하고, 그렇지 않으면 false를 반환합니다.

선입 선출 대기열의 예

선입선출의 경우, 먼저 들어간 요소가 가장 먼저 나옵니다.

대기열에 추가 및 항목 추가

대기열에 항목을 추가하는 예제를 살펴보겠습니다. 대기열 작업을 시작하려면 먼저 아래 예와 같이 모듈 대기열을 가져옵니다.

항목을 추가하려면 예제에 표시된 대로 put() 메소드를 사용할 수 있습니다.

import queue
q1 = queue.Queue()
q1.put(10) #this will additem 10 to the queue.

기본적으로 대기열의 크기는 무한하며 대기열에 항목을 원하는 만큼 추가할 수 있습니다. 대기열의 크기를 정의하려는 경우 다음과 같이 동일한 작업을 수행할 수 있습니다.

import queue
q1 = queue.Queue(5) #The max size is 5.
q1.put(1)
q1.put(2)
q1.put(3)
q1.put(4)
q1.put(5)
print(q1.full()) # will return true.

출력:

True

이제 대기열의 크기는 5이고 5개 이상의 항목을 차지하지 않으며 q1.full() 메서드는 true를 반환합니다. 항목을 더 추가하면 더 이상 코드가 실행되지 않습니다.

대기열에서 항목 제거

대기열에서 항목을 제거하려면 get()이라는 메서드를 사용할 수 있습니다. 이 메서드는 호출 시 대기열의 항목을 허용합니다.

다음 예제는 대기열에서 항목을 제거하는 방법을 보여줍니다.

import queue
q1 = queue.Queue()
q1.put(10)

item1 = q1.get()

print('The item removed from the queue is ', item1)

출력:

The item removed from the queue is  10

후입선출 대기열 예

첫 번째 출력 대기열의 마지막 경우에는 마지막에 입력된 요소가 가장 먼저 나옵니다.

LIFO로 작업하려면, 즉 First Out 대기열의 마지막 대기열 모듈을 가져와서 LifoQueue() 메서드를 사용해야 합니다.

대기열에 추가 및 항목 추가

여기서는 LIFO 대기열에 항목을 추가하는 방법을 살펴보겠습니다.

import queue
q1 = queue.LifoQueue()
q1.put(10)

위의 예와 같이 LifoQueue에서 put() 메서드를 사용해야 합니다.

대기열에서 항목 제거

LIFOqueue에서 항목을 제거하려면 get() 메서드를 사용할 수 있습니다.

import queue
q1 = queue.LifoQueue()
q1.put(10)

item1 = q1.get()

print('The item removed from the LIFO queue is ', item1)

출력:

The item removed from the LIFO queue is  10

대기열에 1개 이상의 항목 추가

위의 예에서는 단일 항목을 추가하고 FIFO 및 LIFOqueue에 대한 항목을 제거하는 방법을 살펴보았습니다. 이제 두 개 이상의 항목을 추가하고 제거하는 방법을 살펴보겠습니다.

FIFOqueue에 추가 및 항목 추가

import queue
q1 = queue.Queue()

for i in range(20):
    q1.put(i) # this will additem from 0 to 20 to the queue

FIFOqueue에서 항목 제거

import queue
q1 = queue.Queue()

for i in range(20):
    q1.put(i) # this will additem from 0 to 20 to the queue

while not q1.empty():
print("The value is ", q1.get()) # get() will remove the item from the queue.

출력:

The value is  0
The value is  1
The value is  2
The value is  3
The value is  4
The value is  5
The value is  6
The value is  7
The value is  8
The value is  9
The value is  10
The value is  11
The value is  12
The value is  13
The value is  14
The value is  15
The value is  16
The value is  17
The value is  18
The value is  19

LIFOqueue에 항목 추가 및 항목

import queue
q1 = queue.LifoQueue()
for i in range(20):
    q1.put(i) # this will additem from 0 to 20 to the queue

LIFOqueue에서 항목 제거

import queue
q1 = queue.LifoQueue()

for i in range(20):
    q1.put(i) # this will additem from 0 to 20 to the queue

while not q1.empty():
print("The value is ", q1.get()) # get() will remove the item from the queue.

출력:

The value is  19
The value is  18
The value is  17
The value is  16
The value is  15
The value is  14
The value is  13
The value is  12
The value is  11
The value is  10
The value is  9
The value is  8
The value is  7
The value is  6
The value is  5
The value is  4
The value is  3
The value is  2
The value is  1
The value is  0 

대기열 정렬

다음 예제는 큐 정렬을 보여줍니다. 정렬에 사용된 알고리즘은 버블 정렬입니다.

import queue
q1 = queue.Queue()
#Addingitems to the queue
q1.put(11)
q1.put(5)
q1.put(4)
q1.put(21)
q1.put(3)
q1.put(10)

#using bubble sort on the queue
n =  q1.qsize()
for i in range(n):
    x = q1.get() # the element is removed
    for j in range(n-1):
        y = q1.get() # the element is removed
        if x > y :  
            q1.put(y)   #the smaller one is put at the start of the queue
        else:
            q1.put(x)  # the smaller one is put at the start of the queue
            x = y     # the greater one is replaced with x and compared again with nextelement
    q1.put(x)

while (q1.empty() == False): 
print(q1.queue[0], end = " ")  
        q1.get()

출력:

3 4 5 10 11 21

Rev대기열 삭제 중

대기열을 되돌리려면 다른 대기열과 재귀를 사용할 수 있습니다.

다음 예에서는 대기열을 반대로 바꾸는 방법을 보여줍니다.

예:

import queue
q1 = queue.Queue()

q1.put(11)
q1.put(5)
q1.put(4)
q1.put(21)
q1.put(3)
q1.put(10)

def reverseQueue (q1src, q2dest) :  
    buffer = q1src.get()
    if (q1src.empty() == False) :
reverseQueue(q1src, q2dest)      #using recursion
    q2dest.put(buffer)
return q2dest

q2dest = queue.Queue()
qReversed = reverseQueue(q1,q2dest)

while (qReversed.empty() == False): 
print(qReversed.queue[0], end = " ")  
        qReversed.get()

출력:

10 3 21 4 5 11

자주 묻는 질문

큐는 FIFO 방식이므로 가장 오래된 항목이 먼저 제거되는 반면, 스택은 LIFO 방식이므로 가장 새로운 항목이 먼저 제거됩니다. Python's의 큐 모듈은 FIFO 동작을 위한 Queue와 스택 동작을 위한 LifoQueue를 제공합니다.

네. Queue, LifoQueue, PriorityQueue는 멀티스레드 프로그램을 위해 설계되었으며 내부적으로 락킹을 처리하므로 여러 생산자 및 소비자 스레드가 경쟁 조건이나 데이터 손상 없이 하나의 큐를 공유할 수 있습니다.

`queue.Queue`는 스레드 안전성을 보장하며 생산자-소비자 스레딩을 위해 설계되었습니다. `collections.deque`는 단일 스레드 코드에서 사용하기에 더 빠르고 범용적인 양방향 큐로, 양쪽 끝에서 빠른 추가 및 제거를 지원합니다.

PriorityQueue는 항목을 삽입 순서가 아닌 우선순위 순서대로 해제합니다. (우선순위, 데이터) 튜플을 넣고 get() 메서드가 가장 낮은 우선순위의 항목을 먼저 반환하면 스케줄러와 최단 경로 알고리즘에 적합합니다.

기본적으로 get() 메서드는 항목이 사용 가능해질 때까지 대기합니다. 새 항목을 기다리지 않고 즉시 queue.Empty 예외를 발생시키려면 block=False를 전달하거나 get_nowait()를 사용하십시오.

생성자에 maxsize를 전달합니다. 예를 들어 queue.Queue(5)와 같이 사용합니다. 큐가 가득 차면 put() 메서드는 공간이 확보되고 full() 메서드가 True를 반환할 때까지 대기합니다. maxsize가 0이면 큐에 제한이 없습니다.

AI 어시스턴트는 생산자-소비자 큐 코드를 생성하고, FIFO와 LIFO의 장단점을 설명하며, queue.Queue, deque 또는 asyncio.Queue 중 어떤 것이 사용자의 상황에 적합한지 제안합니다. 또한 교착 상태와 누락된 task_done() 호출을 찾아내는 데 도움을 줍니다.

네. GitHub Copilot은 주석에서 큐 설정, put() 및 get() 루프, 작업자 스레드 등을 자동 완성해 줍니다. 에이전트 기반 AI 도구는 한 단계 더 나아가 블로킹 코드를 asyncio.Queue로 리팩토링하고 파일 전체에 오류 처리를 추가합니다.

이 게시물을 요약하면 다음과 같습니다.