threading - thread starts, but main does not run
-
Hi All,
I want to run a thread in the background, reading I2C GPS pytrack data and feeding a micropyGPS object to constantly update GPS/GNS data.
In the main thread I want to read from the same micropyGPS object to occasionally update location data.
I have a main.py that does;
my_gps = MicropyGPS() py = Pytrack() L76micropyGPS = L76micropyGPS(my_gps, py) while (True): print("my_gps.parsed_sentences : {}".format(my_gps.parsed_sentences())) time.sleep(2)
This creates creates the object that then starts a thread thus;
class L76micropyGPS: GPS_I2CADDR = const(0x10) def __init__(self, my_gps, pytrack=None, sda='P22', scl='P21'): <snippage> self.my_gps = my_gps # start thread feeding microGPS _thread.start_new_thread("GPS", self.feedMicroGPS(), ()) def feedMicroGPS(self): print('Running feedGps_thread id: {}'.format(_thread.get_ident())) someNmeaData = '' while True: # get some NMEA data someNmeaData = str(self.i2c.readfrom(GPS_I2CADDR, 128)) print(" feedGps_thread - gpsChars recieved : {}".format(len(someNmeaData))) # Pass NMEA data to micropyGPS object for x in someNmeaData: self.my_gps.update(str(x)) time.sleep(2)
Actual behaviour - I see the thread start, and get I2C data, whilst updating the object, but the main thread never gets beyond creating that object - ie the while loop never executes.
My expected behaviour is the thread runs in the background (in this case printing data) and then the main thread carries on running (and can see the new GPS data).
Have I mis understood something about _threading on micropython?
Complete code: https://github.com/gregcope/L76micropyGPS
-
@seb said in threading - thread starts, but main does not run:
Ta.
Opened;
https://github.com/pycom/pycom-micropython-sigfox/issues/158
-
As in report a bug? The relevant github repo is usally the best place for such things:
Firmware: https://github.com/pycom/pycom-micropython-sigfox/issues
Libraries: https://github.com/pycom/pycom-libraries/issues
Documentation: https://github.com/pycom/pycom-documentation/issues
Pymakr: https://github.com/pycom/pymakr-atom/issues
-
@timh said in threading - thread starts, but main does not run:
@gregcope Sorry I missed the arglist 2nd argument altogether.
I was focusing on the first arg, where you were still calling a function/method and passing it's result to start_new_thread rather than passing the function handle.
As to bug, that probably should raise an expecption, but thats in the
_thread
libraryNo problem - thanks for all your help.
@Seb - where do i raise bugs?
-
@gregcope Sorry I missed the arglist 2nd argument altogether.
I was focusing on the first arg, where you were still calling a function/method and passing it's result to start_new_thread rather than passing the function handle.
As to bug, that probably should raise an expecption, but thats in the
_thread
library
-
@timh Many thanks.
self.gps_thread = _thread.start_new_thread(self.feedMicroGPS)
I found that did NOT work.
But
self.gps_thread = _thread.start_new_thread(self.feedMicroGPS, ())
Does work - ie you have to supply an empty arg list, otherwise it does not return.
Is that a bug? Should it not throw an exception?
-
@gregcope Hi Greg.
You missed the crucial bit in my email. You code still calls
self.feedMicroGPS()
once and it's result is passed tostart_new_thread
.self.gps_thread = _thread.start_new_thread(self.feedMicroGPS())
should be
self.gps_thread = _thread.start_new_thread(self.feedMicroGPS)
-
Thanks @timh tried that (or something similar);
Changed main to include;
L76micropyGPS = L76micropyGPS(my_gps, py) gpsThread = L76micropyGPS.startGPSThread() print("startGPSThread thread id is: " + startGPSThread)
And class L76micropyGPS to (separate out the thread start to its own method, so I can call thread stop in another method);
def startGPSThread(self): # start thread feeding microGPS self.gps_thread = _thread.start_new_thread(self.feedMicroGPS())
My expected behavour is that the Main thread gets to this line just after thread start and Main carries on (with Thread in background also carrying on;
print("startGPSThread thread id is: " + startGPSThread)
This never happens ....
Output (that just carries on)Free Mem: 2535984 Free Mem post pytrack instantiation: 2534320 Free Mem post my_gps instantiation: 2533616 Running feedGps_thread id: 1073503820 feedGps_thread - gpsChars recieved : 226 feedGps_thread - gpsChars recieved : 139 feedGps_thread - gpsChars recieved : 141 feedGps_thread - gpsChars recieved : 139
-
@gregcope Have a look at the docs and your call to
start_new_thread
_thread.start_new_thread(function, args[, kwargs])
Start a new thread and return its identifier. The thread executes the function with the argument list args (which must be a tuple). The optional kwargs argument specifies a dictionary of keyword arguments. When the function returns, the thread silently exits. When the function terminates with an unhandled exception, a stack trace is printed and then the thread exits (but other threads continue to run).At the moment you are passing in a 'string' GPS as the first argument and the result of the function call
self.feedMicroGPS()
in the second.Your start_new_thread call should look like
_thread.start_new_thread(self.feedMicroGPS, <some args>)
When the docs say pass a function, your are passing a function/method handle and not calling the function.