我想在运行0.5秒后让一段特定的python代码超时。因此,我打算在0.5秒后引发一个异常/信号,并优雅地处理它,然后继续其余的代码。
在python中,我知道signal.alarm()
可以设置整秒的闹钟。有没有其他方法可以在0.5秒后发出警报。在其他帖子中建议的signal.setitimer()
在python2.4中不可用,为此我需要使用python2.4?
发布于 2011-11-23 20:39:05
从耐心等待的“守护进程”线程发出警报。在下面的代码中,snoozealarm
通过SnoozeAlarm
线程执行您想要的操作:
#! /usr/bin/env python
import os
import signal
import threading
import time
class SnoozeAlarm(threading.Thread):
def __init__(self, zzz):
threading.Thread.__init__(self)
self.setDaemon(True)
self.zzz = zzz
def run(self):
time.sleep(self.zzz)
os.kill(os.getpid(), signal.SIGALRM)
def snoozealarm(i):
SnoozeAlarm(i).start()
def main():
snoozealarm(0.5)
while True:
time.sleep(0.05)
print time.time()
if __name__ == '__main__':
main()
发布于 2011-11-23 13:18:12
您有两个选择:
当有问题的代码运行时,
time.time()
或类似程序。setitimer()
。这并不太难,因为您可以简单地从更高版本的signal.getitimer()
的源代码中复制Python和signal.setitimer()
的代码。它们只是对相同名称的系统调用的简单包装。只有当您使用CPython并且您所处的环境允许您使用自定义C扩展时,此选项才是可行的。
Python:这是从signalmodule.c
in Python 2.7复制的代码(适用许可):
#include "Python.h“#include静态计时器*ItimerError;/*辅助函数setitimer/getitimer */ static void timeval_from_double(double d,struct timeval *tv) { tv->tv_sec = floor(d);tv->tv_sec = fmod(d,1.0) * 1000000.0;}Py_LOCAL_INLINE(Double_from_timeval) double_from_timeval(struct timeval *tv) { return tv->tv_sec+ (double)(tv->tv_usec / 1000000.0);} PyObject * itimer_retval(struct itimerval *iv) { PyObject *r,*v;r= PyTuple_New(2);if (r == NULL)返回NULL;if(!(v = PyFloat_FromDouble(double_from_timeval(&iv->it_value)))) { Py_DECREF(r);return NULL;} PyTuple_SET_ITEM(r,0,v);如果(!(v= PyFloat_FromDouble(double_from_timeval(&iv->it_interval)))) { Py_DECREF(r);return NULL;} PyTuple_SET_ITEM(r,1,v);return r;} static PyObject * itimer_setitimer(PyObject *self,PyObject *args) { double first;double interval = 0;int which;struct itimerval new,old;if(!PyArg_ParseTuple(args,"id|d:setitimer",&which,&first,&interval)) return NULL;timeval_from_double(first,&new.it_value);timeval_from_double(interval,&new.it_interval);/*让操作系统检查"which“值*/ if (setitimer(which,&new,&old) != 0) { PyErr_SetFromErrno(ItimerError);return NULL;} return itimer_retval(& old );} PyDoc_STRVAR(setitimer_doc,“setitimer( that,seconds,interval)\n\ \n\设置给定的计时器(ITIMER_REAL、ITIMER_VIRTUAL\n\或ITIMER_PROF之一)在值为秒后触发,\n\每隔几秒后触发。\n\可以通过将秒设置为零来清除计时器。\n\\n\以元组形式返回旧值:( ITIMER_REAL,interval )。”);static PyObject * itimer_getitimer(PyObject *self,PyObject *args) { int;struct itimerval old;if (!PyArg_ParseTuple(args,"i:getitimer",&which)) return NULL;if (getitimer(which,&old) != 0) { PyErr_SetFromErrno(ItimerError);return NULL;} return itimer_retval(&old);} PyDoc_STRVAR(getitimer_doc,"getitimer(which)\n\ \n\返回给定定时器的当前值。“);static PyMethodDef itimer_methods[] ={ {"setitimer",itimer_setitimer,METH_VARARGS,setitimer_doc},{"getitimer",itimer_getitimer,METH_VARARGS,getitimer_doc},{NULL,NULL} /*标记*/ };PyMODINIT_FUNC初始化(空){ PyObject *m,*d,*x;int i;m= Py_InitModule3("itimer",itimer_methods,0);if (m == NULL) return;d= PyModule_GetDict(m);#ifdef ITIMER_REAL x= PyLong_FromLong(ITIMER_REAL);PyDict_SetItemString(d,"ITIMER_REAL",x);Py_DECREF(x);#endif #ifdef ITIMER_VIRTUAL x= PyLong_FromLong(ITIMER_VIRTUAL);PyDict_SetItemString(d,"ITIMER_VIRTUAL",x);Py_DECREF(x);#endif #ifdef ITIMER_PROF x= PyLong_FromLong(ITIMER_PROF);PyDict_SetItemString(d,"ITIMER_PROF",x);Py_DECREF(x);#endif ItimerError = PyErr_NewException("itimer.ItimerError",PyExc_IOError,NULL);if (ItimerError != NULL) PyDict_SetItemString(d,"ItimerError",ItimerError);}
将这段代码另存为itimermodule.c
,使用如下命令将其编译为C扩展
gcc -I /usr/include/python2.4 2.4 -fPIC -o itimermodule.o -c itimermodule.c gcc -shared -o itimer.so itimermodule.o -lpython2.4
现在,如果您足够幸运,您应该能够使用以下命令从Python导入此文件
导入itimer
并调用itimer.setitimer()
.
https://stackoverflow.com/questions/8242503
复制相似问题