Python: 동시 프로그래밍(12)

머리말

이 기사에서는 Python의 다중 코루틴 동시 프로그래밍 (2부) 에 대해 논의할 것입니다 . 내장 기본 라이브러리 asyncio를 사용하여 동시성을 달성하고 먼저 공식을 통해 이 모듈을 사용하십시오. 기본적인 사용법과 인식을 가질 수 있도록 먼저 기초를 잘 다져놓고 다음 글에서 자세히 활용하도록 하겠습니다.

이 글은 파이썬 동시 프로그래밍의 12번째 글입니다.이전 글의 주소는 다음과 같습니다.

Python: 동시 프로그래밍(11)_라이온 킹의 블로그-CSDN 블로그

다음 기사의 주소는 다음과 같습니다.

파이썬: 동시 프로그래밍(13)_Lion King's Blog-CSDN Blog

1. 실전

1. 실시간 채팅 시스템을 시뮬레이션합니다. 각 코루틴은 사용자를 나타내며 사용자는 메시지를 보내고 받을 수 있습니다. 모든 메시지는 콘솔에 인쇄됩니다.

import asyncio

# 定义聊天用户类
class ChatUser:
    def __init__(self, name):
        self.name = name

    async def send_message(self, message):
        print(f"{self.name}: Sending message: {message}")
        await asyncio.sleep(1)  # 模拟发送消息的延迟

    async def receive_message(self, message):
        print(f"{self.name}: Received message: {message}")
        await asyncio.sleep(1)  # 模拟接收消息的延迟

# 定义聊天任务
async def chat_task(user):
    while True:
        message = input(f"{user.name}: Enter message (or 'quit' to exit): ")
        if message == "quit":
            break
        await user.send_message(message)
        await user.receive_message(message)

# 创建聊天用户
user1 = ChatUser("User1")
user2 = ChatUser("User2")

# 创建事件循环
loop = asyncio.get_event_loop()

# 运行聊天任务
tasks = [
    asyncio.ensure_future(chat_task(user1)),
    asyncio.ensure_future(chat_task(user2))
]
loop.run_until_complete(asyncio.wait(tasks))

# 关闭事件循环
loop.close()

위의 코드에서 두 개의 채팅 사용자 개체를 만들고 함수를 사용하여 user1채팅 작업을 정의했습니다 . 각 채팅 작업은 코루틴을 통해 메시지를 보내고 받는 사용자의 기능을 구현합니다. 메인 루프에서 두 개의 채팅 작업을 실행하고 모든 작업이 완료될 때까지 대기합니다. 마지막으로 이벤트 루프를 닫습니다.user2chat_taskasyncio.wait()

위의 코드를 실행하면 각 사용자는 콘솔에 메시지를 입력하여 상대방에게 메시지를 보낼 수 있으며, 동시에 상대방이 보낸 메시지를 수신하고 메시지를 콘솔에 출력할 수 있습니다. 이것은 간단한 실시간 채팅 시스템을 시뮬레이트합니다.

2. 주차장에 동시에 진입하고 주차 공간을 놓고 경쟁하는 여러 차량을 시뮬레이션합니다. 각 코루틴은 차량을 나타내며, 주차장 진입 후 임의의 시간 동안 기다린 후 주차장을 떠납니다.

import asyncio
import random

# 定义停车场类
class ParkingLot:
    def __init__(self, capacity):
        self.capacity = capacity
        self.available_spots = capacity

    async def enter(self, car):
        print(f"Car {car} entering the parking lot.")
        if self.available_spots == 0:
            print(f"Car {car} is waiting for a spot.")
            await asyncio.sleep(1)  # 模拟等待时间
            await self.enter(car)  # 递归调用,继续尝试进入停车场
        else:
            self.available_spots -= 1
            print(f"Car {car} parked. Available spots: {self.available_spots}")

    async def exit(self, car):
        await asyncio.sleep(random.randint(1, 5))  # 模拟停留时间
        self.available_spots += 1
        print(f"Car {car} left the parking lot. Available spots: {self.available_spots}")

# 定义车辆任务
async def car_task(car, parking_lot):
    await parking_lot.enter(car)
    await parking_lot.exit(car)

# 创建停车场对象
parking_lot = ParkingLot(capacity=5)

# 创建事件循环
loop = asyncio.get_event_loop()

# 创建车辆任务
tasks = [
    asyncio.ensure_future(car_task(car, parking_lot)) for car in range(10)
]
loop.run_until_complete(asyncio.wait(tasks))

# 关闭事件循环
loop.close()

위의 코드에서는 주차장 객체를 생성 parking_lot하고 car_task함수를 사용하여 차량 작업을 정의했습니다. 각 차량은 코루틴을 통해 주차장 출입 기능을 구현한다. 메인 루프에서 우리는 10개의 차량 작업을 생성하고 다음을 사용하여 asyncio.wait()모든 작업이 완료될 때까지 기다립니다. 각 차량이 주차장에 진입할 때 주차장에 주차 공간이 없을 경우 일정 시간 대기 후 다시 주차장 진입을 시도합니다. 각 차량이 머무르는 시간은 무작위로 주차장에 머무르는 차량의 상황을 시뮬레이션합니다.

위의 코드를 실행하면 여러 대의 차량이 동시에 주차장에 진입하여 주차 공간을 놓고 경쟁하고, 일정 시간 대기 후 주차장을 빠져나가 관련 정보를 동시에 출력할 수 있다. 이는 여러 대의 차량이 동시에 주차장에 진입하는 시나리오를 시뮬레이션합니다.

3. 여러 파일의 내용을 동시에 읽고 읽은 내용을 결과 문자열로 병합

import asyncio

async def read_file(file_name):
    print(f"Reading file: {file_name}")
    content = ""
    try:
        with open(file_name, 'r', encoding="utf-8", errors='ignore') as file:
            content = file.read()
    except FileNotFoundError:
        print(f"File not found: {file_name}")
    return content

async def read_files(file_names):
    tasks = [read_file(file_name) for file_name in file_names]
    results = await asyncio.gather(*tasks)
    return "".join(results)

# 要读取的文件列表
files = ["file1.txt", "file2.txt", "file3.txt"]

# 创建事件循环
loop = asyncio.get_event_loop()

# 执行并发读取文件任务
result = loop.run_until_complete(read_files(files))
print("Merged content:", result)

# 关闭事件循环
loop.close()

위의 코드에서 read_file단일 파일의 내용을 읽고 내용을 코루틴으로 반환하는 함수를 정의했습니다. 그런 다음 파일 이름 목록을 가져오고, 여러 코루틴 작업을 만들고, 를 사용하여 모든 작업이 완료될 때까지 대기하고 결과를 문자열로 병합하는 read_files함수를 정의합니다 .read_fileasyncio.gather

메인 루프에서 이벤트 루프 객체를 생성하고 run_until_completerun coroutine task 메서드를 사용하여 read_files파일 목록을 전달합니다. 마지막으로 결합된 콘텐츠 결과를 인쇄합니다.

위의 코드를 실행하면 여러 파일의 내용을 동시에 읽고 하나의 결과 문자열로 결합할 수 있습니다. 이러한 방식으로 파일 읽기 작업을 보다 효율적으로 처리할 수 있으며 프로그램의 실행 속도를 향상시킬 수 있습니다.

2. asyncio 모듈의 주요 기능

1. 용도 asyncawait키워드

코루틴 함수를 정의할 때 async키워드를 사용하여 함수를 코루틴 함수로 표시한 다음 await코루틴 내부에서 키워드를 사용하여 비동기 작업이 완료될 때까지 기다립니다.

2. asyncio.run()메인 코루틴 실행에 사용

함수를 사용하여 asyncio.run()기본 코루틴을 실행하고 이벤트 루프를 자동으로 생성 및 종료하여 코드 구조를 단순화할 수 있습니다.

3. asyncio.gather()여러 코루틴 작업에 대해 동시 대기 사용

asyncio.gather()함수는 인수로 여러 코루틴 작업을 수신하고 모두 완료될 때까지 기다릴 수 있습니다. 이를 통해 여러 작업을 동시에 실행할 수 있습니다.

4. asyncio.wait()반복 가능한 객체에서 코루틴 작업을 처리하는 데 사용

asyncio.wait()함수는 반복 가능한 객체(예: 목록 또는 컬렉션)에서 코루틴 작업을 수신하고 작업이 완료될 때까지 기다립니다. , 등 의 매개변수를 사용하여 return_when대기 조건을 지정할 수 있습니다.asyncio.FIRST_COMPLETEDasyncio.ALL_COMPLETED

5. asyncio.sleep()일시정지 시간을 만들기 위해 사용

asyncio.sleep()함수는 다른 코루틴이 실행될 수 있도록 지정된 시간 동안 이벤트 루프를 일시 중지할 수 있도록 코루틴에 정지 시간을 생성할 수 있습니다.

6. asyncio.TimeoutError시간 초과 처리에 사용

함수를 사용하여 asyncio.wait_for()코루틴 작업의 제한 시간을 설정하고 asyncio.TimeoutError예외를 포착하여 제한 시간 상황을 처리할 수 있습니다.

7. asyncio.Lock()뮤텍스 구현에 사용

asyncio.Lock()이 클래스는 상호 배제 잠금 메커니즘을 제공하며 코루틴에서 명령문을 사용하여 async with잠금을 획득 및 해제하여 하나의 코루틴만 동시에 공유 리소스에 액세스할 수 있도록 할 수 있습니다.

8. asyncio.Queue()코루틴 간 메시지 전달 구현 에 사용

asyncio.Queue()클래스는 코루틴 간의 메시징 채널로 사용할 수 있습니다. 코루틴은 메시지를 대기열에 넣을 수 있고 다른 코루틴은 대기열에서 메시지를 가져와 코루틴 간의 비동기 통신을 실현할 수 있습니다.

asyncio.run_coroutine_threadsafe()9. 멀티스레딩에서 코루틴을 예약하는 데 사용

asyncio.run_coroutine_threadsafe()함수는 다중 스레드 환경에서 코루틴 작업을 예약하고 실행을 위해 이벤트 루프에 제출할 수 있습니다.

10. asyncio.ensure_future()코루틴을 래핑하는 데 사용

asyncio.ensure_future()Task함수는 이벤트 루프에서 일정 관리 및 관리를 위해 코루틴을 개체로 래핑할 수 있습니다 .

추천

출처blog.csdn.net/weixin_43431593/article/details/131257749