2012-12-06 161 views
0

我查看了以前提出的问题,但没有找到类似的问题。我错过了一个,请让我知道,我再次问同样的问题,我很抱歉。Python子进程.Popen挂起

我调试的问题,我有执行以下代码(蟒蛇2.6)当POPEN挂起:

#!/usr/bin/env python 
import subprocess 
cmd = 'service drbd start' 
rc = subprocess.call(cmd.split(), stdout=subprocess.PIPE, stderr=subprocess.STDOUT) 

这也发生,如果我使用了“来电”拦截方法来代替。此问题仅在此一个节点上发生。它运行Suse SLES 11 SP1。

出现故障的节点上strace的显示如下:

<snip> 
fstat(5, {st_mode=S_IFREG|0644, st_size=22808, ...}) = 0 
open("/usr/lib64/python2.6/lib-dynload/cStringIO.so", O_RDONLY) = 6 
read(6, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\0\34\0\0\0\0\0\0"..., 832) =832 
fstat(6, {st_mode=S_IFREG|0644, st_size=22808, ...}) = 0 
mmap(NULL, 2117912, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 6, 0) = 0x7f0cd5987000 
fadvise64(6, 0, 2117912, POSIX_FADV_WILLNEED) = 0 
mprotect(0x7f0cd598b000, 2093056, PROT_NONE) = 0 
mmap(0x7f0cd5b8a000, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 6, 0x3000) = 0x7f0cd5b8a000 
close(6)        = 0 
mprotect(0x7f0cd5b8a000, 4096, PROT_READ) = 0 
close(5)        = 0 
close(4)        = 0 
getrlimit(RLIMIT_NOFILE, {rlim_cur=1024, rlim_max=1024}) = 0 
close(3)        = 0 
pipe([3, 4])       = 0 
pipe([5, 6])       = 0 
fcntl(6, F_GETFD)      = 0 
fcntl(6, F_SETFD, FD_CLOEXEC)   = 0 
clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f0cd793e9d0) = 27688 
close(6)        = 0 
close(4)        = 0 
mmap(NULL, 1052672, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f0cd5886000 
read(5, "", 1048576)     = 0 
mremap(0x7f0cd5886000, 1052672, 4096, MREMAP_MAYMOVE) = 0x7f0cd5886000 
close(5)        = 0 
munmap(0x7f0cd5886000, 4096)   = 0 
fcntl(3, F_GETFL)      = 0 (flags O_RDONLY) 
fstat(3, {st_mode=S_IFIFO|0600, st_size=0, ...}) = 0 
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f0cd794a000 
lseek(3, 0, SEEK_CUR)     = -1 ESPIPE (Illegal seek) 
fstat(3, {st_mode=S_IFIFO|0600, st_size=0, ...}) = 0 
munmap(0x7f0cd794a000, 4096)   = 0 
wait4(27688, 

它挂在这里。相应的工艺是:

root  27688 27659 0 15:34 pts/2 00:00:00 /bin/sh /sbin/service drbd start 
root  27690 27688 0 15:34 pts/2 00:00:00 /bin/bash /etc/init.d/drbd start 

下面是此相同的代码工作的另一个节点上的输出:

<snip> 
fstat(5, {st_mode=S_IFREG|0644, st_size=22808, ...}) = 0 
open("/usr/lib64/python2.6/lib-dynload/cStringIO.so", O_RDONLY) = 6 
read(6, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\0\34\0\0\0\0\0\0"..., 832) = 832 
fstat(6, {st_mode=S_IFREG|0644, st_size=22808, ...}) = 0 
mmap(NULL, 2117912, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 6, 0) = 0x7f57b3833000 
fadvise64(6, 0, 2117912, POSIX_FADV_WILLNEED) = 0 
mprotect(0x7f57b3837000, 2093056, PROT_NONE) = 0 
mmap(0x7f57b3a36000, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 6, 0x3000) = 0x7f57b3a36000 
close(6)        = 0 
mprotect(0x7f57b3a36000, 4096, PROT_READ) = 0 
close(5)        = 0 
close(4)        = 0 
getrlimit(RLIMIT_NOFILE, {rlim_cur=1024, rlim_max=1024}) = 0 
close(3)        = 0 
pipe([3, 4])       = 0 
pipe([5, 6])       = 0 
fcntl(6, F_GETFD)      = 0 
fcntl(6, F_SETFD, FD_CLOEXEC)   = 0 
clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f57b57ea9d0) = 32277 
close(6)        = 0 
close(4)        = 0 
mmap(NULL, 1052672, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f57b3732000 
read(5, "", 1048576)     = 0 
mremap(0x7f57b3732000, 1052672, 4096, MREMAP_MAYMOVE) = 0x7f57b3732000 
close(5)        = 0 
munmap(0x7f57b3732000, 4096)   = 0 
fcntl(3, F_GETFL)      = 0 (flags O_RDONLY) 
fstat(3, {st_mode=S_IFIFO|0600, st_size=0, ...}) = 0 
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f57b57f6000 
lseek(3, 0, SEEK_CUR)     = -1 ESPIPE (Illegal seek) 
fstat(3, {st_mode=S_IFIFO|0600, st_size=0, ...}) = 0 
munmap(0x7f57b57f6000, 4096)   = 0 
wait4(32277, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 32277 
--- SIGCHLD (Child exited) @ 0 (0) --- 
close(3)        = 0 
rt_sigaction(SIGINT, {SIG_DFL, [], SA_RESTORER, 0x7f57b50386a0}, {0x7f57b52d88f8, [], SA_RESTORER, 0x7f57b50386a0}, 8) = 0 
exit_group(0)       = ? 

我想不出有什么不对的节点?为什么这个命令挂在第一个节点而不是第二个节点上(运行完全相同的操作系统和python版本)?

任何帮助将不胜感激。

谢谢你在前进,

D.

PS。如果有人想要从任一节点输出完整的strace,请告诉我。我可以让这台机器保持这种状态,直到星期一:-(

+0

以下是有关挂起进程上述(27688)一些额外的数据:。 根#1/proc/27688/fd total 0 dr-x ------ 2 root root 0 Dec 6 15:38 ./ dr-xr-xr-x 7 root root 0 Dec 6 15:34 ../ lrwx ------ 1 root root 64 Dec 6 16:00 0 - >/dev/pts/2 l-wx ------ 1 root root 64 Dec 6 16:00 1 - > pipe: [5852827] l-wx ------ 1 root root 64 Dec 6 15:38 2 - > pipe:[5852827] lr-x ------ 1 root root 64 Dec 6 16:00 255 - >/sbin/service * –

回答

1

使用subprocess.call(...stdout=PIPE)这是错误的,这会将stdout重定向到一个管道,但是这个管道并没有被当前进程读取,所以子进程比N字节数据输出更多(以N视操作系统而定)后,将阻止

你想要的是subprocess.check_output()

+0

对不起,我原来的代码(在我尝试使用另一个调用之前)如下:\\ –

+0

感谢您的回复。我对此感到抱歉。我的原始代码如下(使用相同的命令cmd,即“service drbd start”):'p = subprocess.Popen(cmd.split(),stdout = subprocess。 PIPE,stderr = subprocess.STDOUT) res = p.communicate()' 这个命令挂起(我也尝试使用subprocess.PIPE stderr具有相同的结果)。当直接在shell中运行时,它会返回以下内容:'启动DRBD资源:[] .' –

+0

请注意,如果使用'ls -l'替换该命令,则它工作得很好。更有趣的是,如果我使用以下命令“服务drbd状态”或甚至“服务drbd停止”,这些也是可行的。运行'service drbd start'有什么特别之处? –