При реализации многопроцессорной обработки Python функция выдает разные возвращаемые значения?

#python #python-multiprocessing

#python #python-многопроцессорность

Вопрос:

Функция выдает разные результаты, когда я запускаю ее из одного процесса, по сравнению с тем, когда я вызываю ее с помощью многопроцессорной обработки. Я не уверен, почему. Я создаю список из диспетчера и вызываю одну и ту же целевую функцию с разными параметрами для каждого процесса. Целевая функция вызывает функцию, которая импортируется из другого модуля. Это импортированная функция, которая дает мне разные результаты в зависимости от того, когда я вызываю ее из нескольких процессов или из одного процесса.

Например:

 from foo import foo_function
from multiprocessing import Process, Manager


def another_function(indices, a_list, return_list):
    for i in indices:
        for j in a_list:
            return_list.append(foo_function(i, j))


if __name__ == '__main__':
    jobs = []
    manager = Manager()
    return_list = manager.list()
    all_indices = [[0, 1, 2], [3, 4, 5], [6, 7, 8]]
    all_lists = [['a', 'b', 'c'], ['d', 'e', 'f'], ['g', 'h', 'i']]
    for i in range(3):
        jobs.append(Process(target=another_function, args=(all_indices[i], all_lists[i])))
        jobs[i].start()
    for i in range(3):
        jobs[i].join()
  

И foo_function() дает мне разные результаты, когда я вызываю ее из нескольких процессов, по сравнению с тем, когда я вызываю ее из одного.

РЕДАКТИРОВАТЬ: вот какова фактическая функция foo_function:

 def battle(ally: CustomClass, enemy: CustomClass, shields: int):
    ally.starting_shields = shields
    enemy.starting_shields = shields

    ally.reset()
    enemy.reset()

    turns = 0

    # Main Battle Loop
    while ally.is_alive() and enemy.is_alive():
        ally.reduce_cooldown()
        enemy.reduce_cooldown()

        turns  = 1
        if ally.can_act():
            if not ally.use_charge_move(enemy):
                ally.use_move(ally.fast_move, enemy)

        if enemy.can_act():
            if not enemy.use_charge_move(ally):
                enemy.use_move(enemy.fast_move, ally)

    # There are 2 points for using enemy shields and 3 for using enemy health.
    ally_rating = enemy.starting_shields - enemy.get_shields()
    enemy_rating = ally.starting_shields - ally.get_shields()
    ally_rating  = 5 * (enemy.starting_health - enemy.get_health()) / enemy.starting_health
    enemy_rating  = 5 * (ally.starting_health - ally.get_health()) / ally.starting_health
    if ally.get_health() > 0:
        ally_rating  = 3 * ally.energy / 100
    if enemy.get_health() > 0:
        enemy_rating  = 3 * enemy.energy / 100

    total_rating = ally_rating   enemy_rating
    return int(round(1000 * ally_rating / total_rating, 0)), int(round(1000 * enemy_rating / total_rating, 0))
  

Как вы можете видеть, она вызывает только методы CustomClasses и использует только локальные переменные.

Комментарии:

1. Не изменяйте список в своей функции. В результате возвращает новый независимый список.

2. Я не думаю, что это проблема, поскольку foo_function дает разные результаты. Я получаю правильное количество записей в моем return_list , но возвращаемое значение foo_function отличается при использовании многопроцессорной обработки.

3. Трудно сказать без кода этой функции.

4. Да, прошу прощения. Я не могу опубликовать весь код, поскольку эта функция вызывает методы переданных ей классов, а эти классы довольно большие и сложные. Я думаю, мой главный вопрос заключался в том, обрабатывает ли многопроцессорная обработка целевую функцию, вызывающую другие функции, соответствующим образом?

5. Я обновил его с помощью кода foo_function, дайте мне знать, если это поможет.

Ответ №1:

Проблема оказалась не связанной с многопроцессорной обработкой. Извините.

Ответ №2:

Довольно сложно сказать, не зная foo_function , но, вероятно, это связано с тем, что разные процессы обращаются к ссылке на один и тот же список и обнаруживают, что для каждого из них разные значения, поскольку, похоже, там нет какой-либо обработки совпадений.

Комментарии:

1. Итак, два параметра, переданные в foo_function, являются созданными мной классами, но ни один из них не использует какие-либо глобальные переменные или что-либо еще. Что касается самой foo_function, помимо переданных ей классов, она использует только локальные переменные. Это проблема?