@@ -84,8 +84,10 @@ including device drivers, debugging aids, and documentation.
84
84
8.4 [ Scheduling in uasyncio] ( ./TUTORIAL.md#84-scheduling-in-uasyncio )
85
85
8.5 [ Why cooperative rather than pre-emptive?] ( ./TUTORIAL.md#85-why-cooperative-rather-than-pre-emptive )
86
86
8.6 [ Communication] ( ./TUTORIAL.md#86-communication )
87
- 9 . [ Polling vs Interrupts] ( ./TUTORIAL.md#9-polling-vs-interrupts ) A common
88
- source of confusion.
87
+ 9 . [ Polling vs Interrupts] ( ./TUTORIAL.md#9-polling-vs-interrupts ) A common
88
+ source of confusion.
89
+ 10 . [ Interfacing threaded code] ( ./TUTORIAL.md#10-interfacing-threaded-code ) Taming blocking functions. Multi core coding.
90
+
89
91
90
92
###### [ Main README] ( ../README.md )
91
93
@@ -947,18 +949,23 @@ is raised.
947
949
948
950
## 3.5 Queue
949
951
950
- This is currently an unofficial implementation. Its API is a subset of that of
951
- CPython's ` asyncio.Queue ` . Like ` asyncio.Queue ` this class is not thread safe.
952
- A queue class optimised for MicroPython is presented in
953
- [ Ringbuf queue] ( ./EVENTS.md#7-ringbuf-queue ) .
952
+ Queue objects provide a means of synchronising producer and consumer tasks: the
953
+ producer puts data items onto the queue with the consumer removing them. If the
954
+ queue becomes full, the producer task will block, likewise if the queue becomes
955
+ empty the consumer will block. Some queue implementations allow producer and
956
+ consumer to run in different contexts: for example where one runs in an
957
+ interrupt service routine or on a different thread or core from the ` uasyncio `
958
+ application. Such a queue is termed "thread safe".
954
959
955
- The ` Queue ` class provides a means of synchronising producer and consumer
956
- tasks: the producer puts data items onto the queue with the consumer removing
957
- them. If the queue becomes full, the producer task will block, likewise if
958
- the queue becomes empty the consumer will block.
960
+ The ` Queue ` class is an unofficial implementation whose API is a subset of that
961
+ of CPython's ` asyncio.Queue ` . Like ` asyncio.Queue ` this class is not thread
962
+ safe. A queue class optimised for MicroPython is presented in
963
+ [ Ringbuf queue] ( ./EVENTS.md#7-ringbuf-queue ) . A thread safe version is
964
+ documented in [ ThreadSafeQueue] ( ./THREADING.md#22-threadsafequeue ) .
959
965
960
- Constructor: Optional arg ` maxsize=0 ` . If zero, the queue can grow without
961
- limit subject to heap size. If >0 the queue's size will be constrained.
966
+ Constructor:
967
+ Optional arg ` maxsize=0 ` . If zero, the queue can grow without limit subject to
968
+ heap size. If ` maxsize>0 ` the queue's size will be constrained.
962
969
963
970
Synchronous methods (immediate return):
964
971
* ` qsize ` No arg. Returns the number of items in the queue.
@@ -1093,39 +1100,8 @@ hardware device requires the use of an ISR for a μs level response. Having
1093
1100
serviced the device, the ISR flags an asynchronous routine, typically
1094
1101
processing received data.
1095
1102
1096
- The fact that only one task may wait on a ` ThreadSafeFlag ` may be addressed as
1097
- follows.
1098
- ``` python
1099
- class ThreadSafeEvent (asyncio .Event ):
1100
- def __init__ (self ):
1101
- super ().__init__ ()
1102
- self ._waiting_on_tsf = False
1103
- self ._tsf = asyncio.ThreadSafeFlag()
1104
-
1105
- def set (self ):
1106
- self ._tsf.set()
1107
-
1108
- async def _waiter (self ): # Runs if 1st task is cancelled
1109
- await self ._tsf.wait()
1110
- super ().set()
1111
- self ._waiting_on_tsf = False
1112
-
1113
- async def wait (self ):
1114
- if self ._waiting_on_tsf == False :
1115
- self ._waiting_on_tsf = True
1116
- await asyncio.sleep(0 ) # Ensure other tasks see updated flag
1117
- try :
1118
- await self ._tsf.wait()
1119
- super ().set()
1120
- self ._waiting_on_tsf = False
1121
- except asyncio.CancelledError:
1122
- asyncio.create_task(self ._waiter())
1123
- raise # Pass cancellation to calling code
1124
- else :
1125
- await super ().wait()
1126
- ```
1127
- An instance may be set by a hard ISR or from another thread/core. As an ` Event `
1128
- it can support multiple tasks and must explicitly be cleared.
1103
+ See [ Threadsafe Event] ( ./THREADING.md#31-threadsafe-event ) for a thread safe
1104
+ class which allows multiple tasks to wait on it.
1129
1105
1130
1106
###### [ Contents] ( ./TUTORIAL.md#contents )
1131
1107
@@ -2883,3 +2859,17 @@ This, along with other issues, is discussed in
2883
2859
[ Interfacing uasyncio to interrupts] ( ./INTERRUPTS.md ) .
2884
2860
2885
2861
###### [ Contents] ( ./TUTORIAL.md#contents )
2862
+
2863
+ # 10. Interfacing threaded code
2864
+
2865
+ In the context of a ` uasyncio ` application, the ` _thread ` module has two main
2866
+ uses:
2867
+ 1 . Defining code to run on another core (currently restricted to RP2).
2868
+ 2 . Handling blocking functions. The technique assigns the blocking function to
2869
+ another thread. The ` uasyncio ` system continues to run, with a single task
2870
+ paused pending the result of the blocking method.
2871
+
2872
+ These techniques, and thread-safe classes to enable their use, are presented in
2873
+ [ this doc] ( ./THREAD.md ) .
2874
+
2875
+ ###### [ Contents] ( ./TUTORIAL.md#contents )
0 commit comments