Alex
Alex

Reputation: 873

Python parallel threads

Here the code which download 3 files, and do something with it. But before starting Thread2 it waits until Thread1 will be finished. How make them run together? Specify some examples with commentary. Thanks

import threading
import urllib.request


def testForThread1():
    print('[Thread1]::Started')
    resp = urllib.request.urlopen('http://192.168.85.16/SOME_FILE')
    data = resp.read()
    # Do something with it
    return 'ok'


def testForThread2():
    print('[Thread2]::Started')
    resp = urllib.request.urlopen('http://192.168.85.10/SOME_FILE')
    data = resp.read()
    # Do something with it
    return 'ok'


if __name__ == "__main__":
    t1 = threading.Thread(name="Hello1", target=testForThread1())
    t1.start()
    t2 = threading.Thread(name="Hello2", target=testForThread2())
    t2.start()
    print(threading.enumerate())
    t1.join()
    t2.join()
    exit(0)

Upvotes: 8

Views: 33381

Answers (3)

jinglebird
jinglebird

Reputation: 578

To make Thread1 and Thread2 run together, you need to ensure that both threads are started without waiting for each other to finish

In your code,functions for the threads are called immediately (target=testForThread1()) instead of being passed as references (target=testForThread1). This causes the functions to execute before the threads are started, That is not you want that

Check bellow code, I think you can run this as parralel thread:

import threading
import urllib.request

def testForThread1():
    //

def testForThread2():
    //

if __name__ == "__main__":
    # Create thread objects with the target functions
    t1 = threading.Thread(name="Hello1", target=testForThread1)
    t2 = threading.Thread(name="Hello2", target=testForThread2)
    
    # Start both threads
    t1.start()
    t2.start()
    
    # List all threads currently running
    print(threading.enumerate())
    
    # Wait for both threads to complete
    t1.join()
    t2.join()
    
    exit(0)

Upvotes: 0

user7159290
user7159290

Reputation:

For this, we can use threading but it's not efficient since you want to download files. so the total time will be equal to the sum of download time of all files. If you have good internet speed, then multiprocessing is the best way.

import multiprocessing


def test_function():
    for i in range(199999998):
        pass
    
    
t1 = multiprocessing.Process(target=test_function)
t2 = multiprocessing.Process(target=test_function)
t1.start()
t2.start()

This is the fastest solution. You can check this using following command:

time python3 filename.py

you will get the following output like this:

real    0m6.183s
user    0m12.277s
sys     0m0.009s

here, real = user + sys

user time is the time taken by python file to execute. but you can see that above formula doesn't satisfy because each function takes approx 6.14. But due to multiprocessing, both take 6.18 seconds and reduced total time by multiprocessing in parallel.

You can get more about it from here.

Upvotes: 3

Nisan.H
Nisan.H

Reputation: 6352

You are executing the target function for the thread in the thread instance creation.

if __name__ == "__main__":
    t1 = threading.Thread(name="Hello1", target=testForThread1()) # <<-- here
    t1.start()

This is equivalent to:

if __name__ == "__main__":
    result = testForThread1() # == 'ok', this is the blocking execution
    t1 = threading.Thread(name="Hello1", target=result) 
    t1.start()

It's Thread.start()'s job to execute that function and store its result somewhere for you to reclaim. As you can see, the previous format was executing the blocking function in the main thread, preventing you from being able to parallelize (e.g. it would have to finish that function execution before getting to the line where it calls the second function).

The proper way to set the thread in a non-blocking fashion would be:

if __name__ == "__main__":
    t1 = threading.Thread(name="Hello1", target=testForThread1) # tell thread what the target function is
    # notice no function call braces for the function "testForThread1"
    t1.start() # tell the thread to execute the target function

Upvotes: 10

Related Questions