Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
new python example: actor-kill
authorMartin Quinson <martin.quinson@ens-rennes.fr>
Tue, 8 Jan 2019 18:30:11 +0000 (19:30 +0100)
committerMartin Quinson <martin.quinson@ens-rennes.fr>
Tue, 8 Jan 2019 22:17:12 +0000 (23:17 +0100)
examples/python/CMakeLists.txt
examples/python/actor-kill/actor-kill.py [new file with mode: 0644]
examples/python/actor-kill/actor-kill.tesh [new file with mode: 0644]
src/bindings/python/simgrid_python.cpp

index 6f1c596..709ee0f 100644 (file)
@@ -1,4 +1,4 @@
-foreach(example actor-create actor-daemon actor-join actor-migrate actor-suspend actor-yield
+foreach(example actor-create actor-daemon actor-join actor-kill actor-migrate actor-suspend actor-yield
                 exec-basic)
   set(tesh_files    ${tesh_files}   ${CMAKE_CURRENT_SOURCE_DIR}/${example}/${example}.tesh)
   set(examples_src  ${examples_src} ${CMAKE_CURRENT_SOURCE_DIR}/${example}/${example}.py)
                 exec-basic)
   set(tesh_files    ${tesh_files}   ${CMAKE_CURRENT_SOURCE_DIR}/${example}/${example}.tesh)
   set(examples_src  ${examples_src} ${CMAKE_CURRENT_SOURCE_DIR}/${example}/${example}.py)
diff --git a/examples/python/actor-kill/actor-kill.py b/examples/python/actor-kill/actor-kill.py
new file mode 100644 (file)
index 0000000..bfa31a3
--- /dev/null
@@ -0,0 +1,74 @@
+# Copyright (c) 2017-2018. 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 simgrid import *
+import sys
+
+
+def victimA_fun():
+    this_actor.on_exit(lambda: this_actor.info("I have been killed!"))
+    this_actor.info("Hello!")
+    this_actor.info("Suspending myself")
+    this_actor.suspend()                        # - Start by suspending itself
+    # - Then is resumed and start to execute a task
+    this_actor.info("OK, OK. Let's work")
+    this_actor.execute(1e9)
+    # - But will never reach the end of it
+    this_actor.info("Bye!")
+
+
+def victimB_fun():
+    this_actor.info("Terminate before being killed")
+
+
+def killer():
+    this_actor.info("Hello!")  # - First start a victim process
+    victimA = Actor.create("victim A", Host.by_name("Fafard"), victimA_fun)
+    victimB = Actor.create("victim B", Host.by_name("Jupiter"), victimB_fun)
+    this_actor.sleep_for(10)  # - Wait for 10 seconds
+
+    # - Resume it from its suspended state
+    this_actor.info("Resume the victim A")
+    victimA.resume()
+    this_actor.sleep_for(2)
+
+    this_actor.info("Kill the victim A")   # - and then kill it
+    this_actor.kill(victimA.pid)  # Kill by PID is legit
+
+    this_actor.sleep_for(1)
+
+    # that's a no-op, there is no zombies in SimGrid
+    this_actor.info("Kill victimB, even if it's already dead")
+    victimB.kill()
+
+    this_actor.sleep_for(1)
+
+    this_actor.info("Start a new actor, and kill it right away")
+    victimC = Actor.create("victim C", Host.by_name("Jupiter"), victimA_fun)
+    victimC.kill()
+
+    this_actor.sleep_for(1)
+
+    this_actor.info("Killing everybody but myself")
+    this_actor.kill_all()
+
+    this_actor.info("OK, goodbye now. I commit a suicide.")
+    this_actor.exit()
+
+    this_actor.info(
+        "This line never gets displayed: I'm already dead since the previous line.")
+
+
+if __name__ == '__main__':
+    e = Engine(sys.argv)
+    if len(sys.argv) < 2:
+        raise AssertionError(
+            "Usage: actor-kill.py platform_file [other parameters]")
+
+    e.load_platform(sys.argv[1])     # Load the platform description
+    # Create and deploy killer process, that will create the victim actors
+    Actor.create("killer", Host.by_name("Tremblay"), killer)
+
+    e.run()
diff --git a/examples/python/actor-kill/actor-kill.tesh b/examples/python/actor-kill/actor-kill.tesh
new file mode 100644 (file)
index 0000000..422e40a
--- /dev/null
@@ -0,0 +1,16 @@
+#!/usr/bin/env tesh
+
+$ python3 ${bindir:=.}/actor-kill.py ${platfdir}/small_platform.xml "--log=root.fmt:[%10.6r]%e(%P@%h)%e%m%n"
+> [  0.000000] (killer@Tremblay) Hello!
+> [  0.000000] (victim A@Fafard) Hello!
+> [  0.000000] (victim A@Fafard) Suspending myself
+> [  0.000000] (victim B@Jupiter) Terminate before being killed
+> [ 10.000000] (killer@Tremblay) Resume the victim A
+> [ 10.000000] (victim A@Fafard) OK, OK. Let's work
+> [ 12.000000] (killer@Tremblay) Kill the victim A
+> [ 12.000000] (victim A@Fafard) I have been killed!
+> [ 13.000000] (killer@Tremblay) Kill victimB, even if it's already dead
+> [ 14.000000] (killer@Tremblay) Start a new actor, and kill it right away
+> [ 14.000000] (victim C@Jupiter) I have been killed!
+> [ 15.000000] (killer@Tremblay) Killing everybody but myself
+> [ 15.000000] (killer@Tremblay) OK, goodbye now. I commit a suicide.
index 21cd88c..a3acac5 100644 (file)
@@ -72,6 +72,13 @@ PYBIND11_MODULE(simgrid, m)
   m2.def("yield_", &simgrid::s4u::this_actor::yield,
          "Yield the actor, see :cpp:func:`void simgrid::s4u::this_actor::yield()`");
   m2.def("exit", &simgrid::s4u::this_actor::exit, "kill the current actor");
   m2.def("yield_", &simgrid::s4u::this_actor::yield,
          "Yield the actor, see :cpp:func:`void simgrid::s4u::this_actor::yield()`");
   m2.def("exit", &simgrid::s4u::this_actor::exit, "kill the current actor");
+  m2.def("kill", [](py::int_ pid) { Actor::kill(pid); }, "Kill an actor by pid");
+  m2.def("kill_all", &Actor::kill_all, "Kill all actors but the caller.");
+
+  m2.def(
+      "on_exit",
+      [](py::function fun) { simgrid::s4u::this_actor::on_exit([fun](int ignored, void* data) { fun(); }, nullptr); },
+      "");
 
   /* Class Engine */
   py::class_<Engine>(m, "Engine", "Simulation Engine, see :ref:`class s4u::Engine <API_s4u_Engine>`")
 
   /* Class Engine */
   py::class_<Engine>(m, "Engine", "Simulation Engine, see :ref:`class s4u::Engine <API_s4u_Engine>`")
@@ -172,11 +179,15 @@ PYBIND11_MODULE(simgrid, m)
            },
            "Create an actor from a function or an object, see :cpp:func:`simgrid::s4u::Actor::create()`")
       .def_property("host", &Actor::get_host, &Actor::migrate, "The host on which this actor is located")
            },
            "Create an actor from a function or an object, see :cpp:func:`simgrid::s4u::Actor::create()`")
       .def_property("host", &Actor::get_host, &Actor::migrate, "The host on which this actor is located")
+      .def_property_readonly("pid", &Actor::get_pid, "The PID (unique identifier) of this actor.")
       .def("daemonize", &Actor::daemonize,
            "This actor will be automatically terminated when the last non-daemon actor finishes, see :cpp:func:`void "
            "simgrid::s4u::Actor::daemonize()`")
       .def("join", py::overload_cast<double>(&Actor::join),
            "Wait for the actor to finish, see :cpp:func:`void simgrid::s4u::Actor::join(double)`", py::arg("timeout"))
       .def("daemonize", &Actor::daemonize,
            "This actor will be automatically terminated when the last non-daemon actor finishes, see :cpp:func:`void "
            "simgrid::s4u::Actor::daemonize()`")
       .def("join", py::overload_cast<double>(&Actor::join),
            "Wait for the actor to finish, see :cpp:func:`void simgrid::s4u::Actor::join(double)`", py::arg("timeout"))
+      .def("kill", [](py::int_ pid) { Actor::kill(pid); }, "Kill an actor by pid")
+      .def("kill", [](ActorPtr act) { act->kill(); }, "Kill that actor")
+      .def("kill_all", &Actor::kill_all, "Kill all actors but the caller.")
       .def("migrate", &Actor::migrate,
            "Moves that actor to another host, see :cpp:func:`void simgrid::s4u::Actor::migrate()`", py::arg("dest"))
       .def("self", &Actor::self, "Retrieves the current actor, see :cpp:func:`void simgrid::s4u::Actor::self()`")
       .def("migrate", &Actor::migrate,
            "Moves that actor to another host, see :cpp:func:`void simgrid::s4u::Actor::migrate()`", py::arg("dest"))
       .def("self", &Actor::self, "Retrieves the current actor, see :cpp:func:`void simgrid::s4u::Actor::self()`")