<div align="center">
<strong>版本: 0.0.7</strong> |
<a href="https://github.com/sandorn/xtthread">GitHub</a> |
<strong>Python 3.13+</strong>
</div>
# xtthread
xtthread 是一个全面的 Python 并发编程增强库,为标准线程、进程和 Qt 线程提供了更高级的抽象和异常处理机制。作者: sandorn sandorn@live.cn
## 功能特点
- **增强的线程管理**:提供 `ThreadManager` 和 `QtThreadManager` 用于集中管理线程生命周期
- **异常安全的执行**:通过 `safe_call` 装饰器提供统一的异常捕获和日志记录
- **单例线程支持**:实现 `SingletonThread` 和 `ComposedSingletonThread` 等单例模式线程
- **Qt 集成**:提供基于 PyQt6 的线程增强实现
- **Future 模式支持**:多种线程池实现,简化异步任务处理
- **进程管理**:提供增强的进程处理能力
- **生产者-消费者模式**:实现同步和异步版本的任务处理框架
- **丰富的装饰器**:提供多种线程相关的装饰器,简化并发编程
## 安装
### 基本安装
```bash
pip install xtthread
```
### 可选依赖
如果需要使用 Qt 相关功能,请单独安装 PyQt6:
```bash
pip install PyQt6
```
## 快速开始
### 1. 基本线程使用
```python
from xtthread import ThreadBase
# 创建线程并启动
def my_task(name):
import time
time.sleep(1) # 模拟耗时操作
return f"Hello, {name}!"
thread = ThreadBase(target=my_task, args=("World",))
thread.start()
# 获取线程执行结果
result = thread.get_result(timeout=2)
print(result) # 输出: Hello, World!
```
### 2. 使用装饰器简化并发编程
```python
from xtthread import run_in_thread, safe_call
import time
# 在单独线程中执行函数
@run_in_thread
@safe_call
def process_data(data):
time.sleep(1) # 模拟处理时间
return data * 2
# 调用函数(异步执行)
thread = process_data(10)
# 主线程可以做其他事情
print("等待处理结果...")
# 获取结果
result = thread.get_result()
print(f"处理结果: {result}")
```
### 3. 使用线程池处理批量任务
```python
from xtthread import EnhancedThreadPool
import time
# 创建线程池(最多4个工作线程)
with EnhancedThreadPool(max_workers=4) as pool:
# 提交多个任务
tasks = [pool.submit(time.sleep, i * 0.5) for i in range(1, 6)]
# 等待所有任务完成并获取结果
results = pool.wait_all_completed()
print(f"任务完成数量: {len(results)}")
```
### 4. 生产者-消费者模式
```python
from xtthread import Production
import time
import random
# 创建生产者-消费者系统
production = Production(queue_size=10)
# 定义生产者函数
def producer():
for i in range(5):
task_data = random.randint(1, 100)
production.add_task(task_data)
print(f"生产者添加任务: {task_data}")
time.sleep(0.5)
# 定义消费者函数
def consumer(task_data):
print(f"消费者处理任务: {task_data}")
time.sleep(1) # 模拟处理时间
return task_data * 2
# 添加生产者和消费者
production.add_producer(producer)
production.add_consumer(consumer, num_workers=2)
# 启动系统
production.start()
# 等待所有任务完成
production.wait_completed()
# 获取处理结果
results = production.get_results()
print(f"所有结果: {results}")
```
## 核心模块详解
### 1. 异常处理模块 (`exception.py`)
提供统一的异常捕获和处理机制,确保并发任务中的异常被正确记录和处理。
#### handle_exception
```python
"""统一的异常处理函数,提供完整的异常捕获、记录和处理机制
参数:
exc: 异常对象
re_raise: 是否重新抛出异常,默认False
handler: 异常处理函数,默认None
default_return: 默认返回值
log_traceback: 是否记录完整堆栈信息,默认True
custom_message: 自定义错误提示信息,默认None
返回:
如果re_raise=True,重新抛出异常;否则返回default_return
"""
```
#### safe_call
```python
"""捕获函数执行过程中的异常并记录日志
参数:
func: 要执行的目标函数
re_raise: 是否重新抛出异常,默认False
handler: 异常处理函数,默认None
default_return: 默认返回值
返回:
包装后的函数
"""
```
### 2. 线程基础模块 (`thread.py`)
提供增强型线程基类和线程管理功能。
#### ThreadBase
```python
"""增强型线程基类,提供结果获取、安全停止和资源清理功能
特性:
支持结果获取、超时控制、安全停止和资源自动清理
可作为上下文管理器使用
"""
```
#### SafeThread
```python
"""继承自 ThreadBase,提供额外的异常处理机制
特性:
内置异常捕获和重试机制
确保线程即使在出错情况下也能正确结束
"""
```
#### ThreadManager
```python
"""线程管理器,用于集中管理多个线程的创建、启动、停止和结果获取
类方法:
create_thread: 创建并返回线程实例
start_all: 启动所有创建的线程
wait_all_completed: 等待所有线程完成并返回结果列表
stop_all: 安全停止所有线程
"""
```
### 3. 线程池模块 (`futures.py`)
提供多种线程池实现,满足不同的并发需求。
#### BaseThreadRunner
```python
"""极简线程池实现,使用信号量控制并发线程数量
参数:
max_workers: 最大工作线程数
name_prefix: 线程名称前缀
方法:
submit: 提交任务到线程池
wait_all_completed: 等待所有任务完成并返回结果列表
"""
```
#### EnhancedThreadPool
```python
"""增强型线程池,扩展标准ThreadPoolExecutor,提供结果收集和异常处理
特性:
自动收集任务结果
支持超时控制
完整的异常捕获和处理
支持上下文管理器语法
"""
```
### 4. 进程管理模块 (`process.py`)
提供增强的进程管理功能,支持跨进程并行计算。
#### ProcessBase
```python
"""增强型进程基类,提供结果获取、安全停止和资源清理功能
特性:
支持结果获取、超时控制、安全停止和资源自动清理
可作为上下文管理器使用
"""
```
#### CustomProcess
```python
"""自定义进程类,提供任务分片和结果收集功能
参数:
target: 目标函数
chunk_size: 任务分片大小
max_workers: 最大工作进程数
方法:
add_task: 添加单个任务
add_tasks: 添加多个任务
start: 启动进程
wait_completed: 等待所有任务完成
"""
```
### 5. 生产者-消费者模式模块 (`production.py`)
提供同步和异步版本的生产者-消费者模式实现。
#### Production
```python
"""同步多线程生产者-消费者模式实现
参数:
queue_size: 任务队列的最大容量
max_workers: 最大工作线程数
方法:
add_producer: 添加生产者函数
add_consumer: 添加消费者函数
add_task: 直接添加任务到队列
start: 启动所有生产者和消费者
wait_completed: 等待所有任务完成
get_results: 获取所有处理结果
"""
```
#### AsyncProduction
```python
"""异步协程生产者-消费者模式实现
参数:
queue_size: 异步任务队列的最大容量
方法:
add_producer: 添加异步生产者协程
add_consumer: 添加异步消费者协程
add_task: 直接添加任务到队列
start: 启动所有生产者和消费者
wait_completed: 等待所有任务完成
get_results: 获取所有处理结果
"""
```
### 6. PyQt 线程增强模块 (`qthread.py`)
提供基于 PyQt6 的线程增强功能,适用于 GUI 应用程序。
#### QtThreadBase
```python
"""基于QThread的增强型线程基类
信号:
finished_signal: 线程完成时发射,携带执行结果
error_signal: 线程发生错误时发射,携带异常信息
特性:
支持结果获取、超时控制、安全停止
可作为上下文管理器使用
"""
```
#### QtThreadManager
```python
"""Qt线程管理器,用于集中管理多个Qt线程
类方法:
create_thread: 创建并返回Qt线程实例
start_all: 启动所有创建的线程
wait_all_completed: 等待所有线程完成并返回结果列表
stop_all: 安全停止所有线程
"""
```
### 7. 装饰器集合 (`wraps.py`)
提供多种线程相关的装饰器,简化并发编程。
#### thread_safe
```python
"""确保函数在多线程环境下的安全性
参数:
func: 要保护的目标函数
返回:
线程安全的包装函数
"""
```
#### run_in_thread
```python
"""在单独的线程中执行函数
参数:
func: 要在新线程中执行的目标函数
daemon: 是否为守护线程,默认True
返回:
包装后的函数,调用后返回线程实例
"""
```
#### run_in_qtthread
```python
"""在QThread中执行函数
参数:
func: 要在QThread中执行的目标函数
返回:
包装后的函数,调用后返回Qt线程实例
"""
```
## 单例线程支持
xtthread 提供了多种单例模式线程实现,确保同一目标函数只有一个线程实例运行:
- `SingletonThread`: 确保同一目标函数只有一个线程实例
- `ComposedSingletonThread`: 使用组合而非继承实现的单例线程
- `SingletonQtThread`: 基于 QThread 的单例线程
- `ComposedSingletonQtThread`: 基于组合模式的 Qt 单例线程
## 使用场景
xtthread 适用于以下各种并发编程场景:
- **简单并发任务**: 使用 ThreadBase 或 SafeThread
- **批量任务处理**: 使用 BaseThreadPool 或 EnhancedThreadPool
- **动态资源管理**: 使用 DynamicThreadPool 或 ThreadPoolManager
- **跨进程并行**: 使用 CustomProcess 或 run_custom_process
- **UI 响应式应用**: 使用 QtThreadBase 或 QtSafeThread
- **复杂任务流**: 使用 Production 或 AsyncProduction
- **异步函数执行**: 使用 AsyncFunction
- **线程安全保证**: 使用 thread_safe 装饰器
- **单例线程**: 使用 SingletonThread 或 SingletonQtThread
## 开发工具
本项目使用以下工具确保代码质量:
- **Ruff**: 用于代码风格检查和格式化
- **basedpyright**: 用于静态类型检查
- **mypy**: 可选的静态类型检查器
## 许可证
本项目采用 MIT 许可证。
Raw data
{
"_id": null,
"home_page": null,
"name": "xtthread",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.13",
"maintainer_email": null,
"keywords": "thread, multithreading, multiprocessing, concurrency, parallelism, PyQt, async, futures",
"author": null,
"author_email": "sandorn <sandorn@live.cn>",
"download_url": "https://files.pythonhosted.org/packages/57/46/a665f086bf203f21350fb3495f234d83fe25a4c9c2d477cac3a2a99b807d/xtthread-0.0.7.tar.gz",
"platform": null,
"description": "<div align=\"center\">\r\n <strong>\u7248\u672c: 0.0.7</strong> | \r\n <a href=\"https://github.com/sandorn/xtthread\">GitHub</a> | \r\n <strong>Python 3.13+</strong>\r\n</div>\r\n\r\n# xtthread\r\n\r\nxtthread \u662f\u4e00\u4e2a\u5168\u9762\u7684 Python \u5e76\u53d1\u7f16\u7a0b\u589e\u5f3a\u5e93\uff0c\u4e3a\u6807\u51c6\u7ebf\u7a0b\u3001\u8fdb\u7a0b\u548c Qt \u7ebf\u7a0b\u63d0\u4f9b\u4e86\u66f4\u9ad8\u7ea7\u7684\u62bd\u8c61\u548c\u5f02\u5e38\u5904\u7406\u673a\u5236\u3002\u4f5c\u8005: sandorn sandorn@live.cn\r\n\r\n## \u529f\u80fd\u7279\u70b9\r\n\r\n- **\u589e\u5f3a\u7684\u7ebf\u7a0b\u7ba1\u7406**\uff1a\u63d0\u4f9b `ThreadManager` \u548c `QtThreadManager` \u7528\u4e8e\u96c6\u4e2d\u7ba1\u7406\u7ebf\u7a0b\u751f\u547d\u5468\u671f\r\n- **\u5f02\u5e38\u5b89\u5168\u7684\u6267\u884c**\uff1a\u901a\u8fc7 `safe_call` \u88c5\u9970\u5668\u63d0\u4f9b\u7edf\u4e00\u7684\u5f02\u5e38\u6355\u83b7\u548c\u65e5\u5fd7\u8bb0\u5f55\r\n- **\u5355\u4f8b\u7ebf\u7a0b\u652f\u6301**\uff1a\u5b9e\u73b0 `SingletonThread` \u548c `ComposedSingletonThread` \u7b49\u5355\u4f8b\u6a21\u5f0f\u7ebf\u7a0b\r\n- **Qt \u96c6\u6210**\uff1a\u63d0\u4f9b\u57fa\u4e8e PyQt6 \u7684\u7ebf\u7a0b\u589e\u5f3a\u5b9e\u73b0\r\n- **Future \u6a21\u5f0f\u652f\u6301**\uff1a\u591a\u79cd\u7ebf\u7a0b\u6c60\u5b9e\u73b0\uff0c\u7b80\u5316\u5f02\u6b65\u4efb\u52a1\u5904\u7406\r\n- **\u8fdb\u7a0b\u7ba1\u7406**\uff1a\u63d0\u4f9b\u589e\u5f3a\u7684\u8fdb\u7a0b\u5904\u7406\u80fd\u529b\r\n- **\u751f\u4ea7\u8005-\u6d88\u8d39\u8005\u6a21\u5f0f**\uff1a\u5b9e\u73b0\u540c\u6b65\u548c\u5f02\u6b65\u7248\u672c\u7684\u4efb\u52a1\u5904\u7406\u6846\u67b6\r\n- **\u4e30\u5bcc\u7684\u88c5\u9970\u5668**\uff1a\u63d0\u4f9b\u591a\u79cd\u7ebf\u7a0b\u76f8\u5173\u7684\u88c5\u9970\u5668\uff0c\u7b80\u5316\u5e76\u53d1\u7f16\u7a0b\r\n\r\n## \u5b89\u88c5\r\n\r\n### \u57fa\u672c\u5b89\u88c5\r\n\r\n```bash\r\npip install xtthread\r\n```\r\n\r\n### \u53ef\u9009\u4f9d\u8d56\r\n\r\n\u5982\u679c\u9700\u8981\u4f7f\u7528 Qt \u76f8\u5173\u529f\u80fd\uff0c\u8bf7\u5355\u72ec\u5b89\u88c5 PyQt6\uff1a\r\n\r\n```bash\r\npip install PyQt6\r\n```\r\n\r\n## \u5feb\u901f\u5f00\u59cb\r\n\r\n### 1. \u57fa\u672c\u7ebf\u7a0b\u4f7f\u7528\r\n\r\n```python\r\nfrom xtthread import ThreadBase\r\n\r\n# \u521b\u5efa\u7ebf\u7a0b\u5e76\u542f\u52a8\r\ndef my_task(name):\r\n import time\r\n time.sleep(1) # \u6a21\u62df\u8017\u65f6\u64cd\u4f5c\r\n return f\"Hello, {name}!\"\r\n\r\nthread = ThreadBase(target=my_task, args=(\"World\",))\r\nthread.start()\r\n\r\n# \u83b7\u53d6\u7ebf\u7a0b\u6267\u884c\u7ed3\u679c\r\nresult = thread.get_result(timeout=2)\r\nprint(result) # \u8f93\u51fa: Hello, World!\r\n```\r\n\r\n### 2. \u4f7f\u7528\u88c5\u9970\u5668\u7b80\u5316\u5e76\u53d1\u7f16\u7a0b\r\n\r\n```python\r\nfrom xtthread import run_in_thread, safe_call\r\nimport time\r\n\r\n# \u5728\u5355\u72ec\u7ebf\u7a0b\u4e2d\u6267\u884c\u51fd\u6570\r\n@run_in_thread\r\n@safe_call\r\ndef process_data(data):\r\n time.sleep(1) # \u6a21\u62df\u5904\u7406\u65f6\u95f4\r\n return data * 2\r\n\r\n# \u8c03\u7528\u51fd\u6570\uff08\u5f02\u6b65\u6267\u884c\uff09\r\nthread = process_data(10)\r\n\r\n# \u4e3b\u7ebf\u7a0b\u53ef\u4ee5\u505a\u5176\u4ed6\u4e8b\u60c5\r\nprint(\"\u7b49\u5f85\u5904\u7406\u7ed3\u679c...\")\r\n\r\n# \u83b7\u53d6\u7ed3\u679c\r\nresult = thread.get_result()\r\nprint(f\"\u5904\u7406\u7ed3\u679c: {result}\")\r\n```\r\n\r\n### 3. \u4f7f\u7528\u7ebf\u7a0b\u6c60\u5904\u7406\u6279\u91cf\u4efb\u52a1\r\n\r\n```python\r\nfrom xtthread import EnhancedThreadPool\r\nimport time\r\n\r\n# \u521b\u5efa\u7ebf\u7a0b\u6c60\uff08\u6700\u591a4\u4e2a\u5de5\u4f5c\u7ebf\u7a0b\uff09\r\nwith EnhancedThreadPool(max_workers=4) as pool:\r\n # \u63d0\u4ea4\u591a\u4e2a\u4efb\u52a1\r\n tasks = [pool.submit(time.sleep, i * 0.5) for i in range(1, 6)]\r\n\r\n # \u7b49\u5f85\u6240\u6709\u4efb\u52a1\u5b8c\u6210\u5e76\u83b7\u53d6\u7ed3\u679c\r\n results = pool.wait_all_completed()\r\n print(f\"\u4efb\u52a1\u5b8c\u6210\u6570\u91cf: {len(results)}\")\r\n```\r\n\r\n### 4. \u751f\u4ea7\u8005-\u6d88\u8d39\u8005\u6a21\u5f0f\r\n\r\n```python\r\nfrom xtthread import Production\r\nimport time\r\nimport random\r\n\r\n# \u521b\u5efa\u751f\u4ea7\u8005-\u6d88\u8d39\u8005\u7cfb\u7edf\r\nproduction = Production(queue_size=10)\r\n\r\n# \u5b9a\u4e49\u751f\u4ea7\u8005\u51fd\u6570\r\ndef producer():\r\n for i in range(5):\r\n task_data = random.randint(1, 100)\r\n production.add_task(task_data)\r\n print(f\"\u751f\u4ea7\u8005\u6dfb\u52a0\u4efb\u52a1: {task_data}\")\r\n time.sleep(0.5)\r\n\r\n# \u5b9a\u4e49\u6d88\u8d39\u8005\u51fd\u6570\r\ndef consumer(task_data):\r\n print(f\"\u6d88\u8d39\u8005\u5904\u7406\u4efb\u52a1: {task_data}\")\r\n time.sleep(1) # \u6a21\u62df\u5904\u7406\u65f6\u95f4\r\n return task_data * 2\r\n\r\n# \u6dfb\u52a0\u751f\u4ea7\u8005\u548c\u6d88\u8d39\u8005\r\nproduction.add_producer(producer)\r\nproduction.add_consumer(consumer, num_workers=2)\r\n\r\n# \u542f\u52a8\u7cfb\u7edf\r\nproduction.start()\r\n\r\n# \u7b49\u5f85\u6240\u6709\u4efb\u52a1\u5b8c\u6210\r\nproduction.wait_completed()\r\n\r\n# \u83b7\u53d6\u5904\u7406\u7ed3\u679c\r\nresults = production.get_results()\r\nprint(f\"\u6240\u6709\u7ed3\u679c: {results}\")\r\n```\r\n\r\n## \u6838\u5fc3\u6a21\u5757\u8be6\u89e3\r\n\r\n### 1. \u5f02\u5e38\u5904\u7406\u6a21\u5757 (`exception.py`)\r\n\r\n\u63d0\u4f9b\u7edf\u4e00\u7684\u5f02\u5e38\u6355\u83b7\u548c\u5904\u7406\u673a\u5236\uff0c\u786e\u4fdd\u5e76\u53d1\u4efb\u52a1\u4e2d\u7684\u5f02\u5e38\u88ab\u6b63\u786e\u8bb0\u5f55\u548c\u5904\u7406\u3002\r\n\r\n#### handle_exception\r\n\r\n```python\r\n\"\"\"\u7edf\u4e00\u7684\u5f02\u5e38\u5904\u7406\u51fd\u6570\uff0c\u63d0\u4f9b\u5b8c\u6574\u7684\u5f02\u5e38\u6355\u83b7\u3001\u8bb0\u5f55\u548c\u5904\u7406\u673a\u5236\r\n\r\n\u53c2\u6570:\r\n exc: \u5f02\u5e38\u5bf9\u8c61\r\n re_raise: \u662f\u5426\u91cd\u65b0\u629b\u51fa\u5f02\u5e38\uff0c\u9ed8\u8ba4False\r\n handler: \u5f02\u5e38\u5904\u7406\u51fd\u6570\uff0c\u9ed8\u8ba4None\r\n default_return: \u9ed8\u8ba4\u8fd4\u56de\u503c\r\n log_traceback: \u662f\u5426\u8bb0\u5f55\u5b8c\u6574\u5806\u6808\u4fe1\u606f\uff0c\u9ed8\u8ba4True\r\n custom_message: \u81ea\u5b9a\u4e49\u9519\u8bef\u63d0\u793a\u4fe1\u606f\uff0c\u9ed8\u8ba4None\r\n\r\n\u8fd4\u56de:\r\n \u5982\u679cre_raise=True\uff0c\u91cd\u65b0\u629b\u51fa\u5f02\u5e38\uff1b\u5426\u5219\u8fd4\u56dedefault_return\r\n\"\"\"\r\n```\r\n\r\n#### safe_call\r\n\r\n```python\r\n\"\"\"\u6355\u83b7\u51fd\u6570\u6267\u884c\u8fc7\u7a0b\u4e2d\u7684\u5f02\u5e38\u5e76\u8bb0\u5f55\u65e5\u5fd7\r\n\r\n\u53c2\u6570:\r\n func: \u8981\u6267\u884c\u7684\u76ee\u6807\u51fd\u6570\r\n re_raise: \u662f\u5426\u91cd\u65b0\u629b\u51fa\u5f02\u5e38\uff0c\u9ed8\u8ba4False\r\n handler: \u5f02\u5e38\u5904\u7406\u51fd\u6570\uff0c\u9ed8\u8ba4None\r\n default_return: \u9ed8\u8ba4\u8fd4\u56de\u503c\r\n\r\n\u8fd4\u56de:\r\n \u5305\u88c5\u540e\u7684\u51fd\u6570\r\n\"\"\"\r\n```\r\n\r\n### 2. \u7ebf\u7a0b\u57fa\u7840\u6a21\u5757 (`thread.py`)\r\n\r\n\u63d0\u4f9b\u589e\u5f3a\u578b\u7ebf\u7a0b\u57fa\u7c7b\u548c\u7ebf\u7a0b\u7ba1\u7406\u529f\u80fd\u3002\r\n\r\n#### ThreadBase\r\n\r\n```python\r\n\"\"\"\u589e\u5f3a\u578b\u7ebf\u7a0b\u57fa\u7c7b\uff0c\u63d0\u4f9b\u7ed3\u679c\u83b7\u53d6\u3001\u5b89\u5168\u505c\u6b62\u548c\u8d44\u6e90\u6e05\u7406\u529f\u80fd\r\n\r\n\u7279\u6027:\r\n \u652f\u6301\u7ed3\u679c\u83b7\u53d6\u3001\u8d85\u65f6\u63a7\u5236\u3001\u5b89\u5168\u505c\u6b62\u548c\u8d44\u6e90\u81ea\u52a8\u6e05\u7406\r\n \u53ef\u4f5c\u4e3a\u4e0a\u4e0b\u6587\u7ba1\u7406\u5668\u4f7f\u7528\r\n\"\"\"\r\n```\r\n\r\n#### SafeThread\r\n\r\n```python\r\n\"\"\"\u7ee7\u627f\u81ea ThreadBase\uff0c\u63d0\u4f9b\u989d\u5916\u7684\u5f02\u5e38\u5904\u7406\u673a\u5236\r\n\r\n\u7279\u6027:\r\n \u5185\u7f6e\u5f02\u5e38\u6355\u83b7\u548c\u91cd\u8bd5\u673a\u5236\r\n \u786e\u4fdd\u7ebf\u7a0b\u5373\u4f7f\u5728\u51fa\u9519\u60c5\u51b5\u4e0b\u4e5f\u80fd\u6b63\u786e\u7ed3\u675f\r\n\"\"\"\r\n```\r\n\r\n#### ThreadManager\r\n\r\n```python\r\n\"\"\"\u7ebf\u7a0b\u7ba1\u7406\u5668\uff0c\u7528\u4e8e\u96c6\u4e2d\u7ba1\u7406\u591a\u4e2a\u7ebf\u7a0b\u7684\u521b\u5efa\u3001\u542f\u52a8\u3001\u505c\u6b62\u548c\u7ed3\u679c\u83b7\u53d6\r\n\r\n\u7c7b\u65b9\u6cd5:\r\n create_thread: \u521b\u5efa\u5e76\u8fd4\u56de\u7ebf\u7a0b\u5b9e\u4f8b\r\n start_all: \u542f\u52a8\u6240\u6709\u521b\u5efa\u7684\u7ebf\u7a0b\r\n wait_all_completed: \u7b49\u5f85\u6240\u6709\u7ebf\u7a0b\u5b8c\u6210\u5e76\u8fd4\u56de\u7ed3\u679c\u5217\u8868\r\n stop_all: \u5b89\u5168\u505c\u6b62\u6240\u6709\u7ebf\u7a0b\r\n\"\"\"\r\n```\r\n\r\n### 3. \u7ebf\u7a0b\u6c60\u6a21\u5757 (`futures.py`)\r\n\r\n\u63d0\u4f9b\u591a\u79cd\u7ebf\u7a0b\u6c60\u5b9e\u73b0\uff0c\u6ee1\u8db3\u4e0d\u540c\u7684\u5e76\u53d1\u9700\u6c42\u3002\r\n\r\n#### BaseThreadRunner\r\n\r\n```python\r\n\"\"\"\u6781\u7b80\u7ebf\u7a0b\u6c60\u5b9e\u73b0\uff0c\u4f7f\u7528\u4fe1\u53f7\u91cf\u63a7\u5236\u5e76\u53d1\u7ebf\u7a0b\u6570\u91cf\r\n\r\n\u53c2\u6570:\r\n max_workers: \u6700\u5927\u5de5\u4f5c\u7ebf\u7a0b\u6570\r\n name_prefix: \u7ebf\u7a0b\u540d\u79f0\u524d\u7f00\r\n\r\n\u65b9\u6cd5:\r\n submit: \u63d0\u4ea4\u4efb\u52a1\u5230\u7ebf\u7a0b\u6c60\r\n wait_all_completed: \u7b49\u5f85\u6240\u6709\u4efb\u52a1\u5b8c\u6210\u5e76\u8fd4\u56de\u7ed3\u679c\u5217\u8868\r\n\"\"\"\r\n```\r\n\r\n#### EnhancedThreadPool\r\n\r\n```python\r\n\"\"\"\u589e\u5f3a\u578b\u7ebf\u7a0b\u6c60\uff0c\u6269\u5c55\u6807\u51c6ThreadPoolExecutor\uff0c\u63d0\u4f9b\u7ed3\u679c\u6536\u96c6\u548c\u5f02\u5e38\u5904\u7406\r\n\r\n\u7279\u6027:\r\n \u81ea\u52a8\u6536\u96c6\u4efb\u52a1\u7ed3\u679c\r\n \u652f\u6301\u8d85\u65f6\u63a7\u5236\r\n \u5b8c\u6574\u7684\u5f02\u5e38\u6355\u83b7\u548c\u5904\u7406\r\n \u652f\u6301\u4e0a\u4e0b\u6587\u7ba1\u7406\u5668\u8bed\u6cd5\r\n\"\"\"\r\n```\r\n\r\n### 4. \u8fdb\u7a0b\u7ba1\u7406\u6a21\u5757 (`process.py`)\r\n\r\n\u63d0\u4f9b\u589e\u5f3a\u7684\u8fdb\u7a0b\u7ba1\u7406\u529f\u80fd\uff0c\u652f\u6301\u8de8\u8fdb\u7a0b\u5e76\u884c\u8ba1\u7b97\u3002\r\n\r\n#### ProcessBase\r\n\r\n```python\r\n\"\"\"\u589e\u5f3a\u578b\u8fdb\u7a0b\u57fa\u7c7b\uff0c\u63d0\u4f9b\u7ed3\u679c\u83b7\u53d6\u3001\u5b89\u5168\u505c\u6b62\u548c\u8d44\u6e90\u6e05\u7406\u529f\u80fd\r\n\r\n\u7279\u6027:\r\n \u652f\u6301\u7ed3\u679c\u83b7\u53d6\u3001\u8d85\u65f6\u63a7\u5236\u3001\u5b89\u5168\u505c\u6b62\u548c\u8d44\u6e90\u81ea\u52a8\u6e05\u7406\r\n \u53ef\u4f5c\u4e3a\u4e0a\u4e0b\u6587\u7ba1\u7406\u5668\u4f7f\u7528\r\n\"\"\"\r\n```\r\n\r\n#### CustomProcess\r\n\r\n```python\r\n\"\"\"\u81ea\u5b9a\u4e49\u8fdb\u7a0b\u7c7b\uff0c\u63d0\u4f9b\u4efb\u52a1\u5206\u7247\u548c\u7ed3\u679c\u6536\u96c6\u529f\u80fd\r\n\r\n\u53c2\u6570:\r\n target: \u76ee\u6807\u51fd\u6570\r\n chunk_size: \u4efb\u52a1\u5206\u7247\u5927\u5c0f\r\n max_workers: \u6700\u5927\u5de5\u4f5c\u8fdb\u7a0b\u6570\r\n\r\n\u65b9\u6cd5:\r\n add_task: \u6dfb\u52a0\u5355\u4e2a\u4efb\u52a1\r\n add_tasks: \u6dfb\u52a0\u591a\u4e2a\u4efb\u52a1\r\n start: \u542f\u52a8\u8fdb\u7a0b\r\n wait_completed: \u7b49\u5f85\u6240\u6709\u4efb\u52a1\u5b8c\u6210\r\n\"\"\"\r\n```\r\n\r\n### 5. \u751f\u4ea7\u8005-\u6d88\u8d39\u8005\u6a21\u5f0f\u6a21\u5757 (`production.py`)\r\n\r\n\u63d0\u4f9b\u540c\u6b65\u548c\u5f02\u6b65\u7248\u672c\u7684\u751f\u4ea7\u8005-\u6d88\u8d39\u8005\u6a21\u5f0f\u5b9e\u73b0\u3002\r\n\r\n#### Production\r\n\r\n```python\r\n\"\"\"\u540c\u6b65\u591a\u7ebf\u7a0b\u751f\u4ea7\u8005-\u6d88\u8d39\u8005\u6a21\u5f0f\u5b9e\u73b0\r\n\r\n\u53c2\u6570:\r\n queue_size: \u4efb\u52a1\u961f\u5217\u7684\u6700\u5927\u5bb9\u91cf\r\n max_workers: \u6700\u5927\u5de5\u4f5c\u7ebf\u7a0b\u6570\r\n\r\n\u65b9\u6cd5:\r\n add_producer: \u6dfb\u52a0\u751f\u4ea7\u8005\u51fd\u6570\r\n add_consumer: \u6dfb\u52a0\u6d88\u8d39\u8005\u51fd\u6570\r\n add_task: \u76f4\u63a5\u6dfb\u52a0\u4efb\u52a1\u5230\u961f\u5217\r\n start: \u542f\u52a8\u6240\u6709\u751f\u4ea7\u8005\u548c\u6d88\u8d39\u8005\r\n wait_completed: \u7b49\u5f85\u6240\u6709\u4efb\u52a1\u5b8c\u6210\r\n get_results: \u83b7\u53d6\u6240\u6709\u5904\u7406\u7ed3\u679c\r\n\"\"\"\r\n```\r\n\r\n#### AsyncProduction\r\n\r\n```python\r\n\"\"\"\u5f02\u6b65\u534f\u7a0b\u751f\u4ea7\u8005-\u6d88\u8d39\u8005\u6a21\u5f0f\u5b9e\u73b0\r\n\r\n\u53c2\u6570:\r\n queue_size: \u5f02\u6b65\u4efb\u52a1\u961f\u5217\u7684\u6700\u5927\u5bb9\u91cf\r\n\r\n\u65b9\u6cd5:\r\n add_producer: \u6dfb\u52a0\u5f02\u6b65\u751f\u4ea7\u8005\u534f\u7a0b\r\n add_consumer: \u6dfb\u52a0\u5f02\u6b65\u6d88\u8d39\u8005\u534f\u7a0b\r\n add_task: \u76f4\u63a5\u6dfb\u52a0\u4efb\u52a1\u5230\u961f\u5217\r\n start: \u542f\u52a8\u6240\u6709\u751f\u4ea7\u8005\u548c\u6d88\u8d39\u8005\r\n wait_completed: \u7b49\u5f85\u6240\u6709\u4efb\u52a1\u5b8c\u6210\r\n get_results: \u83b7\u53d6\u6240\u6709\u5904\u7406\u7ed3\u679c\r\n\"\"\"\r\n```\r\n\r\n### 6. PyQt \u7ebf\u7a0b\u589e\u5f3a\u6a21\u5757 (`qthread.py`)\r\n\r\n\u63d0\u4f9b\u57fa\u4e8e PyQt6 \u7684\u7ebf\u7a0b\u589e\u5f3a\u529f\u80fd\uff0c\u9002\u7528\u4e8e GUI \u5e94\u7528\u7a0b\u5e8f\u3002\r\n\r\n#### QtThreadBase\r\n\r\n```python\r\n\"\"\"\u57fa\u4e8eQThread\u7684\u589e\u5f3a\u578b\u7ebf\u7a0b\u57fa\u7c7b\r\n\r\n\u4fe1\u53f7:\r\n finished_signal: \u7ebf\u7a0b\u5b8c\u6210\u65f6\u53d1\u5c04\uff0c\u643a\u5e26\u6267\u884c\u7ed3\u679c\r\n error_signal: \u7ebf\u7a0b\u53d1\u751f\u9519\u8bef\u65f6\u53d1\u5c04\uff0c\u643a\u5e26\u5f02\u5e38\u4fe1\u606f\r\n\r\n\u7279\u6027:\r\n \u652f\u6301\u7ed3\u679c\u83b7\u53d6\u3001\u8d85\u65f6\u63a7\u5236\u3001\u5b89\u5168\u505c\u6b62\r\n \u53ef\u4f5c\u4e3a\u4e0a\u4e0b\u6587\u7ba1\u7406\u5668\u4f7f\u7528\r\n\"\"\"\r\n```\r\n\r\n#### QtThreadManager\r\n\r\n```python\r\n\"\"\"Qt\u7ebf\u7a0b\u7ba1\u7406\u5668\uff0c\u7528\u4e8e\u96c6\u4e2d\u7ba1\u7406\u591a\u4e2aQt\u7ebf\u7a0b\r\n\r\n\u7c7b\u65b9\u6cd5:\r\n create_thread: \u521b\u5efa\u5e76\u8fd4\u56deQt\u7ebf\u7a0b\u5b9e\u4f8b\r\n start_all: \u542f\u52a8\u6240\u6709\u521b\u5efa\u7684\u7ebf\u7a0b\r\n wait_all_completed: \u7b49\u5f85\u6240\u6709\u7ebf\u7a0b\u5b8c\u6210\u5e76\u8fd4\u56de\u7ed3\u679c\u5217\u8868\r\n stop_all: \u5b89\u5168\u505c\u6b62\u6240\u6709\u7ebf\u7a0b\r\n\"\"\"\r\n```\r\n\r\n### 7. \u88c5\u9970\u5668\u96c6\u5408 (`wraps.py`)\r\n\r\n\u63d0\u4f9b\u591a\u79cd\u7ebf\u7a0b\u76f8\u5173\u7684\u88c5\u9970\u5668\uff0c\u7b80\u5316\u5e76\u53d1\u7f16\u7a0b\u3002\r\n\r\n#### thread_safe\r\n\r\n```python\r\n\"\"\"\u786e\u4fdd\u51fd\u6570\u5728\u591a\u7ebf\u7a0b\u73af\u5883\u4e0b\u7684\u5b89\u5168\u6027\r\n\r\n\u53c2\u6570:\r\n func: \u8981\u4fdd\u62a4\u7684\u76ee\u6807\u51fd\u6570\r\n\r\n\u8fd4\u56de:\r\n \u7ebf\u7a0b\u5b89\u5168\u7684\u5305\u88c5\u51fd\u6570\r\n\"\"\"\r\n```\r\n\r\n#### run_in_thread\r\n\r\n```python\r\n\"\"\"\u5728\u5355\u72ec\u7684\u7ebf\u7a0b\u4e2d\u6267\u884c\u51fd\u6570\r\n\r\n\u53c2\u6570:\r\n func: \u8981\u5728\u65b0\u7ebf\u7a0b\u4e2d\u6267\u884c\u7684\u76ee\u6807\u51fd\u6570\r\n daemon: \u662f\u5426\u4e3a\u5b88\u62a4\u7ebf\u7a0b\uff0c\u9ed8\u8ba4True\r\n\r\n\u8fd4\u56de:\r\n \u5305\u88c5\u540e\u7684\u51fd\u6570\uff0c\u8c03\u7528\u540e\u8fd4\u56de\u7ebf\u7a0b\u5b9e\u4f8b\r\n\"\"\"\r\n```\r\n\r\n#### run_in_qtthread\r\n\r\n```python\r\n\"\"\"\u5728QThread\u4e2d\u6267\u884c\u51fd\u6570\r\n\r\n\u53c2\u6570:\r\n func: \u8981\u5728QThread\u4e2d\u6267\u884c\u7684\u76ee\u6807\u51fd\u6570\r\n\r\n\u8fd4\u56de:\r\n \u5305\u88c5\u540e\u7684\u51fd\u6570\uff0c\u8c03\u7528\u540e\u8fd4\u56deQt\u7ebf\u7a0b\u5b9e\u4f8b\r\n\"\"\"\r\n```\r\n\r\n## \u5355\u4f8b\u7ebf\u7a0b\u652f\u6301\r\n\r\nxtthread \u63d0\u4f9b\u4e86\u591a\u79cd\u5355\u4f8b\u6a21\u5f0f\u7ebf\u7a0b\u5b9e\u73b0\uff0c\u786e\u4fdd\u540c\u4e00\u76ee\u6807\u51fd\u6570\u53ea\u6709\u4e00\u4e2a\u7ebf\u7a0b\u5b9e\u4f8b\u8fd0\u884c\uff1a\r\n\r\n- `SingletonThread`: \u786e\u4fdd\u540c\u4e00\u76ee\u6807\u51fd\u6570\u53ea\u6709\u4e00\u4e2a\u7ebf\u7a0b\u5b9e\u4f8b\r\n- `ComposedSingletonThread`: \u4f7f\u7528\u7ec4\u5408\u800c\u975e\u7ee7\u627f\u5b9e\u73b0\u7684\u5355\u4f8b\u7ebf\u7a0b\r\n- `SingletonQtThread`: \u57fa\u4e8e QThread \u7684\u5355\u4f8b\u7ebf\u7a0b\r\n- `ComposedSingletonQtThread`: \u57fa\u4e8e\u7ec4\u5408\u6a21\u5f0f\u7684 Qt \u5355\u4f8b\u7ebf\u7a0b\r\n\r\n## \u4f7f\u7528\u573a\u666f\r\n\r\nxtthread \u9002\u7528\u4e8e\u4ee5\u4e0b\u5404\u79cd\u5e76\u53d1\u7f16\u7a0b\u573a\u666f\uff1a\r\n\r\n- **\u7b80\u5355\u5e76\u53d1\u4efb\u52a1**: \u4f7f\u7528 ThreadBase \u6216 SafeThread\r\n- **\u6279\u91cf\u4efb\u52a1\u5904\u7406**: \u4f7f\u7528 BaseThreadPool \u6216 EnhancedThreadPool\r\n- **\u52a8\u6001\u8d44\u6e90\u7ba1\u7406**: \u4f7f\u7528 DynamicThreadPool \u6216 ThreadPoolManager\r\n- **\u8de8\u8fdb\u7a0b\u5e76\u884c**: \u4f7f\u7528 CustomProcess \u6216 run_custom_process\r\n- **UI \u54cd\u5e94\u5f0f\u5e94\u7528**: \u4f7f\u7528 QtThreadBase \u6216 QtSafeThread\r\n- **\u590d\u6742\u4efb\u52a1\u6d41**: \u4f7f\u7528 Production \u6216 AsyncProduction\r\n- **\u5f02\u6b65\u51fd\u6570\u6267\u884c**: \u4f7f\u7528 AsyncFunction\r\n- **\u7ebf\u7a0b\u5b89\u5168\u4fdd\u8bc1**: \u4f7f\u7528 thread_safe \u88c5\u9970\u5668\r\n- **\u5355\u4f8b\u7ebf\u7a0b**: \u4f7f\u7528 SingletonThread \u6216 SingletonQtThread\r\n\r\n## \u5f00\u53d1\u5de5\u5177\r\n\r\n\u672c\u9879\u76ee\u4f7f\u7528\u4ee5\u4e0b\u5de5\u5177\u786e\u4fdd\u4ee3\u7801\u8d28\u91cf\uff1a\r\n\r\n- **Ruff**: \u7528\u4e8e\u4ee3\u7801\u98ce\u683c\u68c0\u67e5\u548c\u683c\u5f0f\u5316\r\n- **basedpyright**: \u7528\u4e8e\u9759\u6001\u7c7b\u578b\u68c0\u67e5\r\n- **mypy**: \u53ef\u9009\u7684\u9759\u6001\u7c7b\u578b\u68c0\u67e5\u5668\r\n\r\n## \u8bb8\u53ef\u8bc1\r\n\r\n\u672c\u9879\u76ee\u91c7\u7528 MIT \u8bb8\u53ef\u8bc1\u3002\r\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "\u4e00\u4e2a\u5168\u9762\u7684Python\u5e76\u53d1\u7f16\u7a0b\u589e\u5f3a\u5e93\uff0c\u4e3a\u6807\u51c6\u7ebf\u7a0b\u3001\u8fdb\u7a0b\u548cQt\u7ebf\u7a0b\u63d0\u4f9b\u4e86\u66f4\u9ad8\u7ea7\u7684\u62bd\u8c61\u548c\u5f02\u5e38\u5904\u7406\u673a\u5236",
"version": "0.0.7",
"project_urls": {
"Homepage": "https://github.com/sandorn/xtthread",
"Issues": "https://github.com/sandorn/xtthread/issues",
"Repository": "https://github.com/sandorn/xtthread"
},
"split_keywords": [
"thread",
" multithreading",
" multiprocessing",
" concurrency",
" parallelism",
" pyqt",
" async",
" futures"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "4177969637095a466ddd1fab4758add22c01a1fb01b89bd86ed9db922bb1a823",
"md5": "901a618157a78ff7bb132b88a3e04848",
"sha256": "4945f7150f0e388f1ac47a230a82cdb240b4ebf44885219c73d7f7870929e1c7"
},
"downloads": -1,
"filename": "xtthread-0.0.7-py3-none-any.whl",
"has_sig": false,
"md5_digest": "901a618157a78ff7bb132b88a3e04848",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.13",
"size": 42549,
"upload_time": "2025-10-19T07:30:41",
"upload_time_iso_8601": "2025-10-19T07:30:41.305050Z",
"url": "https://files.pythonhosted.org/packages/41/77/969637095a466ddd1fab4758add22c01a1fb01b89bd86ed9db922bb1a823/xtthread-0.0.7-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "5746a665f086bf203f21350fb3495f234d83fe25a4c9c2d477cac3a2a99b807d",
"md5": "7e2510dd7b7b192e1dff8da82d86a98f",
"sha256": "2170f41be8d6c4d9629c41593f57eb5b985a3b25f90b12f671a3908713ffbba6"
},
"downloads": -1,
"filename": "xtthread-0.0.7.tar.gz",
"has_sig": false,
"md5_digest": "7e2510dd7b7b192e1dff8da82d86a98f",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.13",
"size": 58997,
"upload_time": "2025-10-19T07:30:52",
"upload_time_iso_8601": "2025-10-19T07:30:52.724237Z",
"url": "https://files.pythonhosted.org/packages/57/46/a665f086bf203f21350fb3495f234d83fe25a4c9c2d477cac3a2a99b807d/xtthread-0.0.7.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-10-19 07:30:52",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "sandorn",
"github_project": "xtthread",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"lcname": "xtthread"
}