+# Copyright (c) 2010-2022. The SimGrid Team. All rights reserved.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of the license (GNU LGPL) which comes with this package.
+
from argparse import ArgumentParser
from dataclasses import dataclass
import sys
help='path to the platform description'
)
parser.add_argument(
- '--workers',
+ '--actors',
type=int,
default=6,
- help='number of workers to start'
- )
- parser.add_argument(
- '--trials-before-success',
- type=int,
- default=0,
- help='number of attempts each workers need to make before getting the correct answer'
- ' (i.e. number of simulated failures)'
+ help='how many pairs of actors should be started'
)
return parser
value: int
-class CalculationError(RuntimeError):
- """ Fake calculation error
- """
- pass
-
-
-def worker_context_manager(mutex: Mutex, trials_before_success: int, result: ResultHolder):
- """ Worker that uses a context manager to acquire/release the shared mutex
- :param mutex: Shared mutex that guards read/write access to the shared result
- :param trials_before_success: Number of simulated calculation failures before success
- :param result: Shared result which will be updated by the worker
- """
- this_actor.info(f"I just started")
- for trial in range(trials_before_success + 1):
- try:
- with mutex:
- this_actor.info(f"acquired the mutex with context manager")
- this_actor.sleep_for(1)
- if trial < trials_before_success:
- raise CalculationError("did not manage to find the correct answer")
- result.value += 1
- this_actor.info(f"updated shared result, which is now {result.value}")
- except CalculationError as e:
- this_actor.warning(f"ran in trouble while calculating: {e}. Will retry shortly.")
- finally:
- this_actor.info(f"released the mutex after leaving the context manager")
- this_actor.info("Bye now!")
-
-
-def worker(mutex: Mutex, trials_before_success: int, result: ResultHolder):
- """ Worker that manually acquires/releases the shared mutex
- :param mutex: Shared mutex that guards read/write access to the shared result
- :param trials_before_success: Number of simulated calculation failures before success
- :param result: Shared result which will be updated by the worker
- """
- this_actor.info(f"I just started")
- for trial in range(trials_before_success + 1):
- try:
- mutex.lock()
- this_actor.info(f"acquired the mutex manually")
- this_actor.sleep_for(1)
- if trial < trials_before_success:
- raise CalculationError("did not manage to find the correct answer")
- result.value += 1
- this_actor.info(f"updated shared result, which is now {result.value}")
- except CalculationError as e:
- this_actor.warning(f"ran in trouble while calculating: {e}. Will retry shortly.")
- finally:
- this_actor.info(f"released the mutex manually")
- mutex.unlock()
- this_actor.info("Bye now!")
+def worker_context_manager(mutex: Mutex, result: ResultHolder):
+ with mutex:
+ this_actor.info(f"Hello simgrid, I'm ready to compute after acquiring the mutex from a context manager")
+ result.value += 1
+ this_actor.info(f"I'm done, good bye")
+
+
+def worker(mutex: Mutex, result: ResultHolder):
+ mutex.lock()
+ this_actor.info("Hello simgrid, I'm ready to compute after a regular lock")
+ result.value += 1
+ mutex.unlock()
+ this_actor.info("I'm done, good bye")
def master(settings):
- """ Spawns `--workers` workers and wait until they have all updated the shared result, then displays it before
- leaving. Alternatively spawns `worker_context_manager()` and `worker()` workers.
- :param settings: Simulation settings
- """
- result = ResultHolder(value=0)
- mutex = Mutex()
- actors = []
- for i in range(settings.workers):
- use_worker_context_manager = i % 2 == 0
- actors.append(
- Actor.create(
- f"worker-{i}(mgr)" if use_worker_context_manager else f"worker-{i}",
- Host.by_name("Jupiter" if use_worker_context_manager else "Tremblay"),
- worker_context_manager if use_worker_context_manager else worker,
- mutex,
- settings.trials_before_success,
- result
- )
- )
- [actor.join() for actor in actors]
- this_actor.info(f"The final result is: {result.value}")
+ results = [ResultHolder(value=0) for _ in range(settings.actors)]
+ for i in range(settings.actors):
+ mutex = Mutex()
+ Actor.create(f"worker-{i}(mgr)", Host.by_name("Jupiter"), worker_context_manager, mutex, results[i])
+ Actor.create(f"worker-{i}", Host.by_name("Tremblay"), worker, mutex, results[i])
+ this_actor.sleep_for(10)
+ for i in range(settings.actors):
+ this_actor.info(f"Result[{i}] -> {results[i].value}")
+ this_actor.info("I'm done, good bye")
def main():