运行线程时Python数据丢失

时间:2018-11-02 18:51:33

标签: python python-3.x multithreading

我有两个具有相同任务的相同程序版本,一个版本使用线程模块,而另一个版本则没有。我要优化的任务如下

from random import randint
import time

t = time.time()

rolls = 25000
wins = 0
loss = 0

while rolls > 0:
    dice1 = randint(1, 6)
    dice2 = randint(1, 6)

    if dice1+dice2 == 11 or dice1+dice2 == 7 or dice1 == dice2:
        wins += 1
    else:
        loss += 1

    rolls -= 1

print(wins+loss)
percentage = (wins / wins+loss) * 100

print("Calculated percentage of a roll fulfilling requirements are:", 
round(percentage, 2), "%")
print(round((time.time()-t), 3))

您可以希望告诉我,我基本上想将两个骰子掷出一定的次数,在此示例中,该数字为25 000,然后打印出这两个骰子满足三个条件之一的机会,总和为11 ,总和为7或它们都具有相同的数字。

当然,我决定参加的掷骰数量会随着您走的越高给出更准确的答案而改变此程序的结果。到现在为止一切都很好,程序按预期运行,得失之和等于掷骰总数。

困扰我的是该程序的线程版本。当我说输入25,000时,我也得到了大约22,000的获胜+损失总和(这个总和因运行而异,为什么卷消失了?)运行线程版本的另一个副作用是获胜百分比的计算不太准确。

from random import randint
import threading
import time

t = time.time()

def dice_calc(rolls):
    global wins
    global loss
    while rolls > 0:

        dice1 = randint(1, 6)
        dice2 = randint(1, 6)

        if dice1+dice2 == 11 or dice1+dice2 == 7 or dice1 == dice2:
            wins += 1
        else:
            loss += 1

        rolls -= 1

wins = 0
loss = 0
rolls = 25000

t1 = threading.Thread(target=dice_calc, args=(rolls/4,))
t2 = threading.Thread(target=dice_calc, args=(rolls/4,))
t3 = threading.Thread(target=dice_calc, args=(rolls/4,))
t4 = threading.Thread(target=dice_calc, args=(rolls/4,))

t1.start()
t2.start()
t3.start()
t4.start()

print(wins+loss)

t1.join()
t2.join()
t3.join()
t4.join()

percentage = (wins / (wins+loss)) * 100

print("Calculated percentage of a roll fulfilling requirements are:", 
round(percentage, 2), "%")

print(round((time.time()-t), 3))

使用此线程模块的目的是提高程序准确性,同时减少处理时间。我设法做到了完全相反。

这怎么可能?我该怎么解决?

1 个答案:

答案 0 :(得分:0)

def dice_calc(rolls):

    mutex.acquire() #Since you are using global variables you need to lock the code before the thread has access to the global

    global wins
    global loss
    while rolls > 0:

        dice1 = randint(1, 6)
        dice2 = randint(1, 6)

        if dice1+dice2 == 11 or dice1+dice2 == 7 or dice1 == dice2:
            wins += 1
        else:
            loss += 1

        rolls -= 1

    mutex.release() #Then you release it when it is finished

您需要在线程访问全局之前锁定代码,然后在完成处理后释放代码。

一个很好的类比:

您和三个朋友想从饮水机中喝一杯,你们每个人都需要等一会儿再使用它,然后才能喝一杯。如果你们每个人都在同一时间去,那会很混乱,因为只有一个喷泉。饮水机是您的全局变量和代码,您和您的朋友是线程