How does asyncio.sleep work with negative values?

I decided to implement sleep sorting ( https://rosettacode.org/wiki/Sorting_algorithms/Sleep_sort ) using Python asynciowhen I made a strange discovery: it works with negative values ​​(and returns immediately from 0)!

Here is the code (you can run it here https://repl.it/DYTZ ):

import asyncio
import random

async def sleepy(value):
    return await asyncio.sleep(value, result=value)


async def main(input_values):
    result = []
    for sleeper in asyncio.as_completed(map(sleepy, input_values)):
        result.append(await sleeper)
    print(result)


if __name__ == '__main__':
    loop = asyncio.get_event_loop()
    input_values = list(range(-5, 6))
    random.shuffle(input_values)
    loop.run_until_complete(main(input_values))

It takes 5 seconds to execute the code, as expected, but the result is always [0, -5, -4, -3, -2, -1, 1, 2, 3, 4, 5]. I can immediately understand 0, but how do negative values ​​return in the correct order?

+4
source share
2 answers

Ok, looking at the source:

  • delay == 0 , .
  • events.get_event_loop(). asyncio.tasks events.set_event_loop_policy(policy), , , , , asyncio.DefaultEventLoopPolicy.
  • events.py, Windows UNIX.
  • sleep loop.create_future(). , base_events.BaseEventLoop. Future(), .
  • Future :

    future._loop.call_later(delay,
                            futures._set_result_unless_cancelled,
                            future, result)
    
  • BaseEventLoop - delay: self.call_at, .
  • call_at events.TimerHandle, - Future. , , . - .
  • _scheduled heapq - , _when. .
  • , , , , , , .

TL; :

asyncio , "" . , , . , 0 , , " " , .

+3

asyncio, sleep 0 .

if delay == 0:
    yield
    return result

, , call_later. , call_later (BaseEventLoop), , call_later call_at.

self.call_at(self.time() + delay, callback, *args)

, , , , , , .

+4

Source: https://habr.com/ru/post/1654054/


All Articles