Threading Gives No Output in Python 3.6 - python

Here's my code:
import _thread
import time
def print_time(name, delay):
count=1
while count<=5:
time.delay(delay)
print ("Thread %s Time is %s"%(count, time.ctime(time.time())))
count = count+1
_thread.start_new_thread(print_time,("T-1",2))
_thread.start_new_thread(print_time,("T-2",4))
The output should be various lines telling the current time. But after running the program I got no output and no error. Why is this happening? I use Python 3.6.

Probably the first question is why you're using _thread. I am guessing your issue is that your main thread finishes before print_time manages to produce any output, and on this particular system, that exits the whole program.
From the section Caveats in the _thread documentation:
When the main thread exits, it is system defined whether the other threads survive. On most systems, they are killed without executing try … finally clauses or executing object destructors.
When using threading instead, you get to choose whether to await threads with the daemon argument.

The above answers are always the better options but if you still insist on doing with _thread module just delay the main thread by adding time.sleep(1) at the end of the code

Use threading:
import threading
import time
def print_time(name, delay):
count=1
while count<=5:
time.sleep(delay)
print ("Thread %s Time is %s"%(count, time.ctime(time.time())))
count = count+1
t1 = threading.Thread(target=print_time, args=("T-1",2))
t2 = threading.Thread(target=print_time, args=("T-2",4))
t1.start()
t2.start()
The threading module provides an easier to use and higher-level threading API built on top of this [_thread] module.

Related

How to allow a user a specified amount of time on a python program

Im pretty independent when using oython since i wouldnt consider myself a beginner etc, but Iv been coding up a program that I want to sell. The problem is that I want the program to have a timer on it and when it runs out the program will no longer work. Giving the user a specified amount of time they have to use the program.
You will want to run your program from another program using multithreading or asynchronous stuff. If you are looking for a single thing to send to your program (here, an interruption signal), then you should take a look at the signal built in package (for CPython).
(based on this answer from another post)
If you're calling external script using subprocess.Popen, you can just .kill() it after some time.
from subprocess import Popen
from time import sleep
with Popen(["python3", script_path]) as proc:
sleep(1.0)
proc.kill()
Reading documentation helps sometimes.
One way this can be done by interrupting the main thread
from time import sleep
from threading import Thread
from _thread import interrupt_main
import sys
TIME_TO_WAIT = 10
def kill_main(time):
sleep(time)
interrupt_main()
thread = Thread(target=kill_main, args=(TIME_TO_WAIT,))
thread.start()
try:
while True:
print('Main code is running')
sleep(0.5)
except KeyboardInterrupt: print('Time is up!')
sys.exit()

Python Thread Hangs

Seems anytime I try to start a background thread, you never reach code beneath it until the thread finishes. This is Python 3.6.5
I had this problem with a more complicated app, but it doesn't appear to be related to multiprocessing or subprocesses.
The following code never prints 'FG works':
import sys
import time
import threading
def bgthread():
while True:
print('BG works')
sys.stdout.flush()
time.sleep(1)
threading.Thread(bgthread()).start()
while True:
print('FG works')
sys.stdout.flush()
time.sleep(1)
If anyone sees my obvious mistake, please chime in.
You do not want to call the function when starting the new thread, as this will block the main thread. You should do,
threading.Thread(target=bgthread).start()
This is because the call to the Thread initializer is invoking bgthread instead of referring to it in order to start later.

Python multithreaded print statements delayed until all threads complete execution

I have a piece of code below that creates a few threads to perform a task, which works perfectly well on its own. However I'm struggling to understand why the print statements I call in my function do not execute until all threads complete and the print 'finished' statement is called. I would expect them to be called as the thread executes. Is there any simple way to accomplish this, and why does this work this way in the first place?
def func(param):
time.sleep(.25)
print param*2
if __name__ == '__main__':
print 'starting execution'
launchTime = time.clock()
params = range(10)
pool=multiprocessing.Pool(processes=100) #use N processes to download the data
_=pool.map(func,params)
print 'finished'
For python 3 you can now use the flush param like that:
print('Your text', flush=True)
This happens due to stdout buffering. You still can flush the buffers:
import sys
print 'starting'
sys.stdout.flush()
You can find more info on this issue here and here.
Having run into plenty of issues around this and garbled outputs (especially under Windows when adding colours to the output..), my solution has been to have an exclusive printing thread which consumes a queue
If this still doesn't work, also add flush=True to your print statement(s) as suggested by #Or Duan
Further, you may find the "most correct", but a heavy-handed approach to displaying messages with threading is to use the logging library which can wrap a queue (and write to many places asynchronously, including stdout) or write to a system-level queue (outside Python; availability depends greatly on OS support)
import threading
from queue import Queue
def display_worker(display_queue):
while True:
line = display_queue.get()
if line is None: # simple termination logic, other sentinels can be used
break
print(line, flush=True) # remove flush if slow or using Python2
def some_other_worker(display_queue, other_args):
# NOTE accepts queue reference as an argument, though it could be a global
display_queue.put("something which should be printed from this thread")
def main():
display_queue = Queue() # synchronizes console output
screen_printing_thread = threading.Thread(
target=display_worker,
args=(display_queue,),
)
screen_printing_thread.start()
### other logic ###
display_queue.put(None) # end screen_printing_thread
screen_printing_thread.stop()

Problems mixing threads/processes in python [duplicate]

I have a piece of code below that creates a few threads to perform a task, which works perfectly well on its own. However I'm struggling to understand why the print statements I call in my function do not execute until all threads complete and the print 'finished' statement is called. I would expect them to be called as the thread executes. Is there any simple way to accomplish this, and why does this work this way in the first place?
def func(param):
time.sleep(.25)
print param*2
if __name__ == '__main__':
print 'starting execution'
launchTime = time.clock()
params = range(10)
pool=multiprocessing.Pool(processes=100) #use N processes to download the data
_=pool.map(func,params)
print 'finished'
For python 3 you can now use the flush param like that:
print('Your text', flush=True)
This happens due to stdout buffering. You still can flush the buffers:
import sys
print 'starting'
sys.stdout.flush()
You can find more info on this issue here and here.
Having run into plenty of issues around this and garbled outputs (especially under Windows when adding colours to the output..), my solution has been to have an exclusive printing thread which consumes a queue
If this still doesn't work, also add flush=True to your print statement(s) as suggested by #Or Duan
Further, you may find the "most correct", but a heavy-handed approach to displaying messages with threading is to use the logging library which can wrap a queue (and write to many places asynchronously, including stdout) or write to a system-level queue (outside Python; availability depends greatly on OS support)
import threading
from queue import Queue
def display_worker(display_queue):
while True:
line = display_queue.get()
if line is None: # simple termination logic, other sentinels can be used
break
print(line, flush=True) # remove flush if slow or using Python2
def some_other_worker(display_queue, other_args):
# NOTE accepts queue reference as an argument, though it could be a global
display_queue.put("something which should be printed from this thread")
def main():
display_queue = Queue() # synchronizes console output
screen_printing_thread = threading.Thread(
target=display_worker,
args=(display_queue,),
)
screen_printing_thread.start()
### other logic ###
display_queue.put(None) # end screen_printing_thread
screen_printing_thread.stop()

Python: run one function until another function finishes

I have two functions, draw_ascii_spinner and findCluster(companyid).
I would like to:
Run findCluster(companyid) in the backround and while its processing....
Run draw_ascii_spinner until findCluster(companyid) finishes
How do I begin to try to solve for this (Python 2.7)?
Use threads:
import threading, time
def wrapper(func, args, res):
res.append(func(*args))
res = []
t = threading.Thread(target=wrapper, args=(findcluster, (companyid,), res))
t.start()
while t.is_alive():
# print next iteration of ASCII spinner
t.join(0.2)
print res[0]
You can use multiprocessing. Or, if findCluster(companyid) has sensible stopping points, you can turn it into a generator along with draw_ascii_spinner, to do something like this:
for tick in findCluster(companyid):
ascii_spinner.next()
Generally, you will use Threads. Here is a simplistic approach which assumes, that there are only two threads: 1) the main thread executing a task, 2) the spinner thread:
#!/usr/bin/env python
import time
import thread
def spinner():
while True:
print '.'
time.sleep(1)
def task():
time.sleep(5)
if __name__ == '__main__':
thread.start_new_thread(spinner, ())
# as soon as task finishes (and so the program)
# spinner will be gone as well
task()
This can be done with threads. FindCluster runs in a separate thread and when done, it can simply signal another thread that is polling for a reply.
You'll want to do some research on threading, the general form is going to be this
Create a new thread for findCluster and create some way for the program to know the method is running - simplest in Python is just a global boolean
Run draw_ascii_spinner in a while loop conditioned on whether it is still running, you'll probably want to have this thread sleep for a short period of time between iterations
Here's a short tutorial in Python - http://linuxgazette.net/107/pai.html
Run findCluster() in a thread (the Threading module makes this very easy), and then draw_ascii_spinner until some condition is met.
Instead of using sleep() to set the pace of the spinner, you can wait on the thread's wait() with a timeout.
It is possible to have a working example? I am new in Python. I have 6 tasks to run in one python program. These 6 tasks should work in coordinations, meaning that one should start when another finishes. I saw the answers , but I couldn't adopted the codes you shared to my program.
I used "time.sleep" but I know that it is not good because I cannot know how much time it takes each time.
# Sending commands
for i in range(0,len(cmdList)): # port Sending commands
cmd = cmdList[i]
cmdFull = convert(cmd)
port.write(cmd.encode('ascii'))
# s = port.read(10)
print(cmd)
# Terminate the command + close serial port
port.write(cmdFull.encode('ascii'))
print('Termination')
port.close()
# time.sleep(1*60)

Categories

Resources