Python 环境变量的一个坑
Python 中可以使用 os.environ 操作环境变量,前几天看到了其他几个函数 os.getenv 和 os.putenv。然而 os.putenv 是一个大坑,os.putenv 之后,在后面的 os.getenv 中并不能读出来。囧
参考
- https://mail.python.org/pipermail/python-list/2013-June/650294.html
Python 中可以使用 os.environ 操作环境变量,前几天看到了其他几个函数 os.getenv 和 os.putenv。然而 os.putenv 是一个大坑,os.putenv 之后,在后面的 os.getenv 中并不能读出来。囧
如果需要记录 Core Dump 的原因,首先需要使用 faulthandler 参数启动 Python
python -X faulthandler main.py
出 core 之后,可以使用 gdb 调试
gdb python core
参考
在 Linux 中, 当子进程退出的时候, 父进程可以收到信号, 但是当父进程退出的时候, 子进程并不会受到信号. 这样就造成了在父进程崩溃的时候, 子进程并不能同时退出, 而是一直会在后台运行, 比如下面的例子:
import os
import time
def loop_print():
import time
while True:
print('child alive, %s' % time.time())
time.sleep(1)
try:
pid = os.fork()
except OSError:
pass
if pid != 0: # parent
print('parent sleep for 2')
time.sleep(2)
print …
最近要写一个库往 influxdb 中打点, 因为要被很多程序使用, 而又要创建新的进程, 为了避免引起使用方的异常, 简单深入了解了下 Python 的并发控制, 这才发现标准库真是坑. 之前没过多考虑过, 只是凭感觉在 CPU 密集的时候使用 multiprocessing, 而默认使用 threading, 其实两个还是有很多不一样的, 除了都是并发执行以外还有很大的不同. Python 中试图用 threading 和 multiprocessing 实现类似的接口来统一两方面, 结果导致更混乱了. 本文探讨几个坑.
首先不谈 Python, 我们思考一下, 在多线程环境下如果执行 fork 会怎样? 在新的进程中, 会不会所有线程都在运行? 答案是否定的, 在 fork 之后, 只有执行 fork 的线程在运行, 而其他线程都不会运行. 这是 POSIX 标准规定的:
A process …
aiohttp 是 Python 异步编程最常用的一个 web 请求库了, 依托于 asyncio, 性能非常吓人. 下面列举几个常见的用法:
import aiohttp
import asyncio
async def fetch(session, url):
async with session.get(url) as response:
return await response.text()
async def main():
urls = [
'http://python.org',
'https://google.com',
'http://yifei.me'
]
tasks = []
async with aiohttp.ClientSession …
有时候,requests 返回的 cookies 会为空,原因是链接发生了 301/302 跳转,而 cookies 是跟着第一个响应返回的,第二个响应没有返回 Set-Cookie header。所以直接读取 r.cookies 是空的,而在 session.cookies 中是有数据的。
解决方法是直接读 s.cookies。
s = requests.Session()
r = s.get('http://httpbin.org/cookies/set?foo=bar')
cookies = requests.utils.dict_from_cookiejar(s.cookies)
s.cookies.clear()
不过需要注意的是如果在多线程环境中使用 session …
CPython 中默认使用的垃圾回收算法是 Reference Counting。也就是对每个元素标记有多少个其他元素引用了它,当引用数降到零的时候就删除。
为了解决循环引用的问题,CPython 使用了 Cyclic GC,遍历所有的环,并且把每一个元素的引用减一,来检测每一个引用环是不是循环应用。
避免了循环引用的问题
实际的处理过程
Pluggable Generational Incremental
参考资料:
昨天写了一个服务,在本地运行很好,使用 Ctrl-C 结束运行之后会清理资源,然后取消注册,然而放到 Docker 中跑之后发现结束之后资源没有释放。查了查发现原来是下面是几个因素造成的:
所以在 docker stop 的时候服务并不能优雅的推出。
使用 atexit 模块是不可以的,atexit 不会处理 SIGTERM。需要使用 signal 模块来,在网上找到了一份源码 …
我们知道当子进程推出的时候,父进程会收到 SIGCHLD 信号,从而可以采取相应的操作。但是当父进程退出的时候,系统会把子进程的父进程更改为pid=0的 init 进程,而且子进程不会收到任何信号。而我们经常想在父进程退出的时候,让子进程也推出。在 Python 中可以有如下几种做法。
这里的 daemon 和系统的守护进程没有任何关系,是 quit_when_parent_dies 的意思。也就是当父进程退出的时候,会自动尝试关闭 daemon=True 的子进程。
p = multiprocessing.Process(target=foo)
p.daemon = True
p.start()
在 Linux 中,进程可以要求内核在父进程退出的时候给自己发信号。使用系统调用 prctl。
prctl(PR_SET_PDEATHSIG …
basic usage
import gzip/bz2 with gzip.open('file.gz', 'rt') as f: text = f.read()
NOTE: the default mode is binary.