Multiprocesing/Threading , wywolanie funkcji rownolegle i zwrocenie jej wartosci

0

Witam,

potrzebuje podpowiedzi...jak wykonywać traceroute równolegle do np.10 serwisów ? chce żeby każda funkcja kończyła swoje działanie w momencie gdy otrzyma odpowiedz i kończąc swoje działanie dodawała owa odpowiedz do globalnej zmiennej obiektu tablicowego, na której będzie można dalej przetwarzać zwrócone informacje.

Sam threading.Thread działa genialnie, dokładnie tak jak chce, ale nic mi z tego skoro nie mogę przetworzyć zwróconych danych:/. Poniżej to co zrobilem

url = ["www.google.com", "www.se.pl", "www.fakt.pl"]


 def tracert(domainName):
       array = subprocess.check_output(("traceroute", "{}".format(domainName)))
       return array

process =[]

for iUrl in url: 
    process.append(threading.Thread(target=tracert, args=[iUrl]))

for procStart in process:
    procStart.start()

for procJoin in process:
    procJoin.join()
    

Widziałem ze mechanizm muliprocessing.Pool działa podobnie, ale na razie nie mogę tego okiełznać :/. Niby dzięki temu funkcja zwraca wartość, ale nie działa to już z taka szybkością jak Thread, a wręcz przeciwnie , nie działa równolegle, a czeka aż pierwsze wywołanie zwróci wartość, a dopiero później zaczyna następne

Dodam, ze system operacyjny to Debian 4.19.20

1

Możesz, np użyć futures:

# concurrent traceroute
import subprocess
from concurrent import futures

url = ["www.google.com", "www.google.pl", "www.google.co.uk"]


def tracert(domainName):
       array = subprocess.check_output(("traceroute", "{}".format(domainName)))
       return array

def tracert_concurrent(urls):
	w = len(urls)
	with futures.ThreadPoolExecutor(w) as executor:
		result = executor.map(tracert, urls)
	return list(result)

def tracert_linear(urls):
	return list(map(tracert, urls))

def main():
	import time
	st = time.time()
	tracert_linear(url)
	en = time.time()
	print("Linear ", en - st) # -> Linear  15.333056449890137
	st = time.time()
	tracert_concurrent(url) # -> Concurrent 5.180043697357178
	en = time.time()
	print("Concurrent", en - st)


if __name__ =='__main__':
	main()
0

Zaraz zbadam, dzięki :)

0

Możesz użyć multiprocessing pool:

def worker(data):
    return data*2

import multiprocessing

processes=8
pool = multiprocessing.Pool(processes=processes)
data_list = range(10000)
result = pool.map(worker, data_list)
pool.close()
print(result)

To generalnie spawnuje osobne procesy pythona

1 użytkowników online, w tym zalogowanych: 0, gości: 1