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 gaoxinge
Recipients gaoxinge
Date 2018-07-29.03:25:06
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1532834708.12.0.56676864532.issue34268@psf.upfronthosting.co.za>
In-reply-to
Content
## abstract

When using concurrent.futures.ThreadPoolExecutor module, if we code pool.submit in callback, the callback may be not run. This is because main thread will terminate, and call _python_exit to add none to _work_queue before subthread run callback.

## code

```
# -*- coding: utf-8 -*-
from concurrent.futures import ThreadPoolExecutor


def func(x, y):
    import time
    time.sleep(1)
    return x + y


def do_many(n):

    def callback(fut):
        nonlocal n
        result = fut.result()
        print('Got: ', result)
        n -= 1
        if n > 0:
            future = pool.submit(func, n, n)
            future.add_done_callback(callback)

    if n > 0:
        future = pool.submit(func, n, n)
        future.add_done_callback(callback)
     # _python_exit will be called here, and then 
     # add none to _work_queue

pool = ThreadPoolExecutor(max_workers=8)
do_many(10)
```

## result and expectation

The code's result may be 

```
Got:  20
Got:  18
Got:  16
Got:  14
Got:  12
Got:  10
Got:  8
Got:  6
```

But my expectation is

```
Got:  20
Got:  18
Got:  16
Got:  14
Got:  12
Got:  10
Got:  8
Got:  6
Got:  4
Got:  2
```

## question

Is my expectation reasonable?

### if not reasonable

If not, my solution is 

```
from concurrent.futures import ThreadPoolExecutor


def func(x, y):
    import time
    time.sleep(1)
    return x + y


def do_many():

    def callback(fut):
        global n
        result = fut.result()
        print('Got: ', result)
        n -= 1
        if n > 0:
            future = pool.submit(func, n, n)
            future.add_done_callback(callback)

    if n > 0:
        future = pool.submit(func, n, n)
        future.add_done_callback(callback)

n = 10
pool = ThreadPoolExecutor(max_workers=8)
do_many()
while n > 0:  # use while to block main thread
    pass
```

and is there any elegant solution?

### if reasonable

...
History
Date User Action Args
2018-07-29 03:25:08gaoxingesetrecipients: + gaoxinge
2018-07-29 03:25:08gaoxingesetmessageid: <1532834708.12.0.56676864532.issue34268@psf.upfronthosting.co.za>
2018-07-29 03:25:07gaoxingelinkissue34268 messages
2018-07-29 03:25:06gaoxingecreate