Skip to content

Commit 7a948fa

Browse files
committed
docs(python-core): add asyncio/ & debugging/
1 parent 8ed230c commit 7a948fa

File tree

7 files changed

+94
-15
lines changed

7 files changed

+94
-15
lines changed

docs/python-core/asyncio/index.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# 异步编程
2+
3+
<AutoCatalog />

docs/python-core/asyncio/pool.md

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# 池化异步执行任务
2+
3+
[[TOC]]
4+
5+
## 1. 异步线程池
6+
7+
```python
8+
import asyncio
9+
import time
10+
from concurrent.futures import ThreadPoolExecutor
11+
12+
async def main():
13+
start = time.perf_counter()
14+
loop = asyncio.get_event_loop()
15+
with ThreadPoolExecutor(max_workers=4) as executor:
16+
tasks_list = [loop.run_in_executor(executor, time.sleep, 2) for _ in range(16)]
17+
await asyncio.gather(*tasks_list)
18+
end = time.perf_counter()
19+
print(f"Time elapsed: {end - start}")
20+
21+
asyncio.run(main())
22+
```
23+
24+
## 2. 异步进程池
25+
26+
```python
27+
from multiprocessing import Pool
28+
import time
29+
30+
def say_hello(name) -> str:
31+
time.sleep(1)
32+
return f"hello, {name}"
33+
34+
if __name__ == "__main__":
35+
time_start = time.perf_counter()
36+
with Pool() as pool:
37+
hi1_async = pool.apply_async(say_hello, args=("satori",))
38+
hi2_async = pool.apply_async(say_hello, args=("koishi",))
39+
print(hi1_async.get())
40+
print(hi2_async.get())
41+
time_end = time.perf_counter()
42+
print(f"Time elapsed: {time_end - time_start:.2f}s")
43+
```
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# 创建异步子进程
2+
3+
[[TOC]]
4+
5+
## 1. 发起异步进程
6+
7+
```python
8+
import asyncio
9+
10+
async def run(cmd: str | bytes):
11+
proc = await asyncio.create_subprocess_shell(
12+
cmd,
13+
stdout=asyncio.subprocess.PIPE,
14+
stderr=asyncio.subprocess.PIPE,
15+
)
16+
stdout, stderr = await proc.communicate()
17+
18+
print(f"{cmd!r} exited with {proc.returncode}")
19+
if stdout:
20+
print(f"[stdout]\n{stdout.decode()}")
21+
if stderr:
22+
print(f"[stderr]\n{stderr.decode()}")
23+
24+
asyncio.run(run("ls /"))
25+
```
26+
27+
## 2. Windows 下的限制
28+
29+
*@TODO* Windows 只有 `ProactorEventLoop` 支持异步子进程,但是许多库都不支持 `ProactorEventLoop`,所以 Windows 下的异步子进程支持不好。
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# 🐛 Python 调试技巧
2+
3+
<AutoCatalog />
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# Python 如何查找段错误(Segment Fault)
2+
3+
[[TOC]]
4+
5+
## 1. Python 调试选项
6+
7+
问题背景:在开发 PySide6 程序时出现了闪退错误,Windows 上不显示任何内容崩溃,Mac OS 上出现段错误(内容已转储)。常规调试方法无法得出错误出现的位置,因为出错的位置不是在 Python 解释器执行时出现的,而是在执行外部扩展时出现的。
8+
9+
通过下面的方法成功定位到问题:发现是 `QThread` 线程中调用了 UI 功能导致的。PySide6 要求线程想修改或读取 UI 控件的内容必须借助信号通信。
10+
11+
总结:调试方法是,在执行 Python 时加上 `-X faulthandler` 选项,可以在程序出现 Segment Fault 时打印出调用栈。
12+
13+
```bash
14+
python -X faulthandler test.py
15+
```

docs/python-core/errors/segment-fault.md

Lines changed: 0 additions & 15 deletions
This file was deleted.

docs/python-core/errors/sqlalchemy-lost-connection.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ SQLAlchemy 会报错:
8383
## 2. 解决方案
8484

8585
我们先学习一下 SQLAlchemy 的连接池参数。
86+
8687
- `pool_size`:设置连接池中,保持的连接数。初始化时并不产生连接。
8788
- `max_overflow`:当连接池里的连接数已达到 `pool_size` 时,且都被使用时。又要求从连接池里获取连接时,`max_overflow` 就是允许再新建的连接数。
8889
- `pool_timeout`:从连接池里获取连接,如果此时无空闲的连接。且连接数已经到达了 `pool_size+max_overflow`。此时获取连接的进程会等待 `pool_timeout` 秒。如果超过这个时间,还没有获得将会抛出异常,默认为 30 秒。

0 commit comments

Comments
 (0)