Page 1 of 2

ESP8266 and _thread

Posted: Mon Feb 04, 2019 4:46 pm
by radders
Hello,

I can't find out if _thread has been built into the ESP8266 yet.

I just downloaded the latest firmware (esp8266-20190125-v1.10.bin),
yet when I execute
import _thread
I get an error message
ImportError: no module named '_thread'

Please help!

Re: ESP8266 and _thread

Posted: Tue Feb 05, 2019 8:45 am
by pythoncoder
ESP8266 is probably too RAM-limited to support threading. Consider using uasyncio instead: this is much more efficient and better suited to platforms with restricted RAM.

Re: ESP8266 and _thread

Posted: Tue Feb 05, 2019 8:58 am
by radders
Thank you.

I open a socket, and wait for incoming data using socket.receive().

The issue I have is that this method blocks, preventing me from sending data to the same socket until the receive completes.

I was hoping to create 2 threads, one for receive and one for sending. How can uasyncio help in this case?

Regards, Dave

Re: ESP8266 and _thread

Posted: Tue Feb 05, 2019 9:11 am
by Roberthh
In the esp8266 (and ESP32) socket module there is a proprietary method to register a handler, which is called whenever something happens with the socket. It is called like:

socket.setsockopt(socket.SOL_SOCKET, 20, my_event_handler)

my_event_handler() is a function, which has as argument the socket which cause the event, whcih could e.g. be connect request or data being received or the socket being closed. This way, you can make your receive socket non-blocking.
Since this method is also used by Webrepl (it was invented for that), you cannot use webrepl at the same time.

Re: ESP8266 and _thread

Posted: Tue Feb 05, 2019 9:16 am
by radders
Brilliant! Thank you.

Will read up on that.

Dave

Re: ESP8266 and _thread

Posted: Wed Feb 06, 2019 11:48 am
by pythoncoder
radders wrote:
Tue Feb 05, 2019 8:58 am
...
I was hoping to create 2 threads, one for receive and one for sending. How can uasyncio help in this case?...
It is possible to put the sockets into nonblocking mode to enable concurrent I/O. Some care is required as the socket send and recv methods can handle partial data. Given that recv must return immediately it can only return the data which is available at that moment in time. A similar contingency exists with send: it may only send a part of the data.

Re: ESP8266 and _thread

Posted: Sun Mar 14, 2021 8:47 pm
by iconoclastica
Roberthh wrote:
Tue Feb 05, 2019 9:11 am
socket.setsockopt(socket.SOL_SOCKET, 20, my_event_handler)
When this code is used as alternative for

Code: Select all

client, address = socket.accept()
how could I find the remote address from the incoming socket?

Re: ESP8266 and _thread

Posted: Mon Mar 15, 2021 9:00 am
by pythoncoder
You could look at the uasyncio solution Server class and start_server method. Looking at the code, the peer address is assigned to the streams and could be retrieved by the callback.

On an ESP8266 uasyncio is a RAM efficient approach to networking.

Re: ESP8266 and _thread

Posted: Mon Mar 15, 2021 1:09 pm
by iconoclastica
Hmm, that is a lot more code to do the same. It may be more efficient, but optimizing without the need to optimize is not.

Re: ESP8266 and _thread

Posted: Mon Mar 15, 2021 1:46 pm
by pythoncoder
I don't know the detail of what you are trying to achieve, but in general a server needs to be able to serve multiple concurrent clients. The two classic ways of managing that are to use threads (pre-emptive multi tasking as per the OP) or to run a cooperative scheduler. Typical PC based solutions use threading. On a microcontroller cooperative scheduling is much more efficient in terms of RAM usage. See this for an example of how it can be used.

If you only expect to handle a single client, none of this applies.