<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def graceful_exit(servers, *, loop, signals=frozenset({signal.SIGINT, signal.SIGTERM})):
 """Utility context-manager to help properly shutdown server in response to the OS signals By default this context-manager handles ``SIGINT`` and ``SIGTERM`` signals. There are two stages: 1. first received signal closes servers 2. subsequent signals raise ``SystemExit`` exception Example: .. code-block:: python3 with graceful_exit([server], loop=loop):
 await server.start(host, port) print('Serving on {}:{}'.format(host, port)) await server.wait_closed() print('Server closed') First stage calls ``server.close()`` and ``await server.wait_closed()`` should complete successfully without errors. If server wasn't started yet, second stage runs to prevent server start. Second stage raises ``SystemExit`` exception, but you will receive ``asyncio.CancelledError`` in your ``async def main()`` coroutine. You can use ``try..finally`` constructs and context-managers to properly handle this error. This context-manager is designed to work in cooperation with :py:func:`python:asyncio.run` function: .. code-block:: python3 if __name__ == '__main__': asyncio.run(main()) :param servers: list of servers :param loop: asyncio-compatible event loop :param signals: set of the OS signals to handle """

    signals = set(signals)
    flag = []
    for sig_num in signals:
        loop.add_signal_handler(sig_num, _exit_handler, sig_num, servers, flag)
    try:
        yield
    finally:
        for sig_num in signals:
            loop.remove_signal_handler(sig_num)