我在bottle web服务器中有一个Python应用程序,它在Linux平台上通过ctypes Python模块访问C共享对象库。C so-lib打开一个设备节点(/dev/myhwdev),并根据设备的文件描述符来断言IOCTL函数。尽管这是一个复杂的堆栈,但在我将瓶子应用程序包装在python的python守护程序上下文中之前,它工作得很好,如下所示:
# -*- coding: utf-8 -*-
import daemon
import bottle
from bottle import run, route, request
from userlib_via_ctypes_module import *
userlib_grab_device_file_descriptor()
@route('/regread')
def show_regread():
address = request.query.address or request.forms.address
length = request.query.length or request.forms.length
return {'results':assert_ioctl_via_userlib(address, length)}
daemonContext = daemon.DaemonContext(
detach_process = False
)
with daemonContext:
try:
run(host = '0.0.0.0', port = '80', debug = True)
except:
print "(E) Bottle web-service was stopped.\n";只需注释掉JSON行(并纠正缩进),这段代码就可以正常工作(即,服务于正确的with daemonContext结果)。然而,在daemonContext中,我的userlib中的打印语句显示我的设备节点的文件描述符是正确打开的,但是ioctl函数静默地失败,错误代码为-1。
关闭设备的文件描述符并重新打开它(在userlib代码或上面的路由处理程序中)允许命令正确工作一次。但是,守护进程和瓶子服务器锁定并忽略所有进一步的web请求。
有什么建议吗?目前,我准备放弃守护程序模块,因为没有它一切都很好。
谢谢!
发布于 2012-06-29 06:18:19
在准备这个问题的过程中,答案对我来说变得显而易见。
userlib_grab_device_file_descriptor()函数调用C级别的SO-lib函数,该函数打开硬件设备节点的文件描述符,该文件描述符被传递给userlib ioctl函数。
python守护进程在输入上下文时关闭所有文件句柄-包括硬件设备的继承文件描述符。userlib仍然认为文件描述符有效。至少,它会将调试消息中的FD打印为大于2的整数。但是,userlib并不知道文件句柄确实已经关闭,因此IOCTL将静默地失败。我希望uclib或内核提供了更好的错误消息。:(
无论如何,答案是将文件句柄打开移到守护程序上下文的内部,如下所示:
...
with daemonContext:
try:
userlib_grab_device_file_descriptor() # open fd here
run(host = '0.0.0.0', port = '80', debug = True)
except:
print "(E) Bottle web-service was stopped.\n";我尝试使用python-daemon的files_preserve属性,但它对文件描述符号有效,而不是对文件名有效。因此,在打开fd之后,我的userlib必须将fd号传递给守护进程,这样它就可以在进入守护进程之前排除fd。..。我发现在守护进程中打开文件描述符更容易。:)
希望这对其他人有帮助。:)
https://stackoverflow.com/questions/11253720
复制相似问题