Posted on 2017-05-17 03:24:16 python
摘要: 阅读全文Posted on 2014-02-12 08:11:23 python
摘要:一个 greenlet 是一个很小的独立微线程。可以把它想像成一个堆栈帧,栈底是初始调用,而栈顶是当前greenlet的暂停位置。你使用greenlet创建一堆这样的堆 栈,然后在他们之间跳转执行。跳转不是绝对的:一个greenlet必须选择跳转到选择好的另一个greenlet,这会让前一个挂起,而后一个恢复。两 个greenlet之间的跳转称为 切换(switch) 。
当你创建一个greenlet,它得到一个初始化过的空堆栈;当你第一次切换到它,他会启动指定的函数,然后切换跳出greenlet。当最终栈底 函数结束时,greenlet的堆栈又编程空的了,而greenlet也就死掉了。greenlet也会因为一个未捕捉的异常死掉。
阅读全文Posted on 2014-01-28 12:47:57 python
我们都知道,python里面可以用pdb来调试代码。但是pdb往往不大好用。有时候调试代码往往在多重条件里面,直接用pdb需要下条件断点,设定复杂的条件。
一个简单的办法就是这么干。
__import__('pdb').set_trace()
但是有的时候,连这个出现的条件都不满足。例如,代码必须在一个受限环境中运行,很难拿到console,或者其他林林总总的毛病。这时候,我们还有一招秘技。
import pdb, socket
s = socket.socket()
s.connect(('127.0.0.1', 8888))
f = s.makefile()
pdb.Pdb(stdin=f, stdout=f).set_trace()
在连接到的目标端口上,提前用nc做好监听,就可以在触发断点的时候直接连接上来调试。
Posted on 2013-05-08 17:38:07 python
根据查看代码和文档,猜测可能会有以下结果:
线程B报错,没有waiter(这是从源码中看到的)。
如何解决?
这么看来,还是后面这个方法靠谱一些。 Condition类的notify()只管通知,至于有没有线程在wait(),它就不管了(最多只报错).
Posted on 2012-12-15 01:47:04 python
调用函数时,函数参数仅仅是引用传入对象的名称。
参数传递的基本语义和其他编程语言中已知的方式不完全相同。
例如“按值传递” 或 “按引用传递”。
例如,如果传递不可变的值(如tuple、string list),参数看起来实际是按值传递的。
但如果传递可变变量(如列表或字典)给函数,然后再修改次可变对象,这些改动就会反映在原始对象中。
像这样悄悄修改其输入值或者程序其他部分的函数具有副作用。一般来说,最好避免使用这种编程风格,因为随着程序的规模和复杂度不断增加,这类函数会成为各种奇怪编程错误的来源。(例如,如果函数具有副作用,只看函数调用是无法明显找到问题的。)
在设计线程和并发性的程序中,使用此类函数的效率很低,因为通常需要使用锁定来防止副作用的影响。 多线程环境中,对于每个run函数如果显示修改一个全局变量(一个字典),那么需要为每个线程加锁。 一般的办法就是直接return新变量,而不是“原地修改”
Posted on 2012-12-03 17:37:45 python
首先,在python的线程中,任何在run函数中调用的代码,都是运行在新线程中。
其他的实例方法,全部运行在主线程中。
上代码:
#!/usr/bin/python
# -- coding: utf-8 --
import threading
import signal
import time
# 注意:run函数中执行的代码都是在新线程中
# 而hander方法在主线程中,可以查看它们的thread id
def thread_sig():
# 在子线程中发送信号
signal.alarm(3)
class ihander(threading.Thread):
def __init__(self):
super(ihander, self).__init__()
print threading.currentThread(), " in __init__"
signal.signal(signal.SIGALRM, self.handler)
def run(self):
print threading.currentThread(), " in run"
time.sleep(10)
def handler(self, signum, frame):
print threading.currentThread(), " in handler"
print 'signal: ', signum
h = ihander()
h.start()
t = threading.Thread(target=thread_sig, args=())
t.start()
执行结果:
<_MainThread(MainThread, started 139779179116288)> in __init__
<ihander(Thread-1, started 139779145524992)> in run
<_MainThread(MainThread, stopped 139779179116288)> in handler
signal: 14
我们如果把signal.signal放在其他线程中,就会出错:
def thread_sig():
# 在子线程中发送信号
signal.alarm(3)
signal.signal(signal.SIGALRM, h.handler)
class ihander(threading.Thread):
def __init__(self):
super(ihander, self).__init__()
print threading.currentThread(), " in __init__"
def run(self):
print threading.currentThread(), " in run"
time.sleep(10)
def handler(self, signum, frame):
print threading.currentThread(), " in handler"
print 'signal: ', signum
执行结果是:
Exception in thread Thread-2:
Traceback (most recent call last):
File "/usr/lib/python2.7/threading.py", line 551, in __bootstrap_inner
self.run()
File "/usr/lib/python2.7/threading.py", line 504, in run
self.__target(*self.__args, **self.__kwargs)
File "/data/tornado_analyst/test_signal.py", line 14, in thread_sig
signal.signal(signal.SIGALRM, h.handler)
ValueError: signal only works in main thread
python报告说,signal只能工作在主线程中。
下面是一些关于python中信号的注意点:
/*
NOTES ON THE INTERACTION BETWEEN SIGNALS AND THREADS
When threads are supported, we want the following semantics:
- only the main thread can set a signal handler
- any thread can get a signal handler
- signals are only delivered to the main thread
I.e. we don't support "synchronous signals" like SIGFPE (catching
this doesn't make much sense in Python anyway) nor do we support
signals as a means of inter-thread communication, since not all
thread implementations support that (at least our thread library
doesn't).
We still have the problem that in some implementations signals
generated by the keyboard (e.g. SIGINT) are delivered to all
threads (e.g. SGI), while in others (e.g. Solaris) such signals are
delivered to one random thread (an intermediate possibility would
be to deliver it to the main thread -- POSIX?). For now, we have
a working implementation that works in all three cases -- the
handler ignores signals if getpid() isn't the same as in the main
thread. XXX This is a hack.
GNU pth is a user-space threading library, and as such, all threads
run within the same process. In this case, if the currently running
thread is not the main_thread, send the signal to the main_thread.
*/
Posted on 2012-11-30 18:30:54 python
摘要:h(elp),会打印当前版本Pdb可用的命令,如果要查询某个命令,可以输入 h [command],例如:“h l” — 查看list命令 l(ist),可以列出当前将要运行的代码块
阅读全文Posted on 2012-05-08 12:23:39 python
# 因为wrap函数的参数只能是一个函数
# 而wrapper的参数又只能是传递给函数的参数列表
# 如果想要再次处理被装饰函数的返回结果,只能在最外层的函数参数中指定
# 这里就是在deco函数的参数中
# 如果只用两层嵌套就无法做到
def deco(render=None):
def wrap(func):
def wrapper(*args,**kwargs):
result = func(*args,**kwargs) ###
return render(result) ###
return wrapper
return wrap
my_render = lambda x: str(x) + ' --my_render'
@deco(render=my_render)
def test():
return "this is test!"
print test()
这里正是因为想让result被再次处理,所以要在最外层函数的参数中制定调用的处理函数,就是my_render。