diff --git a/docs/tutorials/deadlock.py b/docs/tutorials/deadlock.py new file mode 100644 index 00000000..aea9a726 --- /dev/null +++ b/docs/tutorials/deadlock.py @@ -0,0 +1,54 @@ +#!/usr/bin/env + +import os +import threading +import time + + +def process1(lock1, lock2): + print("Process 1: Trying to acquire lock1") + lock1.acquire() + print("Process 1: lock1 acquired") + time.sleep(1) + + print("Process 1: Trying to acquire lock2") + lock2.acquire() + print("Process 1: lock2 acquired") + + # Release locks + lock2.release() + lock1.release() + print("Process 1: Released both locks") + + +def process2(lock1, lock2): + print("Process 2: Trying to acquire lock2") + lock2.acquire() + print("Process 2: lock2 acquired") + time.sleep(1) + + print("Process 2: Trying to acquire lock1") + lock1.acquire() + print("Process 2: lock1 acquired") + + # Release locks + lock1.release() + lock2.release() + print("Process 2: Released both locks") + + +if __name__ == "__main__": + print(f"Process ID {os.getpid()}") + lock1 = threading.Lock() + lock2 = threading.Lock() + + p1 = threading.Thread(target=process1, args=(lock1, lock2)) + p2 = threading.Thread(target=process2, args=(lock1, lock2)) + + p1.start() + p2.start() + + p1.join() + p2.join() + + print("Finished execution") diff --git a/docs/tutorials/deadlock.rst b/docs/tutorials/deadlock.rst new file mode 100644 index 00000000..b4958d4e --- /dev/null +++ b/docs/tutorials/deadlock.rst @@ -0,0 +1,92 @@ +Deadlock +=============================== + +Intro +--------- + +This lesson is meant to familiarize you with PyStack with a classical problem of locks acquisition. + +We will intentionally perform a deadlock, it a classic concurrency problem where improper ordering of lock acquisition can lead to deadlock, +a situation where two or more threads are waiting for each other to release resources, causing the program to hang indefinitely. + +Development Environment Setup +----------------------------- + +Navigate to the `PyStack GitHub repo `_ and get a copy of the +source code. You can either clone it, or just download the zip, whatever is your preference here. + +You will also need a terminal with ``python3`` installed, preferably one of the latest versions. + +Once you have the repo ready to navigate, ``cd`` into the docs/tutorials folder: + +.. code:: shell + + cd docs/tutorials/ + +It is here where we will be running the tests and exercises for the remainder of the tutorial. +For reference here are the official `python3 venv docs `_. +You can also just follow along with the commands below. + +Let's go ahead and setup our virtual environment. + +.. code:: shell + + python3 -m venv .venv + +Once your virtual environment has been created, you can activate it like so: + +.. code:: shell + + source .venv/bin/activate + +You can confirm activation was successful if your terminal prompt is prefixed with ``(.venv)``. +With our virtual environment ready, we can go ahead and install all the dependencies required +for the tutorial. + +.. code:: shell + + python3 -m pip install -r requirements-tutorial.txt + +Keep your virtual environment activated for the rest of the tutorial, and you should be able to run +any of the commands in the exercises. + +PyStack remote use +------------------------ + +PyStack remote has the ability analyze the status of a running (remote) process. + +Executing the deadlock +^^^^^^^^^^^^^^^^^^^^^^ + +Assuming that we are in the `tutorials` directory, we can run the `deadlock script `_ with: + +.. code:: shell + + python3 deadlock.py + +This script will intentionally perform a deadlock and the first message will contain the process ID. +Another option is to find it with: + +.. code:: shell + + ps | grep deadlock.py + +After the deadlock occurs we can use the PyStack command to analyze the process (replace the pid with the number of the process): + +.. code:: shell + + pystack remote pid + + +Potentially it will appear an `Operation not permitted` error. If it is your case use this command instead: + +.. code:: shell + + sudo -E pystack remote pid + + +Understanding the results +^^^^^^^^^^^^^^^^^^^^^^^^^ + +Notice that each section is displaying a running thread and linking the exactly line that is related to it. +This way we can successful diagnose that there are a improper ordering of lock acquisition. diff --git a/docs/tutorials/requirements-tutorial.txt b/docs/tutorials/requirements-tutorial.txt new file mode 100644 index 00000000..143e4f09 --- /dev/null +++ b/docs/tutorials/requirements-tutorial.txt @@ -0,0 +1 @@ +pystack