2017-04-22 15 views
12

मेरे पास निम्न कोड है जहां मेरे पास उपयोगकर्ता नामों की एक सूची है और मैं कोशिश करता हूं और जांचता हूं कि उपयोगकर्ता net user \domain | find somegroup का उपयोग कर एक विशिष्ट विंडोज उपयोगकर्ता समूह में हैं या नहीं।भविष्य की कॉल कैसे करें और पायथन के साथ पूरा होने तक प्रतीक्षा करें?

समस्या यह है कि मैं प्रति उपयोगकर्ता लगभग 8 उपयोगकर्ता समूह के लिए उस आदेश को चलाता हूं और यह धीमा है। मैं इन कॉलों को वायदा और यहां तक ​​कि अलग धागे का उपयोग करके भेजना चाहता हूं (यदि यह इसे तेज बनाता है)।

मुझे कुछ और करने से पहले मुझे अंत में इंतजार करना होगा। मैं पायथन में इसे करने के बारे में कैसे जा सकता हूं?

for one_username in user_list: 
    response = requests.get(somecontent) 

    bs_parsed = BeautifulSoup(response.content, 'html.parser') 

    find_all2 = bs_parsed.find("div", {"class": "QuickLinks"}) 
    name = re.sub("\s\s+", ' ', find_all2.find("td", text="Name").find_next_sibling("td").text) 

    find_all = bs_parsed.find_all("div", {"class": "visible"}) 
    all_perms = "" 
    d.setdefault(one_username + " (" + name + ")", []) 
    for value in find_all: 
     test = value.find("a", {"onmouseover": True}) 
     if test is not None: 
      if "MyAppID" in test.text: 
       d[one_username + " (" + name + ")"].append(test.text) 

    for group in groups: 
     try: 
      d[one_username + " (" + name + ")"].append(check_output("net user /domain " + one_username + "| find \"" + group + "\"", shell=True, stderr=subprocess.STDOUT).strip().decode("utf-8")) 
     except Exception: 
      pass 

उत्तर

8

उत्पन्न करनी चाहिए (इस उत्तर वर्तमान में पार्स करने के लिए अपने कोड है ... आपको लगता है कि कतार कर सकते हैं एक पूल में HTML पर ध्यान नहीं देता हूबहू कैसे इस दृष्टिकोण net user कॉल कतारों के लिए)

सबसे पहले, (user, group) का tuple लेता है और वांछित जानकारी देता है, तो एक फ़ंक्शन को परिभाषित करने देता है।

# a function that calls net user to find info on a (user, group) 
def get_group_info(usr_grp): 
    # unpack the arguments 
    usr, grp = usr_grp 

    try: 
     return (usr, grp, 
       check_output(
        "net user /domain " + usr + "| find \"" + grp + "\"", 
        shell=True, 
        stderr=subprocess.STDOUT 
        ).strip().decode("utf-8"))) 
    except Exception: 
     return (usr, grp, None) 

अब, हम multiprocessing.dummy.Pool

from multiprocessing.dummy import Pool 
import itertools 

# create a pool with four worker threads 
pool = Pool(4) 

# run get_group_info for every user, group 
async_result = pool.map_async(get_group_info, itertools.product(user_list, groups)) 

# now do some other work we care about 
... 

# and then wait on our results 
results = async_result.get() 

results(user, group, data) tuples की एक सूची का उपयोग कर रहे एक धागा पूल में इस चला सकते हैं और के रूप में आप की इच्छा संसाधित किया जा सकता।

नोट:इस कोड प्लेटफार्मों

1

ऐसा लगता है कि producer consumer problem है।

मुख्य थ्रेड कार्यों

class Task: 
    def Task(self,user,group) 
     self.user = user 
     self.group = group 
    def run(self): 
     pass # call command with self.user and self.group and process results 

twp = TaskWorkerPool(4) 
for group in groups: 
    twp.add(Task(user,group)) 
twp.wait() 
1

अजगर 3 में में एक फर्क की वजह से वर्तमान में अपरीक्षित है, एक और अधिक सरल और सुविधाजनक समाधान concurrent.futures उपयोग करने के लिए है।

concurrent.futures मॉड्यूल अतुल्यकालिक रूप से कॉलबेल निष्पादित करने के लिए एक उच्च स्तरीय इंटरफ़ेस प्रदान करता है। Reference...

import concurrent.futures 


# Get a list containing all groups of a user 
def get_groups(username): 
    # Do the request and check here 
    # And return the groups of current user with a list 
    return list() 

with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor: 
    # Mark each future with its groups 
    future_to_groups = {executor.submit(get_groups, user): user 
         for user in user_list} 

    # Now it comes to the result of each user 
    for future in concurrent.futures.as_completed(future_to_groups): 
     user = future_to_groups[future] 
     try: 
      # Receive the returned result of current user 
      groups = future.result() 
     except Exception as exc: 
      print('%r generated an exception: %s' % (user, exc)) 
     else: 
      # Here you do anything you need on `groups` 
      # Output or collect them 
      print('%r is in %d groups' % (user, len(groups))) 

सूचना है कि max_workers यहाँ धागे की अधिकतम संख्या का मतलब है।

here देखें जहां यह उदाहरण आता है।

संपादित करें:

आप अलग सूत्र में प्रत्येक चेक करने के लिए की जरूरत है:

import concurrent.futures 


# Check if a `user` is in a `group` 
def check(user, group): 
    # Do the check here 
    # And return True if user is in this group, False if not 
    return True 

with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor: 
    # Mark each future with its user and group 
    future_to_checks = {executor.submit(check, user, group): (user, group) 
         for user in user_list for group in group_list} 

    # Now it comes to the result of each check 
    # The try-except-else clause is omitted here 
    for future in concurrent.futures.as_completed(future_to_checks): 
     user, group = future_to_checks[future] 
     in_group = future.result() 
     if in_group is True: 
      print('%r is in %r' % (user, group)) 

@donkopotamus से प्रेरित होकर, itertools.product यहाँ सभी लक्ष्यों उत्पन्न करने के लिए इस्तेमाल किया जा सकता।

और अगर आप अपवाद को संभालने के लिए की जरूरत नहीं है, यह बहुत अधिक आसान होगा:

import concurrent.futures 
from itertools import product 
from collections import defaultdict 


def check(target): 
    user, group = target 
    return True 

with concurrent.futures.ThreadPoolExecutor() as executor: 
    results = defaultdict(list) 
    targets = list(product(user_list, group_list)) 
    for (user, group), in_group in zip(targets, executor.map(check, targets)): 
     if in_group is True: 
      results[user].append(group) 

    print(results) 
संबंधित मुद्दे