Найти - Пользователи
Полная версия: wmi.WMI не дружит с многопоточностью
Начало » Network » wmi.WMI не дружит с многопоточностью
1
XTerm
Добрый вечер всем!

Есть нехитрый скрипт для получения данных с серваков по WMI. Сначала я написал все “в столбик” и все было ОК но, на один запрос уходило по 50 секунд. Потом я решил переписать все это на многопоточность. И Пайтон стал ругаться на “c = wmi.WMI(host)”

Подскажите что с этим делать, или куда копать? Мой мозг уже моргает…

Скрипт:
#!/bin/python
import sys
import os
import wmi
import csv
import thread
import time
import getpass # hidden pass
# wmi username and password
#username = raw_input("Enter domain and adm_ user: ")
#password = getpass.getpass("Enter adm_ pass: ")
print "Start working..."
# thread function
def get_wmi(n, host, lock):
  #c = wmi.WMI("ees-hst-01", user=r"MachineB\fred", password="secret")
  c = wmi.WMI(host) # connect to server
  wql = "SELECT Size FROM Win32_LogicalDisk WHERE Caption = 'C:'"
  for disk in c.query(wql): # get data from server by WQL
    print "%s, %s, %s" % (n, host, disk.Size)
  lock.release()
n=0
lock_list=[] # lock list
for row in csv.reader(open("servers2.csv")):
  host = row[0]
  n=n+1
  lock=thread.allocate_lock() # create new lock (default=false)
  lock.acquire() # set lock true
  lock_list.append(lock) # save lock to list
  thread.start_new_thread(get_wmi, (n, host, lock))
  
while(any([l.locked() for l in lock_list])):
  time.sleep(2)
print "DONE"

Текст ошибки:
Start working...
Unhandled exception in thread started by <function get_wmi at 0x01A035F0>Unhandl
ed exception in thread started by <function get_wmi at 0x01A035F0>
Traceback (most recent call last):

Traceback (most recent call last):
File "get-disk.py", line 19, in get_wmi
File "get-disk.py", line 19, in get_wmi
Unhandled exception in thread started by <function get_wmi at 0x01A035F0>

Traceback (most recent call last):
File "get-disk.py", line 19, in get_wmi
c = wmi.WMI(host) # connect to server
c = wmi.WMI(host) # connect to server
File "C:\Python27\lib\site-packages\wmi.py", line 1182, in connect
File "C:\Python27\lib\site-packages\wmi.py", line 1182, in connect
c = wmi.WMI(host) # connect to server
File "C:\Python27\lib\site-packages\wmi.py", line 1182, in connect
handle_com_error (error_info)
handle_com_error (error_info)
File "C:\Python27\lib\site-packages\wmi.py", line 189, in handle_com_error

File "C:\Python27\lib\site-packages\wmi.py", line 189, in handle_com_error
handle_com_error (error_info)
raise x_wmi, "\n".join (exception_string)
raise x_wmi, "\n".join (exception_string)
wmi.x_wmiwmi. File "C:\Python27\lib\site-packages\wmi.py", line 189, in handle_
com_error
: x_wmi -0x7ffbfe1c - Invalid syntax
: -0x7ffbfe1c - Invalid syntax
raise x_wmi, "\n".join (exception_string)
wmi.x_wmi: -0x7ffbfe1c - Invalid syntax
Traceback (most recent call last):
File "get-disk.py", line 39, in <module>
time.sleep(2)
KeyboardInterrupt
lorien
Попробуйте переписать с использованием модуля multiprocessing вместо threading
XTerm
lorien
Попробуйте переписать с использованием модуля multiprocessing вместо threading

Блин, так не хочется. Уже вроде потихоньку вкуриваю как простые треды работают.

Я обновил WMI-либу и текст ошибки изменился. Теперь он явно ругается на

raise x_wmi_uninitialised_thread ("WMI returned a syntax error: you're proba
bly running inside a thread without first calling pythoncom.CoInitialize")

Быстрый гуглеж показал, что надо вызывать “pythoncom.CoInitialize()” из либы “pythoncom” при старте каждого треда. В тестовых условиях заработало Осталось проверить в понедельник на боевых.
lorien
multiprocessing это то же самое, что threading, API тот же самый, только создаются процессы, а не треды, ну и нельзя просто так брать и менять переменные, нужно использовать очереди или же специально заворачивать переменные в proxy-классы. Но если вам надо менять всякие переменные из разных потоков, это не очень хороший дизайн приложения.
XTerm
lorien
multiprocessing это то же самое, что threading, API тот же самый, только создаются процессы, а не треды, ну и нельзя просто так брать и менять переменные, нужно использовать очереди или же специально заворачивать переменные в proxy-классы. Но если вам надо менять всякие переменные из разных потоков, это не очень хороший дизайн приложения.

Я боюсь, что главной проблемой будет то, что если 70 потоков разом еще можно запустить, то на 70 процесов операционка явно обидится.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB