This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author Ilya.Kulakov
Recipients Ilya.Kulakov, yselivanov
Date 2017-09-16.05:25:53
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1505539554.17.0.680456394796.issue31489@psf.upfronthosting.co.za>
In-reply-to
Content
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.
History
Date User Action Args
2017-09-16 05:25:54Ilya.Kulakovsetrecipients: + Ilya.Kulakov, yselivanov
2017-09-16 05:25:54Ilya.Kulakovsetmessageid: <1505539554.17.0.680456394796.issue31489@psf.upfronthosting.co.za>
2017-09-16 05:25:54Ilya.Kulakovlinkissue31489 messages
2017-09-16 05:25:53Ilya.Kulakovcreate