简体   繁体   English

运行线程时Python数据丢失

[英]Python Loss of data when running threads

I have two versions of the same program with the same task, one that utilizes the threading module while the other doesn't. 我有相同任务的同一程序的两个版本,一个版本利用线程模块,而另一个版本则没有。 The task I want to optimize is the following 我要优化的任务如下

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))

As you can hopefully tell I basically want to roll two dices a certain amount of times, in this example that number is 25 000 and then print out what the chance that these two dice fulfill one of the three criteria, sum is 11, sum is 7 or they both have the same number. 如您所愿,我基本上想将两个骰子掷出一定的次数,在此示例中,该数字为25,000,然后打印出这两个骰子满足以下三个条件之一的总和是11,总和是7或它们都具有相同的数字。

Of course the amount of rolls I decide to go with alters the outcome of this program by giving a more accurate answer the higher you go. 当然,我决定参加的掷骰数量会随着您的得分越高而给出更准确的答案来改变该计划的结果。 All well and good up until this point, program working as expected and the sum of wins and loss is equal to total amount of rolls. 到现在为止一切都很好,程序按预期工作,得失之和等于掷骰总数。

What bothers me is the threaded version of the program. 困扰我的是该程序的线程版本。 When I enter say, 25 000 rolls there too I end up with the sum of around 22 000 for wins + loss (this sum varies from run to run, why are there rolls disappearing?) Another side effect from running the threaded version is a less accurate calculation of the win percentage. 当我说输入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))

My aim with using this threading module was to increase the programs accuracy while taking up less processing time. 使用此线程模块的目的是提高程序精度,同时减少处理时间。 I have managed to do the exact opposite. 我设法做到了完全相反。

How is this possible and what can I do to fix it? 这怎么可能?我该如何解决?

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

You need to lock the code before the thread has access to the global, then you release it after it is done processing. 您需要先锁定代码,然后线程才能访问全局,然后在完成处理后将其释放。

A good analogy: 一个很好的类比:

You and three friends want a drink out of the water fountain, you each need to wait your turn to use it before you are able to take a drink. 您和三个朋友想要从饮水机中喝一杯,你们每个人都需要等待轮到使用它才能喝一杯。 If you each go at the same time it will get messy because there is only one water fountain. 如果你们每个人都在同一时间去,那会很混乱,因为只有一个喷泉。 The water fountain are your global variables and code, you and your friends are the threads 饮水机是您的全局变量和代码,您和您的朋友是线程

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM