[New-bugs-announce] [issue31489] Signal delivered to a subprocess triggers parent's handler

Ilya Kulakov report at bugs.python.org
Sat Sep 16 01:25:54 EDT 2017


New submission from Ilya Kulakov:

It looks like a signal delivered to multiprocessing's process implicitly created by ProcessPoolExecutor triggers signal handler in the parent:

```
from concurrent.futures import ProcessPoolExecutor
import asyncio
import os
import signal
import sys
import time


def background_task():
    print(f"Running background task {os.getpid()}", file=sys.stderr)
    time.sleep(15)
    print("Exiting background task", file=sys.stderr)


async def task():
    print("Running task")

    executor = ProcessPoolExecutor()
    with executor:
        loop = asyncio.get_event_loop()

        try:
            await loop.run_in_executor(executor, background_task)
        except asyncio.CancelledError:
            print("Cancelling task 1", file=sys.stderr)

            try:
                await asyncio.sleep(15)
            except asyncio.CancelledError:
                print("Cancelling task 2", file=sys.stderr)
                raise

            raise

def main():
    def terminate(coro):
        print(f"Terminating {os.getpid()}")
        coro.cancel()

    loop = asyncio.get_event_loop()
    t = asyncio.ensure_future(task())
    loop.add_signal_handler(signal.SIGTERM, terminate, t)

    try:
        print(f"Running {os.getpid()}", file=sys.stderr)
        loop.run_until_complete(t)
    finally:
        loop.run_until_complete(loop.shutdown_asyncgens())
        loop.close()


if __name__ == '__main__':
    main()
```

1. Normal execution:

> Running 1000
> Running task
> Running background task 9999
> Exiting background task

2. Sending SIGTERM to parent once:

> Running 1000
> Running task
> Running background task 9999

< kill -s SIGTERM 9999

> Terminating 1000
> Cancelling task 1
> Exiting background task


3. Sending SIGTERM to parent twice:

> Running 1000
> Running task
> Running background task 9999

< kill -s SIGTERM 1000

> Terminating 1000
> Cancelling task 1

< kill -s SIGTERM 1000

> Terminating 1000
> Cancelling task 2
> Exiting background task


4. Sending SIGTERM to once to parent and once to child:

> Running 1000
> Running task
> Running background task 9999

< kill -s SIGTERM 1000

> Terminating 1000
> Cancelling task 1

< kill -s SIGTERM 9999

> Terminating 1000
> Cancelling task 2
> Exiting background task


As you can see, sending SIGTERM into a subprocess somehow triggered a signal handler inside a parent. This is unexpected.

----------
components: asyncio
messages: 302321
nosy: Ilya.Kulakov, yselivanov
priority: normal
severity: normal
status: open
title: Signal delivered to a subprocess triggers parent's handler
type: behavior
versions: Python 3.6

_______________________________________
Python tracker <report at bugs.python.org>
<https://bugs.python.org/issue31489>
_______________________________________


More information about the New-bugs-announce mailing list