Skip to content
Momtchil Momtchev edited this page Jan 21, 2023 · 5 revisions

[New in 1.3]

Introduction

Full multi-threading safety is guaranteed and worker_threads are supported.

Quick reminder of the status of multithreading in Python and JavaScript (Node.js):

  • Python: only one thread can actually execute Python code at any given moment but threads can access each other's objects (shared memory model), binary extensions have no limitations but can access Python objects only while holding the global interpreter lock (GIL)
  • JavaScript: all threads can run at the same time but cannot access each other's objects (separate isolates model) and must communicate mostly through message passing and some very limited data structures such as SharedArrayBuffer, binary extensions have no such limitations but can access JavaScript objects only when running in the context of the JavaScript thread that created them

[New in 1.4] Thread-safe bootstrap and shutdown is also supported allowing to load and unload the module at will in a worker_thread. See #69.

Asynchronous execution

Asynchronous calling of Python functions in a background thread is possible by using callAsync.

In this case Python will run in one of the libuv worker threads.

You should be aware that:

  • The Python interpreter is single-threaded and two threads cannot simultaneously run Python code. Well-written native extensions such as numpy will release the lock when running C/C++ code to allow for parallel execution. This means that if JavaScript calls asynchronously a Python function, all attempts at accessing a PyObject will block until that function has released the Python Global Interpreter Lock. This is a Python restriction that cannot be avoided.
  • pymport will also release the GIL when the Python code has re-entered JavaScript by calling a passed JavaScript callback.
  • When calling JavaScript from a background thread, this thread will block until V8 is available to run the callback - as V8 is not preemptive. While waiting, the GIL won't be held, allowing for other Python code to run.
  • Unlike JavaScript, Python threads share the same memory storage - this means that worker_threads will share one Python environment. As Python supports multiple interpreter instances, this can eventually no longer be the case in a future version.
  • Zero-copy transfers of PyObjects between worker_threads are not yet supported - but are planned.

JavaScript async / await

Using async JavaScript functions is supported as well as awaiting Promises returned from asynchronous execution of Python code. However when passing an async callback to Python, Python won't be able to process the returned Promise and won't be able to handle its return value.

Python asyncio

Python's own asyncio is still not supported.