V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX  ›  dbow  ›  全部回复第 21 页 / 共 25 页
回复总数  490
1 ... 13  14  15  16  17  18  19  20  21  22 ... 25  
2017-07-01 10:47:45 +08:00
回复了 yucongo 创建的主题 Python Windows 下 Python 3 出 segfault 时如何找错?
gdb --args ./app ..... 跑一遍, 出了 segment fault, 用 bt 命令, 输出 stack trace
@wwqgtxx ctypes 调用 c 函数是自动释放 GIL 的, 除非是调用 python 自己的 C API.

821 #ifdef WITH_THREAD
822 if ((flags & FUNCFLAG_PYTHONAPI) == 0)
823 Py_UNBLOCK_THREADS
824 #endif
825 if (flags & FUNCFLAG_USE_ERRNO) {
826 int temp = space[0];
827 space[0] = errno;
828 errno = temp;
829 }
830 #ifdef MS_WIN32
831 if (flags & FUNCFLAG_USE_LASTERROR) {
832 int temp = space[1];
833 space[1] = GetLastError();
834 SetLastError(temp);
835 }
2017-07-01 10:34:39 +08:00
回复了 yucongo 创建的主题 Python Windows 下 Python 3 出 segfault 时如何找错?
完整的错误信息贴出来看看。
@wwqgtxx 是的, 主动释放的, 方法就是下面的, 在底层 C 代码释放的。
Py_BEGIN_ALLOW_THREADS
rc = WaitForSingleObjectEx(hInterruptEvent, ul_millis, FALSE);
Py_END_ALLOW_THREADS
@davinci 释放不了, 需要主动写代码释放, 典型的模式是在阻塞之前释放线程锁, 阻塞操作结束后重新取得。
以 time.sleep()里的这段代码为例,
Py_BEGIN_ALLOW_THREADS
rc = WaitForSingleObjectEx(hInterruptEvent, ul_millis, FALSE);
Py_END_ALLOW_THREADS
释放不了, 需要主动写代码释放, 典型的模式是在阻塞之前释放线程锁, 阻塞操作结束后重新取得。
以 time.sleep()里的这段代码为例,
Py_BEGIN_ALLOW_THREADS
rc = WaitForSingleObjectEx(hInterruptEvent, ul_millis, FALSE);
Py_END_ALLOW_THREADS
要不试试我的库 https://github.com/maliubiao/simple_http
还能控制并发量, 超时时间
### 异步方式
```shell

In [21]: def print_it(x):
import pprint
....: pprint.pprint(x)
....:

In [22]: async_http.repeat_tasks([{"url": "http://www.baidu.com", "parser": print_it}])
{'chain': None,
'chain_idx': 0,
'con': <socket._socketobject object at 0x2812bb0>,
'fd': 5,
'header_only': False,
'parser': <function print_it at 0x283da28>,
'proxy': '',
'random': '60804c2a0b053fbd',
'recv': <cStringIO.StringO object at 0x283a3e8>,
'redirect': 0,
'res_cookie': {'BAIDUID': {'domain': '.baidu.com',
'expires': 'Thu, 31-Dec-37 23:55:55 GMT',
'max-age': '2147483647',
'path': '/',
'value': 'BCB0BBBB4312D00C88BCDC9EEAAE3726:FG=1'},
'BD_LAST_QID': {'Max-Age': '1',
'path': '/',
'value': '16069052107084303783'},
'BIDUPSID': {'domain': '.baidu.com',
'expires': 'Thu, 31-Dec-37 23:55:55 GMT',
'max-age': '2147483647',
'path': '/',
'value': 'BCB0BBBB4312D00C88BCDC9EEAAE3726'}},
'res_header': {'Connection': 'Keep-Alive',
'Content-Length': '215',
'Content-Type': 'text/html',
'Date': 'Thu, 21 May 2015 15:50:43 GMT',
'Location': 'https://www.baidu.com/',
'P3P': 'CP=" OTI DSP COR IVA OUR IND COM "',
'Server': 'BWS/1.1',
'Set-Cookie': 'BAIDUID=BCB0BBBB4312D00C88BCDC9EEAAE3726:FG=1; expires=Thu, 31-Dec-37 23:55:55 GMT; max-age=2147483647; path=/; domain=.baidu.com\r\nBIDUPSID=BCB0BBBB4312D00C88BCDC9EEAAE3726; expires=Thu, 31-Dec-37 23:55:55 GMT; max-age=2147483647; path=/; domain=.baidu.com\r\nBD_LAST_QID=16069052107084303783; path=/; Max-Age=1',
'X-UA-Compatible': 'IE=Edge,chrome=1'},
'res_status': {'message': 'Moved Temporarily',
'protocol': 'HTTP/1.1',
'status': 302},
'retry': 0,
'send': <cStringIO.StringO object at 0x25fb8f0>,
'ssl': False,
'start': 1432223278.489937,
'status': 512,
'text': '<html>\r\n<head><title>302 Found</title></head>\r\n<body bgcolor="white">\r\n<center><h1>302 Found</h1></center>\r\n<hr><center>pr-nginx_1-0-221_BRANCH Branch\nTime : Wed May 20 10:35:46 CST 2015</center>\r\n</body>\r\n</html>\r\n',
'url': 'http://www.baidu.com'}
async_http Thu May 21 23:47:58 2015: 'acnt: 1, fcnt: 0, time: 0'
```
要是刚学 python, 会 C 的话 , 建议直接文档对着源代码看, 免得瞎猜, 浪费时间。https://github.com/python/cpython/blob/master/Python/ceval.c#L1103
这样就应该写对了, 多线程抢占的程序的结果比较随机, lock 并没有线程优先取得的问题。
另外 bytecode 的执行 应该是 100 个为单位切换执行
The interpreter releases the GIL every 100 "ticks".
661 /* for manipulating the thread switch and periodic "stuff" - used to be
662 per thread, now just a pair o' globals */
663 int _Py_CheckInterval = 100;
改成这样, 应该就是顺序输出 了. 按你的写法哪个先 acuire lock 不一定。
def run_thread(n):
with lock:
code
CPython 有 GIL, 代码是单线程执行的, run_thread 一个线程执行完, 另一个线程才能执行, 跟锁没关系。
2015-12-11 10:04:17 +08:00
回复了 dbow 创建的主题 程序员 golang 经验交流, 如何避免 gc 杀手
@CRVV 我讲如果能处理
enter function
new slice
leave function
问题就小很多
在 while 里引用了别人写的这种函数就是 for {malloc}, 给 gc 集中式回收造成了很大的压力
如果能实现把 function 内显而易见的 heap 分配可以立刻回收掉, 这种问题就能解决掉, 内存占用不会升的太快, gc 造成的延迟也会减小。
这事不在内存池上, 因为有了 gc , 别人的代码会"不负责任的"这么干.
2015-12-10 12:55:59 +08:00
回复了 dbow 创建的主题 程序员 golang 经验交流, 如何避免 gc 杀手
@tiancaiamao
问题是 f 多数情况下不是自己写的, 所以要求 gc 能自己搞定这个事。
2015-12-10 12:44:39 +08:00
回复了 dbow 创建的主题 程序员 golang 经验交流, 如何避免 gc 杀手
@tiancaiamao
C 语言指针可以乱跑就没 hack 这回事, 我讲的是 go 里要实现如下模式, 需要 hack
enter function
malloc -> new
自动 free -> delete
leave function
2015-12-10 12:37:08 +08:00
回复了 dbow 创建的主题 程序员 golang 经验交流, 如何避免 gc 杀手
@cloudzhou
如果能实现下面这种模式, 问题也是可以解决的, while {malloc, free}, 这样内存耗用就相对较小, 不会 malloc 堆在一起又占内存而且一下 gc 造成巨大的延迟。
```gol
enter function
malloc -> new
自动 free -> delete
leave function
```
2015-12-10 12:07:31 +08:00
回复了 dbow 创建的主题 程序员 golang 经验交流, 如何避免 gc 杀手
@cloudzhou 除了做一些底层的 dirty hack, 针对各种 golang 的内置对象, 你有什么办法用 golang 的 api 接口实现这个吗?
```golang
enter function
malloc -> new
自动 free -> delete
leave function
```
2015-12-10 11:56:47 +08:00
回复了 dbow 创建的主题 程序员 golang 经验交流, 如何避免 gc 杀手
@cloudzhou
while { readline, 每次都分配内存而且不归我管的函数}, 我讲的是 gc 对这种情况反应不行,
也就是下面的情况做不到.
enter function
malloc -> new
自动 free -> delete
leave function
```
```go
package main

func main() {
b := make([][]byte, 3000000)
for i := 0; i < 3000000; i++ {
buffer := make([]byte, 1024)
copy(buffer, []byte("abcd"))
b[i] = buffer
}
}
```
```shell
gc1(1): 1+0+33224+1 us, 0 -> 68 MB, 21 (21-0) objects, 2 goroutines, 16/0/0 sweeps, 0(0) handoff, 0(0) steal, 0/0/0 yields
gc2(1): 0+2+29460+1 us, 68 -> 68 MB, 22 (23-1) objects, 3 goroutines, 16/0/2 sweeps, 0(0) handoff, 0(0) steal, 0/0/0 yields
gc3(1): 0+8+29552+0 us, 68 -> 137 MB, 104710 (139608-34898) objects, 3 goroutines, 8808/0/0 sweeps, 0(0) handoff, 0(0) steal, 0/0/0 yields
gc4(1): 0+881+29664+1 us, 136 -> 136 MB, 69814 (139608-69794) objects, 3 goroutines, 8808/0/8803 sweeps, 0(0) handoff, 0(0) steal, 0/0/0 yields
gc5(1): 0+10+30403+0 us, 136 -> 273 MB, 278374 (417688-139314) objects, 3 goroutines, 26255/0/0 sweeps, 0(0) handoff, 0(0) steal, 0/0/0 yields
gc6(1): 0+2650+30961+0 us, 272 -> 272 MB, 208854 (417688-208834) objects, 3 goroutines, 26255/0/26250 sweeps, 0(0) handoff, 0(0) steal, 0/0/0 yields
gc7(1): 0+15+31651+0 us, 272 -> 545 MB, 624366 (971704-347338) objects, 3 goroutines, 61016/0/0 sweeps, 0(0) handoff, 0(0) steal, 0/0/0 yields
gc8(1): 0+5795+32788+0 us, 543 -> 543 MB, 485862 (971704-485842) objects, 3 goroutines, 61016/0/61011 sweeps, 0(0) handoff, 0(0) steal, 0/0/0 yields
gc9(1): 0+23+33831+0 us, 543 -> 1086 MB, 1313658 (2075432-761774) objects, 3 goroutines, 130267/0/0 sweeps, 0(0) handoff, 0(0) steal, 0/0/0 yields
gc10(1): 0+12912+35999+0 us, 1082 -> 1082 MB, 1037726 (2075432-1037706) objects, 3 goroutines, 130267/0/130262 sweeps, 0(0) handoff, 0(0) steal, 0/0/0 yields
gc11(1): 1+39+39331+1 us, 1082 -> 2164 MB, 2686898 (4274328-1587430) objects, 3 goroutines, 268233/0/0 sweeps, 0(0) handoff, 0(0) steal, 0/0/0 yields
gc12(1): 0+28420+41711+0 us, 2155 -> 2155 MB, 2137174 (4274328-2137154) objects, 3 goroutines, 268233/0/268228 sweeps, 0(0) handoff, 0(0) steal, 0/0/0 yields
```
2015-12-09 22:17:55 +08:00
回复了 dbow 创建的主题 程序员 golang 经验交流, 如何避免 gc 杀手
停喷, 结贴。
2015-12-09 17:58:07 +08:00
回复了 dbow 创建的主题 程序员 golang 经验交流, 如何避免 gc 杀手
@dbow
while {readline} 不建内存池这种模式下, 10 亿行文本, 吃内存嗖嗖的, 慢点是没有关系的.
2015-12-09 17:50:52 +08:00
回复了 dbow 创建的主题 程序员 golang 经验交流, 如何避免 gc 杀手
@pathletboy
性能不是关键问题, 随着 objects 越来越多, 进程内存越占越多, gc 的回收效果不好才是个大麻烦。
1 ... 13  14  15  16  17  18  19  20  21  22 ... 25  
关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2602 人在线   最高记录 6679   ·     Select Language
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.8.5 · 22ms · UTC 05:35 · PVG 13:35 · LAX 22:35 · JFK 01:35
Developed with CodeLauncher
♥ Do have faith in what you're doing.