Reputation: 152
import time
import thread
import termios
import sys
import datetime
try:
from msvcrt import getch # try to import Windows version
except ImportError:
def getch(): # define non-Windows version
import tty, termios
fd = sys.stdin.fileno()
old_settings = termios.tcgetattr(fd)
try:
tty.setraw(sys.stdin.fileno())
ch = sys.stdin.read(1)
finally:
termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
return ch
def tm():
char = None
def keypress():
count=0
while count<5:
a=time.time()
global char
char = getch()
b=time.time()
c=b-a
c=c*10000000000000000
c=int (c)
c=c%1000
print c
count+=1
thread.start_new_thread(keypress, ())
while True:
'''if char is not None:
print("Key pressed is " + char.decode('utf-8'))
break'''
print("Program is running")
time.sleep(5)
thread.start_new_thread(tm ())
when I run the code as shown above, it happily does what it's meant to do, which is measure the time in between keystrokes and give the 3 least significant numbers in the measurement.
However, when I take out this part (because I don't need nor necessarily want it there):
while True:
'''if char is not None:
print("Key pressed is " + char.decode('utf-8'))
break'''
print("Program is running")
time.sleep(5)
It breaks. I get the following error code:
Traceback (most recent call last):
File "randgen.py", line 50, in <module>
thread.start_new_thread(tm ())
TypeError: start_new_thread expected at least 2 arguments, got 1
Update
when I add a comma to the thread.start_new_thread(tm, ())
I get this error:
Unhandled exception in thread started by
sys.excepthook is missing
lost sys.stderr
However, when the comma is missing, it runs fine as long as that piece of while True
code is there.
Upvotes: 2
Views: 2538
Reputation: 373
If you are still using Python 2.7, here is another example.
import thread
import threading
class PeriodicThread(threading._Timer):
def __init__(self, *args, **kwargs):
threading._Timer.__init__(self, *args, **kwargs)
self.daemon = True
def run(self):
while True:
self.finished.clear()
self.finished.wait(self.interval)
if not self.finished.isSet():
self.function(*self.args, **self.kwargs)
else:
return
self.finished.set()
class PeriodicThreadManager(object):
periodic_threads = []
def run(self, interval, callback_fn, args=[], kwargs={}):
new_thread = PeriodicThread(interval, callback_fn, args, kwargs)
self.periodic_threads.append(new_thread)
thread.start_new_thread(new_thread.run, ())
def stop_all(self):
for t in self.periodic_threads:
t.cancel()
self._event.set()
class YourApplication:
def __init__(self):
self.threads = PeriodicThreadManager()
self.threads.run( .01, self.periodic_callback_1 ) # 10 ms but ...
self.threads.run( .01, self.periodic_callback_2 )
def periodic_callback_1(self):
....
def periodic_callback_2(self):
....
Upvotes: 0
Reputation: 3939
If you truly intend to run tm
in a separate thread, you are missing a comma between your two positional arguments. It should read as follows:
thread.start_new_thread(tm, ())
If you do not need the execution of tm
to happen in another thread, simple call the function in the current thread like so:
tm()
This is happening already without the comma since the space is removed by the Python interpreter.
thread.start_new_thread(tm ())
# gets turned into
thread.start_new_thread(tm())
# which evaluates tm() before calling 'start_new_thread'
If the loop is removed, the return value of tm()
gets passed as a single argument to start_new_thread
which results in the original error posted.
As mentioned in the other answer, you likely should be using the threading
library instead of thread
. More details about why are listed here.
Upvotes: 2
Reputation: 1221
You should be using threading
instead of thread
The thread
module is a low-level interface to starting threads, and it's going to require a lot of unnecessary headaches while you're learning this. See this post
Then, the proper way to start a thread would be
import threading
import time
def printstuff(stuff):
while 1:
print(stuff)
time.sleep(3)
t = threading.Thread(target=printstuff, args=('helloworld',))
t.start()
# Here is where your main thread will do whatever
print('Main thread running')
time.sleep(5)
print('Main thread done')
# At this point the main thread will be done
# but printstuff will still be printing stuff.
# Control-c will exit the second thread, and
# youll be back at a prompt
Your code above is not a minimal example, and it's very hard to understand what you're actually trying to accomplish. Try clarifying the goal in some pseudo-code, and then I can work with you to improve your understanding of multi-threading.
Upvotes: 4