Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1125496
  • 博文数量: 170
  • 博客积分: 1603
  • 博客等级: 上尉
  • 技术积分: 1897
  • 用 户 组: 普通用户
  • 注册时间: 2010-07-09 15:54
文章分类

全部博文(170)

文章存档

2016年(27)

2015年(21)

2014年(27)

2013年(21)

2012年(7)

2011年(67)

我的朋友

分类: Python/Ruby

2014-12-29 14:57:02

把我的代理开服关服的程序改到类里,并用python-deamon来启动
磕磕碰碰遇到的问题记录下
过几天把全部源代码放上来


第一个问题是print调试遇到的问题
因为要把进程用python-deamon启动后,stdout被重定向到文件里了
调试的时候发现死循环主进程里print后文件里没有内容
multiprocessing启动的子进程里的print却有打印
但是打印顺序错乱
主进程里打印的内容在另外一个子进程里打印了出来
对比了下subprocess模块和python模块对stdout的处理,发现两者没什么区别都是os.dup2

想了半天终于想明白了,主进程不打印是因为stdout没有刷新!
但是子进程为什么又会打印呢?

折腾了半天最后发现其实子进程也没有直接打印,而是子进程结束后缓冲区一次性刷新了....
之前主进程里没打印的东西也因为子进程结束一起刷新了,所以造成了打印顺序错乱的错觉....(print函数本来会自动flush sys.stdout,重定向以后需要手动刷新,具体原因要到print函数里看才知道)

一开是我直接结重定向的文件的文件对象flush发现没有效果,还以为上面的想法不对....又折腾半天....
后来才发现要对sys.stdout做flush()

我花了好长时间,还是没明白为什么直接对原file对象直接flush不行
如果我要想通过文件对象而不是stdout来flush的话,必须用fdopen(stdout.flieno())来打开再flush?
这样好像也不对....之前已经在fock之前将打开的文件对象传到类里了,之前测试flush也不行哇
应该还是要对sys.stdout做flush,print的内容才能刷新并写入文件里?虽然file的fileno已经dup到sys.stdout上了,但是这两还是不一样的?

顺便说下
python-daemon里os.dup2后并没有关闭原来的fd,subprocess里os.dup2以后是关闭掉原fd的


第二格问题是控制关服stop函数失效,erl进程无法启动,连直接执行/usr/bin/erl都回报错
测试发现所有函数——start、reload、reload配置、热函数执行都没问题

看半天不知道哪有问题,对比没使用守护进程的写法没看出改了什么地方
初步怀疑是环境变量问题,尝试用写入环境变量,发现没有效果.........

开始还以为python-daemon导致了什么奇怪的bug,把函数名字和内容换了下发现原stop下的函数代码还是有问题(简直废话...)
最后终于找到元凶

start和stop函数里,我没有重定向subprocess的stdin
其他所有函数因为涉及到输入都重定向过stdin.....

start没出问题是因为完全不需要stdin。
stop的里虽然也不需要输入内容,但是里面依旧会启用一个erlang shell来做关闭操作,没有输入内容但是会打开stdin
python-daemon里重定向stdin到文件了,所以导致erlang shell无法启动....
subprocess里stdin定义成用pipe的就好了

阅读(3177) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~