Какая разница между этими двумя методами соединения в многопоточности в python?

Я хочу использовать пакет потоков для вычисления квадрата числа и моего кода, например,

import threading
def my_squr(num):   #if this function take long time to run
    print(num*num)
    return num*num

if __name__ == "__main__":

    l1 = [1,3,5,7,11,13,15,17]
    for i, item in enumerate(l1):
        if i % 3 == 0:
            t1 = threading.Thread(target=my_squr, args=(item,))
            t1.start()
            t1.join()
        elif i % 3 == 1:
            t2 = threading.Thread(target=my_squr, args=(item,))
            t2.start()
            t2.join()
        else:
            t3 = threading.Thread(target=my_squr, args=(item,))
            t3.start()
            t3.join()

    # t1.join()
    # t2.join()
    # t3.join()

    print("Done")

Однако я не понимаю, куда мне поместить метод join(). Хотя они оба получают одинаковый ответ, я думаю, между ними есть некоторые различия.

Если вы запускаете поток и сразу же присоединяетесь к нему, вы можете пропустить поток и просто выполнить операцию в обычном вызове функции, многопоточность не требуется, в основном будет тот же эффект.

luk2302 18.11.2022 09:30

Отвечает ли это на ваш вопрос? Какая польза от join() в многопоточности Python?

luk2302 18.11.2022 09:31

@ luk2302 luk2302 спасибо за ваш ответ, я все еще не понимаю этот метод после прочтения веб-сайта, означает ли это, что метод соединения не имеет смысла, соединение предназначено только для того, чтобы сделать код понятным?

4daJKong 18.11.2022 09:55
14 Задание: Типы данных и структуры данных Python для DevOps
14 Задание: Типы данных и структуры данных Python для DevOps
проверить тип данных используемой переменной, мы можем просто написать: your_variable=100
Python PyPDF2 - запись метаданных PDF
Python PyPDF2 - запись метаданных PDF
Python скрипт, который будет записывать метаданные в PDF файл, для этого мы будем использовать PDF ридер из библиотеки PyPDF2 . PyPDF2 - это...
Переменные, типы данных и операторы в Python
Переменные, типы данных и операторы в Python
В Python переменные используются как место для хранения значений. Пример переменной формы:
Почему Python - идеальный выбор для проекта AI и ML
Почему Python - идеальный выбор для проекта AI и ML
Блог, которым поделился Harikrishna Kundariya в нашем сообществе Developer Nation Community.
Как автоматически добавлять котировки в заголовки запросов с помощью PyCharm
Как автоматически добавлять котировки в заголовки запросов с помощью PyCharm
Как автоматически добавлять котировки в заголовки запросов с помощью PyCharm
Анализ продукта магазина на Tokopedia
Анализ продукта магазина на Tokopedia
Tokopedia - это место, где продавцы могут продавать свои товары. Товар должен быть размещен на витрине, чтобы покупателям было легче найти товар...
2
3
63
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

Если вы присоединяетесь сразу после запуска потока, это означает, что вы ждете, пока он выполнится. Однако это ничем не отличается от обычного вызова функции внутри основного потока. Предположим, что работа функций занимает немного времени, и вам нужно обрабатывать их одновременно. Затем вы можете запустить их и раскомментировать соединения. Это ваш текущий рабочий процесс фрагмента кода

->Create thread x and start
->wait for finish of thread x
->Create thread y and start
->wait for finish of thread y
... and so on.

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

->Create thread x and start
->Create thread y and start
->Create thread z and start
... 

at the end
->wait thread x to finish
->wait thread y to finish
...

Так что здесь, даже когда вы ждете завершения X, ваши другие потоки, такие как y и z, все еще обрабатывают то, что вы делаете внутри.

Обновлено: Вы должны удалить соединения сразу после начала и раскомментировать потоки, которые были в конце. Это было бы более уместно. Кроме того, поскольку процессоры достаточно быстры, чтобы выполнить простую математику всего за миллисекунду, вы не почувствуете никакой разницы.

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

Однако предположим, что у вас будет другой поток с именем X_2, который будет использовать результат потока X_1. Затем, прежде чем создавать поток X_2, вы должны присоединиться к потоку X_1.

еще раз спасибо, вы имели в виду, что нигде не нужно добавлять join? извините, я все еще в замешательстве, если my_squr выполняется долго, какой из них правильный?

4daJKong 18.11.2022 09:53

В вашей ситуации использование в конце было бы правильным

Mustafa KÜÇÜKDEMİRCİ 18.11.2022 09:58

@4daJKong, Re, "... нигде не нужно добавлять соединение?" t.join() — это то, как один поток может дождаться окончания другого потока. Если поток t что-то делает, и *ЕСЛИ* в каком-то другом потоке u есть точка, за которой u не следует продолжать, пока t не выполнит свою задачу, тогда поток u может вызвать t.join() в этой точке, и вызов соединения не вернется до тех пор, пока тред t сделал свое дело.

Solomon Slow 18.11.2022 15:29

@4daJKong, в вашем примере последнее, что делает ваш основной поток, это print("done"). Если вы не хотите, чтобы это произошло до тех пор, пока не будут выполнены другие три потока, вы можете убедиться, что основной поток join() все эти другие потоки, прежде чем он напечатает сообщение «Готово».

Solomon Slow 18.11.2022 15:29

Вы можете создать список потоков, а затем присоединиться к ним после завершения цикла:

import threading
def my_squr(num):   #if this function take long time to run
    print(num*num)
    return num*num

if __name__ == "__main__":
    threads = []
    l1 = [1,3,5,7,11,13,15,17]
    for i, item in enumerate(l1):
        if i % 3 == 0:
            t1 = threading.Thread(target=my_squr, args=(item,))
            t1.start()
            threads.append(t1)
        elif i % 3 == 1:
            t2 = threading.Thread(target=my_squr, args=(item,))
            t2.start()
            threads.append(t2)
        else:
            t3 = threading.Thread(target=my_squr, args=(item,))
            t3.start()
            threads.append(t3)

    for thread in threads:
        thread.join()

    print("Done")

спасибо за ваш ответ, основная проблема в том, что я не знаю, где я должен добавить join, в цикле или вне цикла, потому что они оба возвращают один и тот же результат, но я хочу использовать многопоточность

4daJKong 18.11.2022 10:08

Соединение в моем ответе находится вне цикла, т. Е. Это операция очистки. Мне интересно узнать, что будет делать ваша долговременная функция. Я надеюсь, что это не будет интенсивно использовать процессор, потому что если это так, многопоточность не будет хорошим вариантом.

Pingu 18.11.2022 10:11

Присоединение просто останавливает завершение приложения до завершения потока.
Итак, вы хотите присоединиться к темам ПОСЛЕ того, как они начались.

import threading
def my_squr(num):   #if this function take long time to run
    print(num*num)
    return num*num

if __name__ == "__main__":
    threads = list()
    l1 = [1,3,5,7,11,13,15,17]
    for i, item in enumerate(l1):
        if i % 3 == 0:
            t1 = threading.Thread(target=my_squr, args=(item,))
            threads.append(t1)
            t1.start()
        elif i % 3 == 1:
            t2 = threading.Thread(target=my_squr, args=(item,))
            threads.append(t2)
            t2.start()
        else:
            t3 = threading.Thread(target=my_squr, args=(item,))
            threads.append(t3)
            t3.start()

    for t in threads:
        t,join()

    print("Done")

спасибо за ваш ответ, основная проблема в том, что я не знаю, где я должен добавить join, в цикле или вне цикла, потому что они оба возвращают один и тот же результат, но я хочу использовать многопоточность

4daJKong 18.11.2022 10:08

Re, «присоединиться... останавливает приложение». Это вводящее в заблуждение утверждение. t.join() ждет окончания треда t. Если вам случится вызвать t.join() из какого-то потока, который вы считаете «приложением», то конечно, присоединение остановит приложение. Но любой поток может присоединиться к любому другому потоку. Самое простое объяснение того, что делает соединение, — это объяснение того, как оно ведет себя в любой ситуации. t.join() ничего не делает. Он продолжает ничего не делать, пока поток t не завершится, а затем возвращается.

Solomon Slow 18.11.2022 15:22

Без join ваше приложение завершилось бы до завершения потоков.... таким образом, join ОСТАНАВЛИВАЕТ ваше приложение от продолжения. Если вы не запустили другой поток ДО того, как вы присоединились, другой поток не может начаться. Мое решение правильное, потому что я join ПОСЛЕ того, как все темы запущены.

eatmeimadanish 22.11.2022 04:38

Другие вопросы по теме