Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Martin's suggestions
[simgrid.git] / examples / python / synchro-mutex / synchro-mutex.py
1 from argparse import ArgumentParser
2 from dataclasses import dataclass
3 import sys
4
5 from simgrid import Actor, Engine, Host, Mutex, this_actor
6
7
8 def create_parser() -> ArgumentParser:
9     parser = ArgumentParser()
10     parser.add_argument(
11         '--platform',
12         type=str,
13         required=True,
14         help='path to the platform description'
15     )
16     parser.add_argument(
17         '--workers',
18         type=int,
19         default=6,
20         help='number of workers to start'
21     )
22     return parser
23
24
25 @dataclass
26 class ResultHolder:
27     value: int
28
29
30 def worker_context_manager(mutex: Mutex, result: ResultHolder):
31     """ Worker that uses a context manager to acquire/release the shared mutex
32     :param mutex: Shared mutex that guards read/write access to the shared result
33     :param result: Shared result which will be updated by the worker
34     """
35     this_actor.info(f"I just started")
36     with mutex:
37         this_actor.info(f"acquired the mutex with context manager")
38         result.value += 1
39         this_actor.info(f"updated shared result, which is now {result.value}")
40     this_actor.info(f"released the mutex after leaving the context manager")
41     this_actor.info("Bye now!")
42
43
44 def worker(mutex: Mutex, result: ResultHolder):
45     """ Worker that manually acquires/releases the shared mutex
46     :param mutex: Shared mutex that guards read/write access to the shared result
47     :param result: Shared result which will be updated by the worker
48     """
49     this_actor.info(f"I just started")
50     mutex.lock()
51     this_actor.info(f"acquired the mutex manually")
52     result.value += 1
53     this_actor.info(f"updated shared result, which is now {result.value}")
54     mutex.unlock()
55     this_actor.info(f"released the mutex manually")
56     this_actor.info("Bye now!")
57
58
59 def master(settings):
60     """ Spawns `--workers` workers and wait until they have all updated the shared result, then displays it before
61         leaving. Alternatively spawns `worker_context_manager()` and `worker()` workers.
62     :param settings: Simulation settings
63     """
64     result = ResultHolder(value=0)
65     mutex = Mutex()
66     actors = []
67     for i in range(settings.workers):
68         use_worker_context_manager = i % 2 == 0
69         actors.append(
70             Actor.create(
71                 f"worker-{i}(mgr)" if use_worker_context_manager else f"worker-{i}",
72                 Host.by_name("Jupiter" if use_worker_context_manager else "Tremblay"),
73                 worker_context_manager if use_worker_context_manager else worker,
74                 mutex,
75                 result
76             )
77         )
78     this_actor.sleep_for(10)
79     this_actor.info(f"The final result is: {result.value}")
80
81
82 def main():
83     settings = create_parser().parse_known_args()[0]
84     e = Engine(sys.argv)
85     e.load_platform(settings.platform)
86     Actor.create("master", Host.by_name("Tremblay"), master, settings)
87     e.run()
88
89
90 if __name__ == "__main__":
91     main()