Форум сайта python.su
-1
Есть два scripts, первый выполняется без потока, второй с потоком, но результат по выполнения одинаковый. Поясните, как может быть такое?
from pysnmp.entity.rfc3413.oneliner import cmdgen
from pysnmp.proto import rfc1902
def eval_model():
for ln in open('lst'):
errorIndication,errorStatus,errorIndex,varBinds = cmdgen.CommandGenerator().getCmd(cmdgen.CommunityData('None', 'public'),
cmdgen.UdpTransportTarget((ln.split()[0],161),retries=0),(1,3,6,1,4,1,171,12,8,1,1,3,0))
if __name__ == "__main__":
eval_model()
real 1m32.357s
user 1m7.872s
sys 0m2.608s
from pysnmp.entity.rfc3413.oneliner import cmdgen
from pysnmp.proto import rfc1902
from Queue import Queue
from threading import Thread
num_threads = 100
queue = Queue()
ips = [line for line in open('lst')]
def pinger(i, q):
while True:
ip = q.get()
cmdgen.CommandGenerator().getCmd(cmdgen.CommunityData('None', 'public'),
cmdgen.UdpTransportTarget((ip.split()[0],161),retries=1),(1,3,6,1,4,1,171,12,8,1,1,3,0))
q.task_done()
for i in range(num_threads):
worker = Thread(target=pinger, args=(i, queue))
worker.setDaemon(True)
worker.start()
for ip in ips:
queue.put(ip.rstrip())
queue.join()
real 1m24.136s
user 1m13.941s
sys 0m11.661s
Отредактировано (Май 31, 2011 09:36:35)
Офлайн
14
А почему он должен быть разный?
И почему вы заводите сто потоков? Из соображения “маслом кашу не испортишь”?
Офлайн
-1
Андрей СветловМне нужно уменьшить опроса сети, который состоит из 700 узлов, при использовании потока время должно сократиться. Почему взял 100, у меня 700 устройств для опроса, прикинул, взял сто потоков
А почему он должен быть разный?
И почему вы заводите сто потоков? Из соображения “маслом кашу не испортишь”?
Офлайн
0
Почитайте вот эту статью на хабре. Скорее всего потоки Вам здесь не помогут.
http://habrahabr.ru/blogs/python/84629/
Офлайн
-1
немного изменим вместо PySNMP воспользуемся net-snmp и вызовем его через subporcess
результат сразу же меняется.
import subprocess
from Queue import Queue
from threading import Thread
num_threads = 50
queue = Queue()
ips = [line for line in open('lst')]
def pinger(i, q):
while True:
ip = q.get()
subprocess.call('snmpget -v2c -c public {0} 1.3.6.1.4.1.171.12.8.1.1.3.0'.format(ip),
stdout=open('/dev/null','w'),stderr=subprocess.STDOUT,shell=True)
q.task_done()
for i in range(num_threads):
worker = Thread(target=pinger, args=(i, queue))
worker.setDaemon(True)
worker.start()
for ip in ips:
queue.put(ip.rstrip())
queue.join()
real 0m15.126s
user 1m1.816s
sys 0m15.737s
import subprocess
for ip in open('lst'):
subprocess.call('snmpget -v2c -c public {0} 1.3.6.1.4.1.171.12.8.1.1.3.0'.format(ip.rstrip()),
stdout=open('/dev/null','w'),stderr=subprocess.STDOUT,shell=True)
real 2m10.877s
user 0m35.538s
sys 0m7.292s
Офлайн
14
Это такая pysnmp чудесатая.
Запустите асинхроный диспетчер http://pysnmp.sourceforge.net/docs/4.x/index.html#ASYNCH-ONELINER-APPS
И, кажется, будет вам счастье в одном потоке.
Офлайн
-1
Андрей Светловрезультат с асинхроный диспетчером, хоть и с одном потоком или 10-ми потоками все тоже
Это такая pysnmp чудесатая.
Запустите асинхроный диспетчер http://pysnmp.sourceforge.net/docs/4.x/index.html#ASYNCH-ONELINER-APPS
И, кажется, будет вам счастье в одном потоке.
from Queue import Queue
from threading import Thread
from pysnmp.entity.rfc3413.oneliner import cmdgen
num_threads = 10
queue = Queue()
ips = [line for line in open('/home/bin/dlink.lst')]
def pinger(i, q):
while True:
ip = q.get()
def cbFun(sendRequestHandle, errorIndication, errorStatus, errorIndex, varBinds, cbCtx):
pass
# print 'sendRequestHandle =', sendRequestHandle
# print 'errorIndication =', errorIndication
# print 'errorStatus =', errorStatus
# print 'varBinds =', varBinds
# print 'cbCtx =', cbCtx
asynCommandGenerator = cmdgen.AsynCommandGenerator()
sendRequestHandle = asynCommandGenerator.asyncNextCmd(cmdgen.CommunityData('None', 'public'),
cmdgen.UdpTransportTarget((ip.split()[0], 161),retries=0),((1,3,6,1,4,1,171,12,8,1,1,3,0),),(cbFun, None))
asynCommandGenerator.snmpEngine.transportDispatcher.runDispatcher()
q.task_done()
for i in range(num_threads):
worker = Thread(target=pinger, args=(i, queue))
worker.setDaemon(True)
worker.start()
for ip in ips:
queue.put(ip.rstrip())
queue.join()
real 1m19.577s
user 1m10.796s
sys 0m11.305s
Отредактировано (Июнь 3, 2011 03:36:25)
Офлайн
14
Вы меня неправильно поняли. Я имел в виду нечто вроде
from pysnmp.entity.rfc3413.oneliner import cmdgen
ips = [line for line in open('/home/bin/dlink.lst')]
def cbFun(sendRequestHandle, errorIndication, errorStatus, errorIndex, varBinds, cbCtx):
print 'sendRequestHandle =', sendRequestHandle
print 'errorIndication =', errorIndication
print 'errorStatus =', errorStatus
print 'varBinds =', varBinds
print 'cbCtx =', cbCtx
asynCommandGenerator = cmdgen.AsynCommandGenerator()
for ip in ips:
sendRequestHandle = asynCommandGenerator.asyncNextCmd(
cmdgen.CommunityData('None', 'initial_pysnmp'),
cmdgen.UdpTransportTarget((ip.split()[0], 161),retries=0),
((1,3,6,1,4,1,171,12,8,1,1,3,0),),(cbFun, None))
asynCommandGenerator.snmpEngine.transportDispatcher.runDispatcher()
Офлайн
-1
Андрей СветловСпасибо, за ответ! Проверил но как-то все странно работает, больше 50 устройств не может обработать, в результате получаю списки а в списке кортежи и говорит что “No SNMP response received before timeout”. Как-то всё веселенько получается.
Вы меня неправильно поняли. Я имел в виду нечто вродеfrom pysnmp.entity.rfc3413.oneliner import cmdgen
ips = [line for line in open('/home/bin/dlink.lst')]
def cbFun(sendRequestHandle, errorIndication, errorStatus, errorIndex, varBinds, cbCtx):
print 'sendRequestHandle =', sendRequestHandle
print 'errorIndication =', errorIndication
print 'errorStatus =', errorStatus
print 'varBinds =', varBinds
print 'cbCtx =', cbCtx
asynCommandGenerator = cmdgen.AsynCommandGenerator()
for ip in ips:
sendRequestHandle = asynCommandGenerator.asyncNextCmd(
cmdgen.CommunityData('None', 'initial_pysnmp'),
cmdgen.UdpTransportTarget((ip.split()[0], 161),retries=0),
((1,3,6,1,4,1,171,12,8,1,1,3,0),),(cbFun, None))
asynCommandGenerator.snmpEngine.transportDispatcher.runDispatcher()
[('a575021578',), ('a575021787',), ('a575021885',), ('a575021573',), ('a575021569',), ('a575022013',), ('a575022090',), ('a575021775',), ('a575022030',), ('a575022247',), ('a575021748',), ('a575021907',), ('a575022076',), ('a575021672',), ('a575021657',), ('a575022173',), ('a575022148',), ('a575021852',), ('a575021705',), ('a575021973',), ('a575022285',), ('a575021946',), ('a575021688',), ('a575022158',), ('a575022098',)]
sendRequestHandle = 193244589
errorIndication = No SNMP response received before timeout
errorStatus = 0
varBinds = ()
cbCtx = NoneОфлайн
0
Возможно обработка 50-сяти snmp запросов занимает более времени таймаута запроса, в рез-те часть ответов отбрасывается. Попробуйте увеличить таймаут ожидания ответа в pysnmp.
Что касается причин неудачи с МТ подходом - возможно проблема в GIL в сочетании с большими затратами на вычисления внутри pysnmp.
Офлайн