Skip to content

Commit 2751bac

Browse files
first commit
0 parents  commit 2751bac

31 files changed

+850
-0
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# git ignore
2+
**/.DS_Store
3+
.DS_Store

README.md

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
# Python ThreadPoolExecutor Jump-Start
2+
3+
![Python ThreadPoolExecutor Jump-Start](cover.png)
4+
5+
* <https://github.com/SuperFastPython/PythonThreadPoolExecutorJumpStart>
6+
7+
This repository provides all source code for the book:
8+
9+
* **Python ThreadPoolExecutor Jump-Start**: _Execute IO-Bound Tasks Asynchronously With Modern Thread Pools_, Jason Brownlee, 2022.
10+
11+
12+
## Source Code
13+
You can access all Python .py files directly here:
14+
15+
* [src/](src/)
16+
17+
## Get the Book
18+
19+
You can learn more about the book here:
20+
21+
* Soon...
22+
23+
### Book Blurb
24+
25+
> How much faster could your Python code run (if you used 100s of thread workers)?
26+
>
27+
> The ThreadPoolExecutor class provides modern thread pools for IO-bound tasks.
28+
>
29+
> This is not some random third-party library, this is a class provided in the Python standard library (already installed on your system).
30+
>
31+
> This is the class you need to make your code run faster.
32+
>
33+
> There's just one problem. No one knows about it (or how to use it well).
34+
>
35+
> Introducing: "Python ThreadPoolExecutor Jump-Start". A new book designed to teach you thread pools in Python, super fast!
36+
>
37+
> You will get a rapid-paced, 7-part course to get you started and make you awesome at using the ThreadPoolExecutor.
38+
>
39+
> Including:
40+
>
41+
> * How to create thread pools and when to use them.
42+
> * How to configure thread pools including the number of threads.
43+
> * How to execute tasks with worker threads and handle for results.
44+
> * How to execute tasks in the thread pool asynchronously.
45+
> * How to query and get results from handles on asynchronous tasks called futures.
46+
> * How to wait on and manage diverse collections of asynchronous tasks.
47+
> * How to develop a concurrent website status checker that is 5x faster than the sequential version.
48+
>
49+
> Each of the 7 lessons was carefully designed to teach one critical aspect of the ThreadPoolExecutor, with explanations, code snippets and worked examples.
50+
>
51+
> Each lesson ends with an exercise for you to complete to confirm you understood the topic, a summary of what was learned, and links for further reading if you want to go deeper.
52+
>
53+
> Stop copy-pasting code from StackOverflow answers.
54+
>
55+
> Learn Python concurrency correctly, step-by-step.

cover.png

682 KB
Loading

src/lesson01_thread.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# SuperFastPython.com
2+
# example of running a function in a new thread
3+
from threading import Thread
4+
5+
# custom function to be executed in a new thread
6+
def task():
7+
# report a message
8+
print('This is another thread')
9+
10+
# protect the entry point
11+
if __name__ == '__main__':
12+
# define a task to run in a new thread
13+
thread = Thread(target=task)
14+
# start the task in a new thread
15+
thread.start()
16+
# wait for the thread to terminate
17+
thread.join()

src/lesson01_threadpoolexecutor.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# SuperFastPython.com
2+
# example running a function in the thread pool
3+
from concurrent.futures import ThreadPoolExecutor
4+
5+
# custom function to be executed in a worker thread
6+
def task():
7+
# report a message
8+
print('This is another thread')
9+
10+
# protect the entry point
11+
if __name__ == '__main__':
12+
# create the thread pool
13+
with ThreadPoolExecutor() as exe:
14+
# issue the task
15+
future = exe.submit(task)
16+
# wait for the task to finish
17+
future.result()
18+
# close the thread pool automatically

src/lesson02_default_config.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# SuperFastPython.com
2+
# example reporting the details of a default pool
3+
from concurrent.futures import ThreadPoolExecutor
4+
5+
# protect the entry point
6+
if __name__ == '__main__':
7+
# create a thread pool
8+
exe = ThreadPoolExecutor()
9+
# report the status of the thread pool
10+
print(exe._max_workers)
11+
# shutdown the thread pool
12+
exe.shutdown()

src/lesson02_initialize_threads.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# SuperFastPython.com
2+
# example initializing worker threads in the pool
3+
from time import sleep
4+
from concurrent.futures import ThreadPoolExecutor
5+
6+
# custom function to be executed in a worker thread
7+
def task(number):
8+
# report a message
9+
print(f'Worker executing task {number}...')
10+
# block for a moment
11+
sleep(1)
12+
13+
# initialize a worker in the thread pool
14+
def init():
15+
# report a message
16+
print('Initializing worker...')
17+
18+
# protect the entry point
19+
if __name__ == '__main__':
20+
# create and configure the thread pool
21+
with ThreadPoolExecutor(2, initializer=init) as exe:
22+
# issue tasks to the thread pool
23+
_ = exe.map(task, range(4))

src/lesson02_num_threads.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# SuperFastPython.com
2+
# example of setting a large number number of workers
3+
from time import sleep
4+
from concurrent.futures import ThreadPoolExecutor
5+
6+
# custom task function executed in the thread pool
7+
def task(number):
8+
# block for a moment
9+
sleep(1)
10+
# report a message
11+
if number % 100 == 0:
12+
print(f'>task {number} done')
13+
14+
# protect the entry point
15+
if __name__ == '__main__':
16+
# create a thread pool
17+
with ThreadPoolExecutor(1000) as exe:
18+
# issue many tasks to the pool
19+
_ = exe.map(task, range(1000))

src/lesson02_thread_names.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# SuperFastPython.com
2+
# example of setting the worker thread name prefix
3+
from time import sleep
4+
from concurrent.futures import ThreadPoolExecutor
5+
import threading
6+
7+
# custom task function executed in the thread pool
8+
def task(number):
9+
# block for a moment
10+
sleep(1)
11+
12+
# protect the entry point
13+
if __name__ == '__main__':
14+
# create a thread pool
15+
with ThreadPoolExecutor(4,
16+
thread_name_prefix='Downloader') as exe:
17+
# issue many tasks to the pool
18+
_ = exe.map(task, range(20))
19+
# report all thread names
20+
for thread in threading.enumerate():
21+
print(thread)

src/lesson03_multiple_arguments.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# SuperFastPython.com
2+
# example executing tasks concurrently with multiple arg
3+
from random import random
4+
from time import sleep
5+
from concurrent.futures import ThreadPoolExecutor
6+
7+
# custom function to be executed in a worker thread
8+
def task(number, value):
9+
# report a message
10+
print(f'Task using {value}')
11+
# block for a moment to simulate work
12+
sleep(value)
13+
# return a new value
14+
return number + value
15+
16+
# protect the entry point
17+
if __name__ == '__main__':
18+
# create the thread pool
19+
with ThreadPoolExecutor(4) as exe:
20+
# prepare random numbers between 0 and 1
21+
values = [random() for _ in range(10)]
22+
# issue tasks to execute concurrently
23+
for result in exe.map(task, range(10), values):
24+
# report results
25+
print(result)

0 commit comments

Comments
 (0)