I am trying to implement a multi-threading program which finds out prime numbers over multiple threads and aggregates their result.
I am using a queue to actually store the returned values. but when I print the values of queue only the address of the function is printed
n = int(input("Enter the value:"))
def task1():
global n
print("Task 1 assigned to thread: {}".format(threading.current_thread().name))
print("ID of process running task 1: {}".format(os.getpid()))
a=[]
for i in range(2,n//2):
c=0
for j in range(2,i+1):
if(i%j==0):
c+=1
if(c<=1):
a.append(i)
return a
def task2():
global n
print("Task 2 assigned to thread: {}".format(threading.current_thread().name))
print("ID of process running task 2: {}".format(os.getpid()))
a=[]
for i in range(n//2+1,n):
c=0
for j in range(2,i+1):
if(i%j==0):
c+=1
if(c<=1):
a.append(i)
return a
import queue
que=queue.Queue()
t1 = threading.Thread(target=lambda q: q.put(task1), args=(que,), name='t1')
t2 = threading.Thread(target=lambda q: q.put(task2), args=(que,), name='t2')
# starting threads Spawn
t1.start()
t2.start()
# wait until all threads finish Sync
t1.join()
t2.join()
while not que.empty():
result=que.get()
print(result)
after running the code, this is the value I am getting
<function task1 at 0x00000204A9A11438>
<function task2 at 0x00000204A9A11288>
I need to print the array of prime numbers instead of the address.
target
is the function to run in the thread. What you've made the thread do (and only do) is add a function reference to the queue. Your task are not run.
Fixes:
global n
isn't needed. It's only needed if you want to reassign n
.You'll also find that this likely runs slower than simply computing primes in one non-parallel task. Python processes are restricted by the global interpreter lock (GIL) to run Python code in only one thread at a time, so the threads are serialized if they run CPU-bound work, which this is.
Threads are ideal for parallelizing I/O bound work. Use processes via the multiprocessing
module to run CPU-bound tasks, but note that the overhead of creating processes and the inter-process communication to send parameters and results back to the main process can overwhelm simple CPU-bound operations like this, unless they run for a significant period of time.
import threading
import os
import queue
n = int(input("Enter the value:"))
lock = threading.Lock()
que = queue.Queue()
def task1():
with lock:
print("Task 1 assigned to thread: {}".format(threading.current_thread().name))
print("ID of process running task 1: {}".format(os.getpid()))
a=[]
for i in range(2,n//2):
c=0
for j in range(2,i+1):
if(i%j==0):
c+=1
if(c<=1):
a.append(i)
que.put(a)
def task2():
with lock:
print("Task 2 assigned to thread: {}".format(threading.current_thread().name))
print("ID of process running task 2: {}".format(os.getpid()))
a=[]
for i in range(n//2+1,n):
c=0
for j in range(2,i+1):
if(i%j==0):
c+=1
if(c<=1):
a.append(i)
que.put(a)
t1 = threading.Thread(target=task1, name='t1')
t2 = threading.Thread(target=task2, name='t2')
# starting threads Spawn
t1.start()
t2.start()
# wait until all threads finish Sync
t1.join()
t2.join()
while not que.empty():
result=que.get()
print(result)
Output:
Enter the value: 100
Task 1 assigned to thread: t1
ID of process running task 1: 3864
Task 2 assigned to thread: t2
ID of process running task 2: 3864
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47]
[53, 59, 61, 67, 71, 73, 79, 83, 89, 97]