Тема: мережі Петрі, багатопотокове обчислення прикладу
Завдання. За допомогою мережі Петрі виконати (багатопотокове) обчислення прикладу Zn = SIN( Un + COS( Vn ) ) * COS( SIN( Un + Vn ) )

Кому лінь читати статтю про мережі Петрі, дивіться короткі пояснення
коло - це Вузол
рисочка або чотирикутник - Стан
Якщо вузол маркований (має 1 або більше крапку в колі) то можна здійснювати перехід на ін. вузол.
Стан перевіряє чи всі вузли марковані, якщо це так то здійсниться перехід.
Але є багато чого іншого, наприклад заперечення, вага дуг та інше.
#include <iostream>
#include <Windows.h>
#include <process.h>
#include <cmath>
/*
Zn = SIN( Un + COS( Vn ) ) * COS( SIN( Un + Vn ) )
*/
namespace example
{
    struct sMathOperation
    {
        sMathOperation() = default;
        sMathOperation(void *par);
        double a;
        double b;
        double result;
    };
    sMathOperation::sMathOperation(void *par)
    {
        sMathOperation *obj = reinterpret_cast<sMathOperation*>(par);
        this->a = obj->a;
        this->b = obj->b;
        this->result = obj->result;
    }    
    struct sMathFunction
    {
        sMathFunction() = default;
        sMathFunction(void *par);
        double (*mathFunction)(double);
        double a;
        double result;
    };
    sMathFunction::sMathFunction(void *par)
    {
        sMathFunction *obj = reinterpret_cast<sMathFunction*>(par);
        this->mathFunction = obj->mathFunction;
        this->a = obj->a;
        this->result = obj->result;
    }
    class example
    {
    public:
        example(double Un_, double Vn_);
        double getResult();
    private:
        static void add(void *par);
        static void multiply(void *par);
        static void mathFunction(void *par);
        double Un;
        double Vn;
        double result;
    };
    example::example(double Un_, double Vn_) : Un(Un_), Vn(Vn_)
    {        
        //array
        HANDLE hand[2];
        //calculation example Un + Vn
        sMathOperation *sAddOperation = new sMathOperation;
        sAddOperation->a = Un;
        sAddOperation->b = Vn;
        hand[0] = (HANDLE)_beginthread(&example::add, 0, sAddOperation);
        //calculation example COS( Vn )
        sMathFunction *sCosFunction = new sMathFunction;
        sCosFunction->a = Vn;
        sCosFunction->mathFunction = cos;
        hand[1] = (HANDLE)_beginthread(&example::mathFunction, 0, sCosFunction);
        //wait previous operations
        WaitForMultipleObjects(2, hand, true, INFINITE);
        //calculation example SIN( Un + Vn )
        sMathFunction *sSinFunction = new sMathFunction;
        sSinFunction->a = sAddOperation->result;
        sSinFunction->mathFunction = sin;
        hand[0] = (HANDLE)_beginthread(&example::mathFunction, 0, sSinFunction);
        //delete previous object
        delete sAddOperation;        
        //calculation example Un + COS( Vn )
        sAddOperation = new sMathOperation;
        sAddOperation->a = Un;
        sAddOperation->b = sCosFunction->result;
        hand[1] = (HANDLE)_beginthread(&example::add, 0, sAddOperation);
        //delete previous object
        delete sCosFunction;
        //wait previous operations
        WaitForMultipleObjects(2, hand, true, INFINITE);
        //calculation example COS( SIN( Un + Vn ) )
        sCosFunction = new sMathFunction;
        sCosFunction->a = sSinFunction->result;
        sCosFunction->mathFunction = cos;
        hand[0] = (HANDLE)_beginthread(&example::mathFunction, 0, sCosFunction);
        //delete previous object
        delete sSinFunction;
        //calculation example SIN( Un + COS( Vn ) )
        sSinFunction = new sMathFunction;
        sSinFunction->a = sAddOperation->result;
        sSinFunction->mathFunction = sin;
        hand[1] = (HANDLE)_beginthread(&example::mathFunction, 0, sSinFunction);
        //delete previous object
        delete sAddOperation;
        //wait previous operations
        WaitForMultipleObjects(2, hand, true, INFINITE);
        //calculation example SIN( Un + COS( Vn ) ) * COS( SIN( Un + Vn ) )
        sMathOperation *sMultiplyOperation = new sMathOperation;
        sMultiplyOperation->a = sCosFunction->result;
        sMultiplyOperation->b = sSinFunction->result;
        hand[0] = (HANDLE)_beginthread(&example::multiply, 0, sMultiplyOperation);
        //delete previous objects
        delete sCosFunction;
        delete sSinFunction;
        //wait previous operation
        WaitForSingleObject(hand[0], INFINITE);
        
        //result        
        result = sMultiplyOperation->result;
        //delete previous object
        delete sMultiplyOperation;
    }
    double example::getResult()
    {
        return result;
    }
    void example::add(void *par)
    {
        sMathOperation *obj = (sMathOperation *)par;
        obj->result = obj->a + obj->b;
    }
    void example::multiply(void *par)
    {
        sMathOperation *obj = (sMathOperation *)par;
        obj->result = obj->a * obj->b;
    }
    
    void example::mathFunction(void *par)
    {
        sMathFunction *obj = (sMathFunction *)par;
        obj->result = obj->mathFunction(obj->a);
    }
}
int main(int argc, char *argv[]) try
{    
    double Un,
        Vn;
    //get Un, Vn
    std::cout << "Enter Un ->";
    std::cin >> Un;
    std::cout << "Enter Vn ->";
    std::cin >> Vn;
    //multi-threaded
    example::example obj(Un, Vn);
    //single-threaded
    double Zn;
    Zn = sin(Un + cos(Vn)) * cos(sin(Un + Vn));
    //output results
    std::cout << "(multi-threaded) Zn = " << obj.getResult() << std::endl;    
    std::cout << "(single-threaded) Zn = " << Zn << std::endl;
    
    system("pause");
    return 0;
}
catch (...)
{
    std::cout << "\ncritical error!\n";
    system("pause");
    return -1;
}В ролі "стану" виступають функції WaitForMultiplyObjects i WaitForSingleObject, вони чекають виконання попередніх дій тим самим не даючи запустити програмі нові потоки.
Я дивився як можна у функцію, що буде виконуватися новим потоком, передати декілька аргументів і знайшов пораду використовувати структури (struct), а в функцію передавати об'єкт структури
Ось і все, не знаю чи правильно я зробив (можливо це робиться якось простіше), але програма робити і показує правильний результат
 ?