這個問題在這里已經有了答案: 執行緒在呼叫 Thread.start 之前開始運行 1 個回答 4天前關閉。
我正在嘗試并行運行兩塊代碼,但沒有這樣做。這兩個函式都是 for 回圈,總共可能需要大約 30 分鐘才能運行,這些函式最終回傳一個字典串列作為結果。單獨運行它們作業正常,但我不能讓它們并行運行......
#When I run these functions separately, it sort of looks like this:
import time
def functionA(A, B):
dictA=[]
for i in list(range(A, B)):
print(i, "from A")
time.sleep(1)
for p in list(range(0, 10)):
dictA.append({i:p})
return(dictA)
def functionB(C, D):
dictB=[]
for i in list(range(C, D)):
print(i, "from B")
time.sleep(1)
for p in list(range(0, 10)):
dictB.append({i:p})
return(dictB)
DictA = functionA(0, 10)
DictB = functionB(10, 20)
#I have tried to run them in parallel, but they still run separately, and in the end the variable I would like to write to is just a thread:
import threading
e = threading.Event()
DictA = threading.Thread(target=functionA(0, 10))
DictA.start()
DictB = threading.Thread(target= functionB(10, 20))
DictB.start()
#Further pieces of code to be executed after threading completed
從列印陳述句中可以看出,這不會使行程并行運行,而是按邏輯順序運行:
0 from A
1 from A
2 from A
3 from A
4 from A
5 from A
6 from A
7 from A
8 from A
9 from A
Exception in thread Thread-12:
Traceback (most recent call last):
File "/home/maestro/.pyenv/versions/3.9.13/lib/python3.9/threading.py", line 980, in _bootstrap_inner
self.run()
File "/home/maestro/.pyenv/versions/3.9.13/lib/python3.9/threading.py", line 917, in run
self._target(*self._args, **self._kwargs)
TypeError: 'list' object is not callable
10 from B
11 from B
12 from B
13 from B
14 from B
15 from B
16 from B
17 from B
18 from B
19 from B
Exception in thread Thread-13:
Traceback (most recent call last):
File "/home/maestro/.pyenv/versions/3.9.13/lib/python3.9/threading.py", line 980, in _bootstrap_inner
self.run()
File "/home/maestro/.pyenv/versions/3.9.13/lib/python3.9/threading.py", line 917, in run
self._target(*self._args, **self._kwargs)
TypeError: 'list' object is not callable
這些功能如何并行運行?
uj5u.com熱心網友回復:
常規函式可以回傳可以存盤在變數中的值。
def check_links_a(links, proxies):
return f'A links are {links} and A proxies are {proxies}'
def check_links_b(links, proxies):
return f'B links are {links} and B proxies are {proxies}'
links_to_check_a = 'A links'
links_to_check_b = 'B links'
proxy_list = 'some proxies'
result1 = check_links_a(links_to_check_a, proxy_list)
result2 = check_links_b(links_to_check_b, proxy_list)
print(result1)
print(result2)
結果:
A links are A links and A proxies are some proxies
B links are B links and B proxies are some proxies
如果您將函式作為執行緒運行,則回傳將是執行緒本身,而不是函式的回傳。
def some_stuff_a(stuff):
for i in range(10):
print(f'some A {stuff}')
time.sleep(1)
return 'A stuff is done'
def some_stuff_b(stuff):
for i in range(10):
print(f'some B {stuff}')
time.sleep(1)
return 'B stuff is done'
a_stuff = 'from the A stuff var'
b_stuff = 'from the B stuff var'
thread1 = threading.Thread(target=some_stuff_a, args=[a_stuff])
thread1.start()
thread2 = threading.Thread(target=some_stuff_b, args=[b_stuff])
thread2.start()
print(thread1)
print(thread2)
兩個 print(thread1) 和 print(thread2) 陳述句的結果將是:
<Thread(Thread-1 (some_stuff_a), started 2368)>
<Thread(Thread-2 (some_stuff_b), started 11224)>
據我所知,從執行緒函式回傳值的唯一方法是使用全域變數或實體變數,因為回傳不會被 Thread 的 start() 方法轉發。
您的執行緒未并行運行的原因是您呼叫函式而不是將它們傳遞給執行緒目標。從函式中洗掉引數并將它們作為 args=[arg1, arg2] 傳遞給執行緒,如上所示。
編輯:
在這里,您有一個使用全域變數的版本。使用全域變數意味著您必須使用在函式外部定義的已定義變數作為函式內部的全域變數。我希望這能解釋我的意思:
import threading
def some_stuff_a(stuff):
global data_from_stuff_a
data_from_stuff_a = 'A stuff is done'
def some_stuff_b(stuff):
global data_from_stuff_b
data_from_stuff_b = 'B stuff is done'
a_stuff = 'from the A stuff var'
b_stuff = 'from the B stuff var'
data_from_stuff_a = ''
data_from_stuff_b = ''
thread1 = threading.Thread(target=some_stuff_a, args=[a_stuff])
thread1.start()
thread2 = threading.Thread(target=some_stuff_b, args=[b_stuff])
thread2.start()
print(data_from_stuff_a)
print(data_from_stuff_b)
這將是一個使用實體變數的版本。實體變數在從類創建的物件中定義。您可以識別它們,因為它們具有前綴 self。
import threading
import time
class MyClass:
def __init__(self):
# instance variables
self.data_from_stuff_a = ''
self.data_from_stuff_b = ''
def run_threads(self):
# local variables
a_stuff = 'from the A stuff var'
b_stuff = 'from the B stuff var'
thread1 = threading.Thread(target=self.some_stuff_a, args=[a_stuff])
thread1.start()
thread2 = threading.Thread(target=self.some_stuff_b, args=[b_stuff])
thread2.start()
thread1.join()
thread2.join()
def print_results(self):
self._print_all_stuff()
def some_stuff_a(self, stuff):
time.sleep(2)
self.data_from_stuff_a = 'A stuff is done'
def some_stuff_b(self, stuff):
time.sleep(4)
self.data_from_stuff_b = 'B stuff is done'
def _print_all_stuff(self):
print(f'stuff A: {self.data_from_stuff_a}')
print(f'stuff B: {self.data_from_stuff_b}')
my_object = MyClass()
my_object.run_threads()
my_object.print_results()
uj5u.com熱心網友回復:
你的問題在這里:
DictA = threading.Thread(target=functionA(0, 10))
在這里,您沒有functionA作為引數傳遞給target; 您正在呼叫 functionA并將值傳遞給target. 這就是為什么你的函式似乎是同步執行而不是并行執行的——因為這就是你呼叫它們的方式。
你要:
DictA = threading.Thread(target=functionA, args=(0, 10))
您的代碼的可運行版本如下所示:
import threading
import time
def functionA(A, B):
dictA = []
for i in list(range(A, B)):
print(i, "from A")
time.sleep(1)
for p in list(range(0, 10)):
dictA.append({i: p})
return dictA
def functionB(C, D):
dictB = []
for i in list(range(C, D)):
print(i, "from B")
time.sleep(1)
for p in list(range(0, 10)):
dictB.append({i: p})
return dictB
DictA = threading.Thread(target=functionA, args=(0, 10))
DictA.start()
DictB = threading.Thread(target=functionB, args=(10, 20))
DictB.start()
# Calling `.join()` on each thread here to wait for them to complete.
DictA.join()
DictB.join()
運行該代碼會產生輸出:
0 from A
10 from B
11 from B
1 from A
2 from A
12 from B
3 from A
13 from B
4 from A
14 from B
5 from A
15 from B
6 from A
16 from B
7 from A
17 from B
18 from B
8 from A
9 from A
19 from B
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/520379.html
下一篇:如何在C#中重用執行緒
