I can believe fly.

Tuesday, December 28, 2010

使用subprocess.Popen,程序block问题处理

使用subprocess.Popen,程序block问题处理

问题:

 脚本运行中,执行sudo strace svnadmin,出现卡死现象,一直保持如下信息不动:

 getcwd("/home/ysl/svn-repo-bak"..., 4098) = 28

 write(2, "* Dumped revision 2769.\n", 24

分析:

jessinio: jobs有什么呢

: 没东西

jessinio: 终端是不是和你运行SvnDumpBak.py是同一个?

: 不是,我又另外打开了一个

jessinio: 呃。。。车子不同, 你查个刹车 没有意义

: 那我要在执行命令那里,ctrl z掉,让它在后台跑?

jessinio: ctrl z 然后bg

: [ysl@svn-repo-bak]$ bg

[1]+ sudo python SvnDumpBak.py yslProR &

[[ysl@svn-repo-bak]]$ jobs

[1]+ Running sudo python SvnDumpBak.py yslProR &

 

jessinio: ps auxwww|grep strace

: [[ysl@svn-repo-bak]]$ ps auxwww|grep strace

ysl 10851 0.0 0.0 61144 728 pts/0 S+ 14:45 0:00 grep strace

root 31108 2.2 0.0 4112 632 pts/1 S+ 14:31 0:17 strace -p 17686

jessinio: 还有一个strace

: 我打另一个连接,在跑strace来看,刚还有信息在更新。现就卡着了

jessinio: 你把strace停了

: ctrl c??

: 停了

 

jessinio: ps auxwww|grep 7z

: root 17687 85.5 4.9 233772 199576 pts/0 Sl 14:15 27:37 /usr/local/p7zip_9.13/bin/7z a -si /data/backup/svnRepo//20101227/yslProR.full20101227.dump -pNBc5RB!

jessinio: strace -p 17687

: [[ysl@svn-repo-bak]]$ sudo strace -p 17687

Process 17687 attached - interrupt to quit

[ Process PID=17687 runs in 32 bit mode. ]

futex(0x86b54ac, FUTEX_WAIT_PRIVATE, 1366961, NULL

jessinio: top -p 17687

: PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND

17687 root 15 0 228m 194m 1856 S 0.0 4.9 27:37.96 7z

jessinio: 变化 不?

: TIME+下的数据没变啊

jessinio: 还是没有变?

: 没,还是 27:37.96

jessinio: ps auxwww|grep svnadmin

: root 17686 2.4 2.5 205868 103152 pts/0 S 14:15 1:10 svnadmin dump /storage/repool/yslProR -r 0:4855

jessinio: 你的代码应该有问题。

: 可是小的仓库为什么没问题呢

jessinio: buffer没有满呀

结论:

    同事帮忙分析是由于buffer满导致,检查了程序,原版:

    p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)

    p.wait()

    # command exec error,print detail info

    if p.returncode:     

        write_log(p.stdout.read())

    return p.returncode

    也就是说没有处理输出数据,而pipe容量有限的。如果满了将会block或者fail。信息如下:

Pipe Capacity

      A pipe has a limited capacity.  If the pipe is full, then a write(2) will block or fail, depending on whether the  O_NONBLOCK

      flag  is  set  (see  below).

解决:调整脚本,增加了一个变量来读取PIPE里的输出数据

    p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)

    retval = p.stdout.read()

    p.wait()

    # command exec error,print detail info

    if p.returncode:     

        write_log(retval)

    return p.returncode

资料:   

    subprocess模块:http://docs.python.org/library/subprocess.html


--
Elian
 
Configuration Manage Engineer
MSN: smallfish961@hotmail.com
Email: smallfish382+work@gmail.com

No comments: