Python多处理奇怪的输出

时间:2018-11-02 21:45:14

标签: python python-3.x multithreading

所以我一直在尝试通过多处理来优化程序,以便它更快地处理信息,但是我得到了一些非常奇怪的结果。

代码如下:

tooltip.pointFormat

目的是从根本上找出两个骰子的总和为7、11或相等的机会是多少。我已经在线程模块中尝试了相同的代码,并且效果很好(就性能而言并没有真正的好处,但是,它确实可以工作)

困扰我的是该版本使用多处理程序的输出:

var yCategories = [
  'One',
  'Two',
  'Three',
  'Four',
  'Five',
  'Six',
  'Seven',
  'Eight',
  'Nine',
  'Ten'
];
...
  tooltip: {
    //headerFormat: '<b>{series.name}</b><br>',
    //pointFormat: 'Rank: {point.y} <br>Date: {point.x:%b %e, %Y}',
    pointFormatter: function() {
      var formatedDate = new Date(this.x).toLocaleDateString("en-US")
      return '<b>' + this.series.name + '</b><br>' +
        'Rank: ' + yCategories[this.y - 1] + '<br>Date: ' + formatedDate
    }
  }

打印的前4个值使我很困惑。不应有任何东西使这些输出成为可能,这些值也因运行而异。我相信它们起源于p1,p2,p3和p4。

此后的两个值不应该为0(这些值表示获胜和失败的次数加起来为1,000,000)(注10)。

最后一个值是唯一有意义的值。基本上,它只是一个计时器,用于检查程序运行了多长时间。

如果有人对我如何进行这项工作有任何见识,我希望听到它。

1 个答案:

答案 0 :(得分:0)

看到这些奇数的原因是由于您的陈述:

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

如果缩进该行,它将仅在名为__main__的模块下执行。

发生这种情况的原因是,当创建Process()时,Python在具有不同模块名称的新实例下执行该过程。因此,当函数dice_calcs的执行完成时,将返回并继续执行脚本,最终到达该行。

同样,您不会从赢利和亏损变量中获得任何正确的值,因为它们存在于不同的流程中。当每个Process引用赢得变量的变量时,它都引用该变量的自身副本,而不是__main__中存在的变量。

要从其他模块中获取这些变量的实际值,您需要采取某种方式在模块之间进行通信。

使用Queue模块中的queue之类的东西,您可以执行以下操作: (注意:我添加的代码被#######包围)

from random import randint
import multiprocessing
import time

t = time.time()

def dice_calc(rolls, q):
    mutex.acquire()
    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

    ########
    #return wins and losses to queue
    q.put((wins,loss))
    ########
    mutex.release()


mutex = multiprocessing.Lock()
wins = 0
loss = 0
rolls = 1000000

if __name__ == "__main__":
    ########
    #create a multiprocessing.Queue() instance that spans across Processes
    q = multiprocessing.Queue()
    ########

    p1 = multiprocessing.Process(target=dice_calc, args=(rolls/4,q))
    p2 = multiprocessing.Process(target=dice_calc, args=(rolls/4, q))
    p3 = multiprocessing.Process(target=dice_calc, args=(rolls/4, q))
    p4 = multiprocessing.Process(target=dice_calc, args=(rolls/4, q))
    p1.start()
    p2.start()
    p3.start()
    p4.start()

    ########
    #Get wins and losses from the queue
    for _ in range(4):
        item = q.get(timeout=5000)
        wins = wins + item[0]
        loss = loss + item[1]
    ########    

    p1.join()
    p2.join()
    p3.join()
    p4.join()

    print(wins)
    print(loss)
    #percentage = (wins / (wins + loss)) * 100
    #print("Calculated percentage of a roll fulfilling requirements are:", round(percentage, 2), "%")

    ########
    #Added an indent to this line
    print(round((time.time()-t), 3))
    ########