[Tutor] Fwd: Concept of multithreading

Dennis Lee Bieber wlfraed at ix.netcom.com
Mon Aug 23 16:59:31 EDT 2021


On Mon, 23 Aug 2021 17:14:29 +0530, Manprit Singh
<manpritsinghece at gmail.com> declaimed the following:

>Dear Sir ,
>
>Just need to know if the below written example can be taken as an
>introduction level example of multithreading or not ?
>import time
>import threading
>
>def sumoflist(seq):
>    sum_no = 0
>    for num in seq:
>        sum_no += num
>    time.sleep(6)
>    print("Sum of list",sum_no)
>
>def sumoftuple(seq):
>    sum_no = 0
>    for num in seq:
>        sum_no += num
>    time.sleep(3)
>    print("Sum of tuple",sum_no)
>

	First comment -- other than the sleep duration, and the print message,
these are identical. It would be better to just define one function and
pass the duration/type to it (actually, I'd want to REMOVE the print
messages from the function, and have that returned to the parent -- which,
for threads, would likely mean using a Queue structure).

	It's also inefficient, since Python HAS a sum() function that likely
operates at the assembly language level, rather than looping at Python's
interpreted level.


>t1 = threading.Thread(target=sumoflist, args=([1, 2, 3],))
>t2 = threading.Thread(target=sumoftuple, args=((2, 4, 3),))
>t1.start()
>t2.start()
>t1.join()
>t2.join()
>
>It takes around 6 seconds to complete the task, in this approach the

	How do you /really/ know -- there is no timing logic in your example.
Granted, one can conclude that by simple analysis of the logic.

	Note that t1.start() could result in swapping to the t1 thread, and it
could execute the entire summation loop, then get to the sleep(), and only
then does t2 get started. It could then run the entire summation loop
before suspending on the sleep(). Given the values, it will likely complete
its sleep() call before t1 does -- so the entire duration is controlled by
t1's sleep(). Your sleep() calls overwhelm any processing, so you could
just remove the summation loop and print statements and get the same
result.

	For an example which illustrates threads actually doing "work", along
with I/O blocking, study... Watch how the first 10 "." are output, then
pauses as the queue is full.

-=-=-=-
import threading
import queue
import random
import time

inQueue = queue.Queue(10)
#limit input queue, otherwise main thread could put ALL inputs on queue
#before any thread even runs

outQueue = queue.Queue()

DONE = object()
NUMWORKERS = 3
NUMVALUES = 250     #with average sleep of 1.0 second, will take 4 minutes
to complete

def worker(id, inQ, outQ):
    sumv = 0
    numv = 0
    startPC = time.perf_counter()
    startPT = time.process_time()
    while True:
        vlu = inQ.get()
        if vlu == DONE: break
        sumv += vlu[0]
        numv += 1
        time.sleep(vlu[1])
    inQ.put(vlu)    #propagate the DONE flag to next
    outQ.put((id, sumv, numv, time.perf_counter() - startPC))

start = time.perf_counter()
threads = [threading.Thread(target=worker, args=(i, inQueue, outQueue)) for
i in range(NUMWORKERS)]

for t in threads:
    t.start()

for _ in range(NUMVALUES):
    v = random.randint(1, NUMVALUES // 2)
    s = random.random() * 2.0
    inQueue.put((v, s))     #will block if 10 items are in the queue,
letting thread(s) run
    print(". ", end="", flush=True)  #progress indicator

print("\n\n")

inQueue.put(DONE)

for t in threads:
    t.join()

for _ in range(NUMWORKERS):
    id, sm, nm, dur = outQueue.get()
    print("Worker: %s\tSum: %s\tNumber Values: %s\tTime: %s"
          % (id, sm, nm, dur))

print("Total time: %s" % (time.perf_counter() - start))
-=-=-=-
C:\Users\Wulfraed\Documents\_Hg-Repositories\Python Progs>Q_Threads.py
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . .


Worker: 2       Sum: 5136       Number Values: 82       Time: 75.9186911
Worker: 1       Sum: 5349       Number Values: 84       Time: 76.3049776
Worker: 0       Sum: 5424       Number Values: 84       Time: 76.3747903
Total time: 76.3832255

C:\Users\Wulfraed\Documents\_Hg-Repositories\Python Progs>

	Note that the time output is wall-clock durations, and mostly counts
the time spent sleeping (or for main thread, blocked trying to queue the
next value).


-- 
	Wulfraed                 Dennis Lee Bieber         AF6VN
	wlfraed at ix.netcom.com    http://wlfraed.microdiversity.freeddns.org/



More information about the Tutor mailing list