Search code examples
c++multithreadingumlmutex

How to draw UML to illustrate 2 threads working on a critical section


I have a small program that runs 2 threads on the same critical section and uses mutex. The program works fine. But I would like to draw a UML, referably activity or state diagram, illustrating that the 2 threads runs the same critical section, not different parts of the codes. Please help me revise my UML.

Below is the source code:

#include <iostream>
#include <thread>
#include <mutex>
#include <stdio.h>
/* Global variables where both threads have access to*/
std::mutex myMutex;
int globalVariable = 1;
/* CRITICAL SECTION */
void hello()
{
    myMutex.lock();
    for (int counter =0 ; counter< 100; counter++){
        //std::lock_guard<std::mutex> lock(myMutex);
        printf("%d ",std::this_thread::get_id() );      //print the id of the thread that executes the for loop
        globalVariable++;
    }
    printf("Thread with id = %d runs. Counter is %d \n", std::this_thread::get_id(), msg) ; //print the result counter value and thread id that finishes the for loop
    myMutex.unlock();
}
int main()
{
    std::thread t1(hello);
    std::thread t2(hello);
    t1.join();
    t2.join();

Below is my UML. It definitely has some faults enter image description here


Solution

  • It definitely has some faults

    yes, for instance :

    • both join finish before the execution of hello, this is impossible
    • each join are executed in one the separated threads, this must be done by main
    • there is a fork but no join (the UML one)
    • after the action unlock the flow goes to t2.join which is false and produces a never ending loop

    In a sequence diagram it is possible to use a combined fragment critical, but there is no specific notation in an activity to indicate a critical region.

    A first possibility is to not try to indicate the critical section, to use call operation actions on the mutex to call lock and unlock, and the reader has to know what that means. You can also add a note to help the reader. For instance (the call to hello is replaced by its body and I replaced the loop by an opaque action to simplify) :

    enter image description here

    Or with the partition :

    enter image description here

    A second way is to use a combined fragment critical even this is not specified in the norm, hoping the reader understand ( may be with the help of a note ) :

    enter image description here

    Of course you can combine using the first way and also drawing the combined fragment critical hoping to help the reader :

    enter image description here

    A third way if you do not want to have actions corresponding to C++ is to emulate the critical region using accept/send signal action, but to be frank this is not really easy to read/understand :

    enter image description here

    or with the partition :

    enter image description here

    Of course it is also possible to do the first send signal action after the fork :

    enter image description here