@@ -1067,14 +1067,59 @@ Scheduling From Other Threads
10671067 This function is meant to be called from a different OS thread
10681068 than the one where the event loop is running. Example::
10691069
1070- # Create a coroutine
1071- coro = asyncio.sleep(1, result=3)
1072-
1073- # Submit the coroutine to a given loop
1074- future = asyncio.run_coroutine_threadsafe(coro, loop)
1075-
1076- # Wait for the result with an optional timeout argument
1077- assert future.result(timeout) == 3
1070+ def in_thread(loop: asyncio.AbstractEventLoop) -> None:
1071+ # Run some blocking IO
1072+ pathlib.Path("example.txt").write_text("hello world", encoding="utf8")
1073+
1074+ # Create a coroutine
1075+ coro = asyncio.sleep(1, result=3)
1076+
1077+ # Submit the coroutine to a given loop
1078+ future = asyncio.run_coroutine_threadsafe(coro, loop)
1079+
1080+ # Wait for the result with an optional timeout argument
1081+ assert future.result(timeout=2) == 3
1082+
1083+ async def amain() -> None:
1084+ # Get the running loop
1085+ loop = asyncio.get_running_loop()
1086+
1087+ # Run something in a thread
1088+ await asyncio.to_thread(in_thread, loop)
1089+
1090+ It's also possible to run the other way around. Example::
1091+
1092+ @contextlib.contextmanager
1093+ def loop_in_thread() -> Generator[asyncio.AbstractEventLoop]:
1094+ loop_fut = concurrent.futures.Future[asyncio.AbstractEventLoop]()
1095+ stop_event = asyncio.Event()
1096+
1097+ async def main() -> None:
1098+ loop_fut.set_result(asyncio.get_running_loop())
1099+ await stop_event.wait()
1100+
1101+ with concurrent.futures.ThreadPoolExecutor(1) as tpe:
1102+ complete_fut = tpe.submit(asyncio.run, main())
1103+ for fut in concurrent.futures.as_completed((loop_fut, complete_fut)):
1104+ if fut is loop_fut:
1105+ loop = loop_fut.result()
1106+ try:
1107+ yield loop
1108+ finally:
1109+ loop.call_soon_threadsafe(stop_event.set)
1110+ else:
1111+ fut.result()
1112+
1113+ # Create a loop in another thread
1114+ with loop_in_thread() as loop:
1115+ # Create a coroutine
1116+ coro = asyncio.sleep(1, result=3)
1117+
1118+ # Submit the coroutine to a given loop
1119+ future = asyncio.run_coroutine_threadsafe(coro, loop)
1120+
1121+ # Wait for the result with an optional timeout argument
1122+ assert future.result(timeout=2) == 3
10781123
10791124 If an exception is raised in the coroutine, the returned Future
10801125 will be notified. It can also be used to cancel the task in
0 commit comments