[ERROR]: Issue with threading.Thread() while executing multithreading script with Python3

13,386

Solution 1

I will use content from the first answer and I will say that:

  • What is the tuple and what is its role: a tuple is similar to a list. The difference between the two is that we cannot change the elements of a tuple once it is assigned whereas in a list, elements can be changed.
  • Advantages of tuple: 1) We generally use tuple for heterogeneous (different) data-types and list for homogeneous (similar) data-types, 2) Since tuple are immutable, iterating through tuple is faster than with list. So there is a slight performance boost, 3) Tuples that contain immutable elements can be used as key for a dictionary. With list, this is not possible, 4) If you have data that doesn't change, implementing it as tuple will guarantee that it remains write-protected

So from what I can see, you do not have issues with understanding the multi-threading logic, but you could not see the reason of tuple inside the code. Now I think it's clear. Of course the solution from the 1st answer is the proper one. A comma is enough to declare that you want to pass nothing in this function:

thread_01 = threading.Thread(target=calculate_the_square, args=(array,))
thread_02 = threading.Thread(target=calculate_the_cube, args=(array,))

I saw the link of the resources of the first answer. I would also tell you to take a look here. I think it's more useful and easy to understand the big picture.

Bye!

Solution 2

The args parameter has to be a tuple. You need to change

thread_01 = threading.Thread(target=calculate_the_square, args=(array))
thread_02 = threading.Thread(target=calculate_the_cube, args=(array))

into

thread_01 = threading.Thread(target=calculate_the_square, args=(array,))
thread_02 = threading.Thread(target=calculate_the_cube, args=(array,))

You can check it out by typing into an interpreter:

type((1))
type((1,))

Output:

<class 'int'>
<class 'tuple'>
Share:
13,386
dpapadopoulos
Author by

dpapadopoulos

Updated on June 29, 2022

Comments

  • dpapadopoulos
    dpapadopoulos almost 2 years

    The below sample of code is a small script that I am trying to create. In this script, there are two functions. The calculate_the_square(takes_the_given_array) and the calculate_the_cube(takes_the_given_array).

    I created two threads, threa_01 and thread_02, and I told them to execute the function that I want to. In the args variable, I send the array that I want to send in order to be calculated (args=array). In the target variable, I send the name of the function where the specific thread I want to run in it (target=calculate_the_square or target=calculate_the_cube). Then I start the execution of the threads and I also make them be joined.

    Unfortunately, when I execute it I face the following issue:

    ISSUE

    Exception in thread Thread-1:
    Traceback (most recent call last):
      File "C:\Program Files (x86)\Python37-32\lib\threading.py", line 917, in _bootstrap_inner
        self.run()
      File "C:\Program Files (x86)\Python37-32\lib\threading.py", line 865, in run
        self._target(*self._args, **self._kwargs)
    TypeError: calculate_the_square() takes 1 positional argument but 6 were given
    
    Exception in thread Thread-2:
    Traceback (most recent call last):
      File "C:\Program Files (x86)\Python37-32\lib\threading.py", line 917, in _bootstrap_inner
        self.run()
      File "C:\Program Files (x86)\Python37-32\lib\threading.py", line 865, in run
        self._target(*self._args, **self._kwargs)
    TypeError: calculate_the_cube() takes 1 positional argument but 6 were given
    
    
    Process finished with exit code 0
    

    WANTED OUTPUT (it has to be mixed but I wrote the generic result and not the multithreaded)

    Cube result:  5832
    Cube result:  778688
    Cube result:  2000376
    Cube result: 281011375 
    Cube result:  967361669
    Cube result:  1006012008
    Square result:  324 
    Square result:  8464
    Square result:  15876
    Square result:  429025
    Square result:  978121
    Square result:  1004004
    The program finished in : ...... SOME TIME
    

    CODE SAMPLE

    import time
    import threading
    
    def calculate_the_square(variables):
    
        for var in variables:
            time.sleep(0.5)     # Insert a sleep just to count the time that needs to be completed
            print("Square result: ", var*var)
    
    def calculate_the_cube(variables):
        time.sleep(0.5)     # Insert a sleep just to count the time that needs to be completed
        for var in variables:
            print("Cube result: ", var*var*var)
    
    
    keeping_time = time.time()              # Keeping the starting time
    array = [18, 92, 126, 655, 989, 1002]  # Random given numbers.
    
    
    
    thread_01 = threading.Thread(target=calculate_the_square, args=(array))     # Creating threadh No1 and the target make this thread to focus on this function, sending the value that is saved in tha variable args.
    thread_02 = threading.Thread(target=calculate_the_cube, args=(array))       # Creating threadh No2 and the target make this thread to focus on this function, sending the value that is saved in tha variable args.
    
    
    thread_01.start()   # Starting the thread 1
    thread_02.start()   # Starting the thread 2
    
    thread_01.join() # Waits until the first thread is finished. Better switching between the threads. Maybe not now (only 2 threads) but if we had 10 and more it would be helpful.
    thread_02.join()
    
    print("The program finished in :", time.time()-keeping_time)
    

    Can you please help me with this issue? What am I doing wrong?

    Thank you for your time in advance!

  • dpapadopoulos
    dpapadopoulos about 5 years
    What does tuple represents?
  • kgorak
    kgorak about 5 years
    Tuple is like an unmodifiable list, you can read more about it here. In this context it represents function parameters. If your calculate_the_square accepted an array and a string, you will need to set args to args=(variables, "example string") and the function declaration will be def calculate_the_square(variables, str):.
  • dpapadopoulos
    dpapadopoulos about 5 years
    Wow. Your answer indeed is much more detailed. From what I can see, that's true. I had issues with the tuple and not with the multithreading. I think that logically your answer was better. Thanks again for your time!