is_alive
is not implemented for any of the ports supporting threads currently (in the official repository, don't know about others). So your options are:
- track it manually
- use different logic in your code so you don't need it
- create a feature request
- implement it yourself for the port you use (if you know C this could be relatively easy as thread implementation usually have a built-in way to report their state)
For the last case I got curious and came up with this, for the unix port as I don't have Lego to play with, which adds is_alive
to the _thread
module. From thereon it should be fairly easy to get it in your Threading
class. Note this is just to give you an idea of what it takes, and is untested proof of concept, YMMV. Patch:
--- a/ports/unix/mpthreadport.c
+++ b/ports/unix/mpthreadport.c
@@ -174,7 +174,20 @@ void mp_thread_start(void) {
pthread_mutex_unlock(&thread_mutex);
}
-void mp_thread_create(void *(*entry)(void*), void *arg, size_t *stack_size) {
+int mp_thread_is_alive(void* id) {
+ int ready = 0;
+ pthread_mutex_lock(&thread_mutex);
+ for (thread_t *th = thread; th != NULL; th = th->next) {
+ if (th->id == (pthread_t)id && th->ready) {
+ ready = 1;
+ break;
+ }
+ }
+ pthread_mutex_unlock(&thread_mutex);
+ return ready;
+}
+
+void* mp_thread_create(void *(*entry)(void*), void *arg, size_t *stack_size) {
// default stack size is 8k machine-words
if (*stack_size == 0) {
*stack_size = 8192 * BYTES_PER_WORD;
@@ -225,7 +238,7 @@ void mp_thread_create(void *(*entry)(void*), void *arg, size_t *stack_size) {
pthread_mutex_unlock(&thread_mutex);
- return;
+ return (void*) th->id;
er:
mp_raise_OSError(ret);
diff --git a/py/modthread.c b/py/modthread.c
index 91237a7..246dd5c 100644
--- a/py/modthread.c
+++ b/py/modthread.c
@@ -264,9 +264,7 @@ STATIC mp_obj_t mod_thread_start_new_thread(size_t n_args, const mp_obj_t *args)
th_args->fun = args[0];
// spawn the thread!
- mp_thread_create(thread_entry, th_args, &th_args->stack_size);
-
- return mp_const_none;
+ return mp_obj_new_int_from_uint((uintptr_t)mp_thread_create(thread_entry, th_args, &th_args->stack_size));
}
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_thread_start_new_thread_obj, 2, 3, mod_thread_start_new_thread);
@@ -275,6 +273,11 @@ STATIC mp_obj_t mod_thread_exit(void) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_0(mod_thread_exit_obj, mod_thread_exit);
+STATIC mp_obj_t mod_thread_is_alive(mp_obj_t id) {
+ return mp_obj_new_bool(mp_thread_is_alive((void*) mp_obj_get_int(id)));
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_thread_is_alive_obj, mod_thread_is_alive);
+
STATIC mp_obj_t mod_thread_allocate_lock(void) {
return MP_OBJ_FROM_PTR(mp_obj_new_thread_lock());
}
@@ -287,6 +290,7 @@ STATIC const mp_rom_map_elem_t mp_module_thread_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR_stack_size), MP_ROM_PTR(&mod_thread_stack_size_obj) },
{ MP_ROM_QSTR(MP_QSTR_start_new_thread), MP_ROM_PTR(&mod_thread_start_new_thread_obj) },
{ MP_ROM_QSTR(MP_QSTR_exit), MP_ROM_PTR(&mod_thread_exit_obj) },
+ { MP_ROM_QSTR(MP_QSTR_is_alive), MP_ROM_PTR(&mod_thread_is_alive_obj) },
{ MP_ROM_QSTR(MP_QSTR_allocate_lock), MP_ROM_PTR(&mod_thread_allocate_lock_obj) },
};
diff --git a/py/mpthread.h b/py/mpthread.h
index 602df83..46f1a3a 100644
--- a/py/mpthread.h
+++ b/py/mpthread.h
@@ -40,7 +40,8 @@ struct _mp_state_thread_t;
struct _mp_state_thread_t *mp_thread_get_state(void);
void mp_thread_set_state(void *state);
-void mp_thread_create(void *(*entry)(void*), void *arg, size_t *stack_size);
+void* mp_thread_create(void *(*entry)(void*), void *arg, size_t *stack_size);
+int mp_thread_is_alive(void*);
Which enables code like:
import _thread
import utime
def Entry():
utime.sleep_ms(1)
t = _thread.start_new_thread(Entry, ())
for i in range(10):
print('thread alive', _thread.is_alive(t))
Which prints True a couple of times, then False.