Skip to content

Commit

Permalink
Add tutorial about deadlock
Browse files Browse the repository at this point in the history
Signed-off-by: Matheus Nascimento <[email protected]>
  • Loading branch information
Matheus Nascimento committed May 20, 2024
1 parent dba965a commit 0b3446d
Show file tree
Hide file tree
Showing 3 changed files with 147 additions and 0 deletions.
54 changes: 54 additions & 0 deletions docs/tutorials/deadlock.py
Original file line number Diff line number Diff line change
@@ -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")
92 changes: 92 additions & 0 deletions docs/tutorials/deadlock.rst
Original file line number Diff line number Diff line change
@@ -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 <https://github.com/bloomberg/pystack>`_ 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 <https://docs.python.org/3/library/venv.html>`_.
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 <https://github.com/bloomberg/pystack/tree/main/docs/tutorials/deadlock.py>`_ 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.
1 change: 1 addition & 0 deletions docs/tutorials/requirements-tutorial.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pystack

0 comments on commit 0b3446d

Please sign in to comment.