0

I am trying to understand multithreading in python, but every examples I read are very simple and similar to each other and don't serve my purpose.

I am performing high mathematics computation tasks so I need to use python mulithreading. I need to use multithreading NOT multiprocessing to avoid memory issues.

Below you will find a simple math problem that I wanna perform multithreading (Not an actual one, but let me understand threading). So i need to run task#1 (square) and task#2 (inve) in-parallel at the same time at two different threads (wait the results from the two), and then use the results from the two to obtain final result back in the main thread.

Please use any threading options in python (Thread, ThreadPool, ThreadPoolExecutor) anything you prefer, and really save time and cost comparing to serial code

If any one has better idea to make this code run faster, please share it

import scipy
import numpy


def square(A):
    # take the square root of a matix
    y = scipy.linalg.sqrtm(A)
    return y

def inve(A):
    # take the inverse of a matrix
    y = numpy.linalg.inv(A)

def main(A):
    # A is a matrix
    # a is the square root of a matrix
    # b is the inverse of a matix

    # Run the first task on one thread
    a = square(A)
    # Run the second task in-parallel in another thread
    b = inve(A)

    # and then run final result in main thread
    result = a * b

    return result

A=[[1,2],[3,4]]
result = main(A)
Zidan
  • 95
  • 1
  • 12
  • Are there any issues you face while implementing multithreading, with which we can help with? – Rahul May 28 '19 at 13:07
  • Thank you for your respond. Yes, I can't fully understand how we do threading for similar example. for example if I use threading.Thread, I don't know how get an output and wait for it. So, if you can help me and rewrite this code using multithreading as i explained above. I really appreciate you if you do this. As i explained, I need to run the two tasks in parallel and then wait for the output, and then use both out put to obtain final result – Zidan May 28 '19 at 13:16
  • Since you don't have the basics of threading, you can go here https://realpython.com/intro-to-python-threading/ or here https://www.geeksforgeeks.org/multithreading-python-set-1/ or here https://pythonprogramming.net/threading-tutorial-python/. You can get answers here but they won't be full fledged as these tutorials provided by these websites. – Rahul May 28 '19 at 13:29
  • 1
    CPU bound tasks will not benefit from multithreading in Python unless you use Jython or IronPython. CPython's memory management is not thread safe, so it uses a [Global Interpreter Lock](https://docs.python.org/3/glossary.html#term-global-interpreter-lock), that a thread must acquire before it can access Python objects. Only one thread can execute bytecode at any given time. Threads in CPython are better suited for I/O bound tasks. CPU bound tasks should be done via multiprocessing if parallelization is desired – shmee May 28 '19 at 13:50
  • OMG, I am feeling lost. Can you please show me in any way you prefer, how would you solve this problem to make it more efficient and take less time. Please rewrite this simple problem using any library you prefer, and then I can read more onto this library and see how it work. I would appreciate if you rewrite it for me. Thanks – Zidan May 28 '19 at 13:57

1 Answers1

0

Here is how you can perform multithreading:

import threading
from scipy import linalg
import numpy

x=1
y=1
def square(A):
    global x
    # take the square root of a matix
    x = linalg.sqrtm(A)

def inve(A):
    global y
    y = numpy.linalg.inv(A)

def main(A):
    # creating thread 
    t1 = threading.Thread(target=square, args=(A,)) 
    t2 = threading.Thread(target=inve, args=(A,)) 

    # starting thread 1 
    t1.start() 
    # starting thread 2 
    t2.start() 

    # wait until thread 1 is completely executed 
    t1.join() 
    # wait until thread 2 is completely executed 
    t2.join() 


if __name__ == "__main__":
    A = [[1,2],[3,4]]
    main(A)
    result = x*y
    print(result)
Anubhav Singh
  • 8,321
  • 4
  • 25
  • 43
  • Dear, Thank you very much. It really helps. However, I have changed it and run it, but it didn't optimize the time the time is higher than serial code. No threading (10.85), with threading (11.3) – Zidan May 28 '19 at 13:37
  • How come with threading takes longer time than serial code?? can you please answer me! – Zidan May 28 '19 at 13:41
  • check this out: https://stackoverflow.com/questions/11798639/multithreading-takes-more-time-than-sequential-execution-in-c-sharp – Anubhav Singh May 28 '19 at 13:43
  • @Zidan, see Shmee's comment on your question. It talks about the limits imposed by C-Python's [Global Interpreter Lock](https://docs.python.org/3/glossary.html#term-global-interpreter-lock) (a.k.a., "the GIL.") – Solomon Slow May 28 '19 at 13:57
  • Thanks Solomon, I read it and understand, but still don't how solve this problem and make computation faster by any mean and any kind of library. Can you tell me how you solve this problem to make your code faster using any kind of library you prefer. Please rewrite the code for me. Thanks – Zidan May 28 '19 at 14:00
  • @Zidan, check this if you want the computation faster but then you would need multiprocessing, not multithreading. https://eli.thegreenplace.net/2012/01/16/python-parallelizing-cpu-bound-tasks-with-multiprocessing – Anubhav Singh May 28 '19 at 14:10