You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

多进程超时装饰器类遇Pickling错误,求将Windows兼容超时函数改写为装饰器

Great call using multiprocessing.Pool for timeout handling on Windows—this avoids the pitfalls of signal-based or thread-based approaches that often fail there. Converting your existing function into a reusable decorator is straightforward, and we can make it flexible so you can apply it to any function with a specified timeout.


Parameterized Timeout Decorator Implementation

Here's how to wrap your logic into a clean, reusable decorator that accepts a timeout value:

import multiprocessing
from multiprocessing import Pool, TimeoutError

def timeout(timeout_seconds):
    def decorator(func):
        def wrapper(*args, **kwargs):
            # Create a single-process pool to isolate the target function
            with Pool(processes=1) as pool:
                # Submit the function call with its arguments/keyword arguments
                result = pool.apply_async(func, args=args, kwds=kwargs)
                try:
                    # Wait for the result with the specified timeout
                    return result.get(timeout=timeout_seconds)
                except TimeoutError:
                    # Re-raise the timeout exception so the caller can handle it
                    raise
        return wrapper
    return decorator

How It Works

  • Parameterized structure: First you pass the timeout value (e.g., @timeout(5) for a 5-second limit), then the decorator wraps your target function.
  • Isolation via Pool: The single-process pool ensures the target function runs in a separate process, which is critical for reliable timeout handling on Windows.
  • Exception consistency: It preserves the original behavior of raising multiprocessing.TimeoutError when the function exceeds the timeout, so you can catch and handle this exactly as before.
  • Clean cleanup: The with statement guarantees the pool is properly closed and resources are released after the function completes or times out.

Example Usage

import time

# Decorate a function with a 3-second timeout
@timeout(3)
def slow_operation(delay):
    time.sleep(delay)
    return f"Success after {delay} seconds"

# Test with a short delay (completes on time)
try:
    print(slow_operation(2))  # Output: Success after 2 seconds
except TimeoutError:
    print("Operation timed out")

# Test with a long delay (triggers timeout)
try:
    print(slow_operation(5))
except TimeoutError:
    print("Operation timed out")  # This will execute

Critical Windows-Specific Note

When running on Windows, always wrap code that uses the decorated function in if __name__ == '__main__':—this prevents infinite process spawning, which is a requirement for multiprocessing to work correctly:

if __name__ == '__main__':
    try:
        slow_operation(5)
    except TimeoutError:
        print("Timed out!")

Also, ensure the function being decorated (and any arguments passed to it) are pickleable—most standard functions and data types work fine, but custom objects may need explicit pickling support.

内容的提问来源于stack exchange,提问作者ic_fl2

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 07:19:14