1# test using lock to coordinate access to global mutable objects
2#
3# MIT license; Copyright (c) 2016 Damien P. George on behalf of Pycom Ltd
4
5try:
6    import utime as time
7except ImportError:
8    import time
9import _thread
10
11
12def fac(n):
13    x = 1
14    for i in range(1, n + 1):
15        x *= i
16    return x
17
18
19def thread_entry():
20    while True:
21        with jobs_lock:
22            try:
23                f, arg = jobs.pop(0)
24            except IndexError:
25                return
26        ans = f(arg)
27        with output_lock:
28            output.append((arg, ans))
29
30
31# create a list of jobs
32jobs = [(fac, i) for i in range(20, 80)]
33jobs_lock = _thread.allocate_lock()
34n_jobs = len(jobs)
35
36# create a list to store the results
37output = []
38output_lock = _thread.allocate_lock()
39
40# spawn threads to do the jobs
41for i in range(4):
42    _thread.start_new_thread(thread_entry, ())
43
44# wait for the jobs to complete
45while True:
46    with jobs_lock:
47        if len(output) == n_jobs:
48            break
49    time.sleep(1)
50
51# sort and print the results
52output.sort(key=lambda x: x[0])
53for arg, ans in output:
54    print(arg, ans)
55