Избыточная/лишняя итерация в цикле

Рейтинг: 0Ответов: 2Опубликовано: 10.07.2023

В общем, моя проблема заключается в избыточной итерации в цикле, когда запускается код.

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

Код:

import threading
import time


mutex = threading.Lock()

flag = True


def function1():
    count = 0
    # происходит всегда лишняя итерация в начале, когда запускается код.
    # мне нужно, чтобы поток сразу заблокировался после первой итерации.
    while flag:
        time.sleep(0.01)
        count += 1
        print("\nFunction 1: Увеличение на 1:", count)
        mutex.acquire()


def function2():
    count = 0

    while flag:
        time.sleep(0.1)
        count += 2
        print("\nFunction 2: Увеличение на 2:", count)
        function3()


def function3():
    global flag

    con_input = input("Do you want to continue: ")
    if con_input.lower().strip() in ["yes", "y"]:
        mutex.release()
    else:
        flag = False
        mutex.release()

    return


thread1 = threading.Thread(target=function1, name="first")
thread2 = threading.Thread(target=function2, name="second")


thread1.start()
thread2.start()

Ответы

▲ 0Принят

Подобные задачи можно решать с использованием переменных состояния. А мьютекс в данном случае стоит оставить для синхронизации ввода/вывода.

import threading
import time

mutex = threading.Lock()
cv = threading.Condition()

flag = True

def addition(step):
    count = 0
    while flag:
        count += step
        mutex.acquire()
        print(f"addition {step}: Увеличение на {step}:", count)
        mutex.release()
        cv.acquire()
        cv.wait()
        cv.release()

def control():
    global flag

    mutex.acquire()
    con_input = input("Do you want to continue: ")
    mutex.release()

    flag = con_input.lower().strip() in ["yes", "y"]

    cv.acquire()
    cv.notify_all()
    cv.release()


thread1 = threading.Thread(target=addition, args=(1,))
thread2 = threading.Thread(target=addition, args=(2,))

thread1.start()
thread2.start()

while thread1.is_alive() and thread2.is_alive():
    control()
    time.sleep(.1)

▲ 0

Проблема возникает из-за того, что вы вызываете функцию function3() внутри цикла function2(). Это приводит к тому, что после каждой итерации цикла function2() выполняется еще одна итерация внутри function3().

Чтобы исправить это, вы можете переместить вызов function3() за пределы цикла function2(), чтобы он выполнялся только один раз после завершения цикла. Вот исправленный код:

import threading
import time

mutex = threading.Lock()

flag = True

def function1():
count = 0
while flag:
    time.sleep(0.01)
    count += 1
    print("\nFunction 1: Увеличение на 1:", count)
    mutex.acquire()

def function2(): count = 0 while flag: time.sleep(0.1) count += 2 print("\nFunction 2: Увеличение на 2:", count)

function3()

def function3():
    global flag
    con_input = input("Do you want to continue: ")
    if con_input.lower().strip() in ["yes", "y"]:
    mutex.release()
    else:
        flag = False
        mutex.release()

thread1 = threading.Thread(target=function1, name="first")
thread2 = threading.Thread(target=function2, name="second")

thread1.start()
thread2.start()

Теперь функция function3() вызывается только один раз после завершения цикла function2(), и избыточная итерация больше не происходит.