Python线程:线程运行两次?

时间:2019-07-18 01:26:01

标签: python multithreading

我对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

1 个答案:

答案 0 :(得分:0)

从多个线程修改全局变量本质上是不安全的。您需要锁定访问权限以防止出现竞争状况,例如线程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()

使用锁更为复杂,但应可移植到任何具有可预测的(行为,毕竟仍在线程化)行为的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的任何给定值。