簡體   English   中英

Python線程:線程運行兩次?

[英]Python threading : Threads runs twice?

我對python完全陌生,當我遇到此問題時,我正在嘗試使用線程模塊:-由於某種原因,線程運行了兩次,我也不知道為什么。 我到處搜索,但找不到任何答案。 希望我能在這里得到一些幫助

import time
from threading import Thread
import requests as requests
import threading as threading 


threads = []
i = 0
time.sleep(0.5)
def whatever():
    global i
    while i < 10:
        get = requests.get("http://www.exemple.com")
        print(i)
        i += 1

for t in range(5):
    t = threading.Thread(target=whatever)
    threads.append(t)
    t.start()

我想要的是:

0
1
2
3
4
5
6
7
8
9
10
11
12
13

輸出:

0
1
1
3
4
5
6
7
7
9
10
11
12
13

從多個線程修改全局變量本質上是不安全的。 您需要鎖定訪問權限以防止出現競爭狀況,例如線程A讀取i ,然后線程B運行並遞增i並將其存儲回去,然后線程A再次進入並存儲其i遞增副本,因此不要遞增兩次,僅增加一次。

解決方法是要么鎖定訪問,要么想出一種天生的線程安全的方式來執行所需的操作。 在CPython參考解釋器上,可以確保字節碼之間沒有GIL釋放,因此有一些技巧可以在沒有鎖定的情況下進行:

import time
from threading import Thread

threads = []
igen = iter(range(10))
time.sleep(0.5)
def whatever():
    for i in igen:
        get = requests.get("http://www.exemple.com")
        print(i)

for t in range(5):
    t = threading.Thread(target=whatever)
    threads.append(t)
    t.start()

使用鎖更為復雜,但應可移植到任何具有可預測(ish,畢竟仍在線程化)行為的Python解釋器中:

import time
from threading import Thread, Lock

threads = []
i = 0
ilock = Lock()
time.sleep(0.5)
def whatever():
    global i
    while True:
        with ilock:
            if i >= 10:
                break
            icopy = i
            i += 1
        get = requests.get("http://www.exemple.com")
        print(icopy)

for t in range(5):
    t = threading.Thread(target=whatever)
    threads.append(t)
    t.start()

這不會按數字順序打印出來,但是會並行運行請求,並且只會為i打印一次任何給定的值。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM