线程子流程的奇怪输出 [英] Strange output for threaded subprocesses

查看:79
本文介绍了线程子流程的奇怪输出的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

感谢您抽出宝贵的时间来研究此问题,对此提供的任何帮助将不胜感激!

thanks for taking the time to look at this, any help with this would be most appreciated!

我试图通过ping称为ips的IP地址列表来获得一些网络统计信息.但是我遇到的问题是我的输出是一个包含几个无"的列表.在实现线程以运行子流程命令之前,下面显示的输出是一系列数字.如果有人可以看一下我的源代码并阐明了这个问题,我将不胜感激!

I am trying to get some network stats by pinging a list of IP address' called ips. The problem i'm having however is that my output is a list containing several 'None's'. Before implementing threads to run the sub-process commands, the output shown below was a series of numbers. If anybody can take a look at my source code and shed some light on the issue i'd be very grateful!

先谢谢您!

import subprocess
import re
import threading
from multiprocessing import Pool, Lock
from multiprocessing.dummy import Pool as ThreadPool



def get_ips():

    # Fill empty list with IP address
    ips = []
    with open('C:\Python26\ARPips.prn','r')as f:
        for line in f:
            line = line[:-1]
            if line != "end":
                ips.append(line)
        return ips

def ping(pingArgs):


    lock = Lock()
    lock.acquire()

    # Ping with "pingArgs" as the arguments
    ping = subprocess.Popen(pingArgs,
        stdout = subprocess.PIPE,
        stderr = subprocess.PIPE,
        shell=True)

    # Get and parse output
    out = ping.communicate()
    out = ''.join((out))

    lost = re.findall(r"Lost = (\d+)", out)
    minimum = re.findall(r"Minimum = (\d+)", out)
    maximum = re.findall(r"Maximum = (\d+)", out)
    avg = re.findall(r"Average = (\d+)", out)
    no =  re.findall(r"Sent = (\d+)", out)

    # Change output to integers
    lost = [int(x) for x in lost]
    minimum = [int(x) for x in minimum]
    maximum = [int(x) for x in maximum]
    avg = [int(x) for x in avg]
    no = [int(x) for x in no]



    print "%s \t \t %s \t \t%s \t \t %s \t \t%s" % (no, lost, maximum, minimum, avg)
    lock.release()

def main():


    # grab IP address list
    ips = get_ips()

    # Declare global variables
    global position, newIP, pingArgs

    position = 0
    newIP = ips[position]
    position += 1
    pingArgs = ["ping", "-n", "1", "-l", "1", "-w", "100", newIP]


    # Header for output
    print "Packets \t loss(%) \t Max(ms) \t Min(ms) \t Average(ms)"

    # Instantiate Pool objects, and set size of pool
    pool = Pool(processes=12)


    #Ping ips in own threads and return the results
    result = pool.map(ping, ips)


    # Close the pool and wait for work to finish
    pool.close()
    pool.join()

    # print the results
    print result

if __name__ == '__main__':
    main()
    print get_ips()

输出如下所示:

Packets      loss(%)     Max(ms)     Min(ms)     Average(ms)
[]       []         []       []         []
[]       []         []       []         []
[]       []         []       []         []
[]       []         []       []         []
[]       []         []       []         []
[]       []         []       []         []
[]       []         []       []         []
[]       []         []       []         []
[]       []         []       []         []
[]       []         []       []         []
[]       []         []       []         []
[]       []         []       []         []
[]       []         []       []         []
[]       []         []       []         []
[]       []         []       []         []
[]       []         []       []         []
[None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None]
['10.10.10.1', '10.10.10.41', '10.10.10.42', '10.10.10.43', '10.10.10.49', '10.10.10.51', '10.10.10.61', '10.10.10.71', '10.10.10.91', '10.10.10.92', '10.10.10.201', '10.10.10.205', '10.10.10.208', '10.10.10.209', '10.10.10.213', '10.10.10.214']

Process finished with exit code 0

推荐答案

但是我遇到的问题是我的输出是一个包含多个无"的列表

The problem i'm having however is that my output is a list containing several 'None's'

Noneprint result生成,其中result = pool.map(ping, ips)因为ping()函数不返回任何内容(这意味着它在Python中返回None).

The Nones are produced by print result where result = pool.map(ping, ips) because ping() function doesn't return anything (it means it returns None in Python).

在实现线程以运行子流程命令之前,下面显示的输出是一系列数字.

Before implementing threads to run the sub-process commands, the output shown below was a series of numbers.

您正在将IP地址传递给Popen(),而不是要运行的完整ping命令.

You are passing ip addresses to Popen() instead of the full ping command to run.

您正在定义不在任何地方使用的global pingArgs(ping()中的本地pingArgs使它黯然失色).您可以用内置的map调用替换pool.map,该调用在同一进程和同一线程中创建结果列表,以查看结果是否相同(正则表达式不匹配)并且错误与线程/程序.

You are defining global pingArgs that is not used anywhere (local pingArgs in ping() overshadows it). You could replace pool.map by builtin map call that creates the result list in the same process and in the same thread, to see that the result is the same (regexes do not match) and the error is not related to threads/processes.

本地 lock = Lock()是没有用的.

以下是解决上述问题的代码:

Here's the code where the above issues are fixed:

#!/usr/bin/env python
import re
from multiprocessing.dummy import Pool # use threads
from subprocess import Popen, PIPE

def get_ips(filename):
    ips = []
    with open(filename) as f:
        for line in f:
            line = line.strip()
            if line and line != "end":
                ips.append(line)
    return ips

def ping(ip):
    cmd = ["ping", "-n", "1", "-l", "1", "-w", "100", ip]
    ping = Popen(cmd, stdout=PIPE, stderr=PIPE)

    # Get and parse output
    output, err = ping.communicate()
    out = ''.join([output, err])

    lost = re.findall(r"Lost = (\d+)", out)
    minimum = re.findall(r"Minimum = (\d+)", out)
    maximum = re.findall(r"Maximum = (\d+)", out)
    avg = re.findall(r"Average = (\d+)", out)
    no =  re.findall(r"Sent = (\d+)", out)

    # Change output to integers
    lost = [int(x) for x in lost]
    minimum = [int(x) for x in minimum]
    maximum = [int(x) for x in maximum]
    avg = [int(x) for x in avg]
    no = [int(x) for x in no]

    return "%s \t \t %s \t \t%s \t \t %s \t \t%s" % (
        no, lost, maximum, minimum, avg)

def main():
    # grab IP address list
    ips = get_ips(r'C:\Python26\ARPips.prn')

    # Header for output
    print "Packets \t loss(%) \t Max(ms) \t Min(ms) \t Average(ms)"

    # Instantiate Pool objects, and set size of pool
    pool = Pool(processes=12)

    #Ping ips in own threads and return the results
    results = pool.map(ping, ips)

    # Close the pool and wait for work to finish
    pool.close()
    pool.join()

    # print the results
    print "\n".join(results)

if __name__ == '__main__':
    main()

这篇关于线程子流程的奇怪输出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆