使用Python实现具备强制终止的线程和协程运行机制

在Python中,线程和协程是强大的并发编程工具。线程可以实现并行执行,而协程则提供了协作式的并发模型。本文将介绍如何使用Python创建一个类,实现一个函数在新线程中独立运行,并提供强制停止的功能。同时,我们将结合线程和协程的机制,使得函数能够在协程中运行,并通过设置停止信号来强制终止协程的执行。

首先,我们定义一个名为CoroutineRunner的类,用于管理线程和协程的运行。该类的主要功能包括启动函数、停止函数以及协程的执行控制。

import threading
import asyncio

class CoroutineRunner:
    def __init__(self):
        self.loop = None
        self.thread = None
        self.stop_event = threading.Event()
        self.stop_event.set()

    def start(self, target_function, *args, **kwargs):
        if self.stop_event.is_set():
            self.stop_event.clear()
            self.thread = threading.Thread(target=self._run_coroutine, args=(target_function, args, kwargs))
            self.thread.start()

    def stop(self):
        if not self.stop_event.is_set():
            self.stop_event.set()
            self.thread.join()

    def _run_coroutine(self, target_function, args, kwargs):
        async def _wrapper():
            try:
                await target_function(*args, **kwargs)
            except asyncio.CancelledError:
                pass

        self.loop = asyncio.new_event_loop()
        asyncio.set_event_loop(self.loop)
        self.loop.run_until_complete(self._run_wrapper(_wrapper()))
        self.loop.close()

    async def _run_wrapper(self, coro):
        while not self.stop_event.is_set():
            await coro

在上述代码中,我们使用threading.Event()创建了一个停止事件stop_event,并将其默认状态设置为已设置。在start方法中,我们检查stop_event的状态,如果事件已设置,则不启动新线程;如果事件未设置,则清除事件并启动新线程来运行目标函数的协程。

在_run_coroutine方法中,我们创建了一个新的事件循环,并通过asyncio.set_event_loop()将其设置为当前事件循环。然后,我们使用loop.run_until_complete()运行目标函数的协程,并在协程内部捕获asyncio.CancelledError异常以响应取消请求。

在stop方法中,我们设置stop_event的状态为已设置,并等待线程的结束。这将导致目标函数的协程在下一个取消点退出。

接下来,我们可以定义一个示例函数my_function,用于演示在协程中运行的目标函数

async def my_function():
    try:
        while True:
            print("Function is running...")
            await asyncio.sleep(1)
    except asyncio.CancelledError:
        print("Function cancelled.")

最后,我们可以使用CoroutineRunner类来运行目标函数,并在需要时强制停

完成代码如下:

import threading
import asyncio

class CoroutineRunner:
    def __init__(self):
        self.loop = None
        self.thread = None
        self.stop_event = threading.Event()
        self.stop_event.set()

    def start(self, target_function, *args, **kwargs):
        if self.stop_event.is_set():
            self.stop_event.clear()
            self.thread = threading.Thread(target=self._run_coroutine, args=(target_function, args, kwargs))
            self.thread.start()

    def stop(self):
        if not self.stop_event.is_set():
            self.stop_event.set()
            self.thread.join()

    def _run_coroutine(self, target_function, args, kwargs):
        async def _wrapper():
            try:
                await target_function(*args, **kwargs)
            except asyncio.CancelledError:
                pass

        self.loop = asyncio.new_event_loop()
        asyncio.set_event_loop(self.loop)
        self.loop.run_until_complete(self._run_wrapper(_wrapper()))
        self.loop.close()

    async def _run_wrapper(self, coro):
        while not self.stop_event.is_set():
            await coro

# 示例使用的函数
async def my_function(stop_event):
    while not stop_event.is_set():
        print("Function is running...")
        await asyncio.sleep(1)

# 创建 CoroutineRunner 实例并运行函数
runner = CoroutineRunner()
runner.start(my_function, runner.stop_event)

# 等待一段时间后停止函数
import time
time.sleep(5)
runner.stop()

print("Runner stopped.")

运行结果如下:

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

义薄云天us

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值