Как сначала выполнить поток из функции, а затем из другой?

#python

#python

Вопрос:

@chepner

Вот как я изначально это делал:

 class Cub:
    def __init__(self, lenght, width, height):
        self.lenght = lenght
        self.width = width
        self.height = height

    def volume(self):
        return self.lenght * self.width * self.height
        

    def calclenght(self):
        return ((self.lenght * 12))

    


def main():
    cub = Cub(3, 4, 5)
    print("Volume = ", cub.volume())
    print("Total lenght = ", cub.calclenght())


if __name__=="__main__":
    main()
 

результаты: объем = 60, длина = 36. Это задача, которую я должен выполнить:

Создайте класс, который будет использоваться для создания экземпляров объектов в форме куба. Определите метод для вычисления объема куба и другой метод для вычисления общей длины всех сторон куба.

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

Создайте два объекта, над которыми будет вызываться каждый из созданных методов.

Отобразите результаты этих методов с помощью команды print .

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

1.Вы не можете повторно использовать имена методов таким образом. Переопределение volume заменяет исходное определение.

2. В любом случае, неясно, какова цель потоков здесь.

3. @chepner я опубликовал задачу, которая у меня есть.

4. Что вы подразумеваете под «размещением этих методов в потоках»? И что вы подразумеваете под «основным проводом»?

5. @Code-Методы ученика — две функции, основной провод — основной поток.

Ответ №1:

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

На самом деле я не уверен, хочет ли задача, чтобы вы печатали результаты в функции объекта напрямую или как часть основной программы. Последнее — это то, что я сделал здесь, хотя прямое присвоение изменяемому объекту — это не то, что вы на самом деле хотели бы сделать (однако в данном случае это не имеет значения). Если это то, что ожидалось, вместо этого используйте очередь потоков, которая позволяет напрямую получать возвращаемые значения потоков безопасным способом.

 import threading

# thread outputs are done by passing in a mutable object to the thread's run function
#   this is not the best way
#   generally, if you have to use threads, you don't expect them to return anything
#   the proper way to do this would be to use python's queue, which I haven't done here

class cuboid:
    x: float
    y: float
    z: float

    def __init__(
        self,
        x: float,
        y: float,
        z: float
    ):
        self.x = x
        self.y = y
        self.z = z

    # output is a mutable object; as an argument these are basically like pointers, they're not copies of objects
    #   this is *not* thread safe, though this isn't a problem in this case as we're joining the threads anyway
    def getVolume(
        self,
        output,
        index: int
    ) -> None:
        output[index] = self.x * self.y * self.z

    # same thing here
    def getSideLength(
        self,
        output,
        index: int
    ) -> None:
        # the total side length of a cuboid (not a cube!) is calculated differently
        output[index] = self.x * 4   self.y * 4   self.z * 4

# sizes to use as initialization parameters for the 2 cuboid objects
sizes = [
    [
        1,
        2,
        3
    ],
    [
        4,
        5,
        6
    ]
]

# mutable object to use as output
#   output[index of cuboid][0 = volume, 1 = length]
#   (could also use a dict for this to make it easier to understand)
output = []

# iterate through initialization sizes
for i in range(
    0,
    len(sizes)
):
    # populate the output list
    output.append(
        [None, None]
    )

    # instantiate cuboid
    cuboi = cuboid(
        *sizes[i]
    )
    
    # create threads
    #   notice the passed in args
    thread1 = threading.Thread(
        target=cuboi.getVolume,
        args=(
            # mutable sub-list
            output[i], 
            # index to assign to of sub-list (effectively output[i][0])
            0
        )
    )
    # same thing here
    thread2 = threading.Thread(
        target=cuboi.getSideLength,
        args=(
            output[i], 
            1
        )
    )

    # start and join the threads
    #   joining a thread blocks the thread which calls .join(), which is the main thread in this case, until it finishes
    thread2.start()
    thread2.join()

    # same thing here
    thread1.start()
    thread1.join()

    # print value of output
    print(
        "Volume of Cuboid #%s: %s" % (i, output[i][0])
    )
    print(
        "Length of Cuboid #%s: %s" % (i, output[i][1])
    )
 

Который будет выводить:

 Volume of Cuboid #0: 6
Length of Cuboid #0: 24
Volume of Cuboid #1: 120
Length of Cuboid #1: 60