Загрузка...

Не понимаю как работает многопоточность

Тема в разделе C/C++ создана пользователем Muha665161 21 апр 2025. 209 просмотров

Загрузка...
  1. Muha665161
    Muha665161 Автор темы 21 апр 2025 66 3 дек 2019
    Не понимаю, как синхронизировать потоки и вообще их юзать. Использовать PIPE нужно обязательно. Вроде все по докам сделал, а как заставить заработать не понимаю. Чат гпт и прочая нечесть не помогают...

    C

    #include <iostream>
    #include <Windows.h>
    #include <math.h>

    const char* PIPE = "\\\\.\\pipe\\hypotenuse_pipe";
    CRITICAL_SECTION cs_finished;
    volatile bool finished = false;


    DWORD WINAPI square_thread(LPVOID param)
    {
    HANDLE hPipeRead = CreateFile(PIPE, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
    HANDLE hPipeWrite = CreateFile(PIPE, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
    if (hPipeRead == INVALID_HANDLE_VALUE || hPipeWrite == INVALID_HANDLE_VALUE)
    {
    return 1;
    }

    double value;
    DWORD bytesRead, bytesWritten;
    for (int i = 0; i < 2; ++i)
    {
    EnterCriticalSection(&cs_finished);
    if (finished)
    {
    LeaveCriticalSection(&cs_finished);
    break;
    }
    LeaveCriticalSection(&cs_finished);

    if (ReadFile(hPipeRead, &value, sizeof(double), &bytesRead, NULL) &&
    bytesRead == sizeof(double))
    {
    double result = value * value;
    WriteFile(hPipeWrite, &result, sizeof(double), &bytesWritten, NULL);
    }
    }

    CloseHandle(hPipeRead);
    CloseHandle(hPipeWrite);
    return 0;
    }



    DWORD WINAPI sum_thread(LPVOID param)
    {
    HANDLE hPipeRead = CreateFile(PIPE, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
    HANDLE hPipeWrite = CreateFile(PIPE, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
    if (hPipeRead == INVALID_HANDLE_VALUE || hPipeWrite == INVALID_HANDLE_VALUE)
    {
    return 1;
    }

    EnterCriticalSection(&cs_finished);
    if (finished)
    {
    LeaveCriticalSection(&cs_finished);
    CloseHandle(hPipeRead);
    CloseHandle(hPipeWrite);
    return 0;
    }
    LeaveCriticalSection(&cs_finished);

    double value1, value2;
    DWORD bytesRead, bytesWritten;
    if (ReadFile(hPipeRead, &value1, sizeof(double), &bytesRead, NULL) &&
    bytesRead == sizeof(double) &&
    ReadFile(hPipeRead, &value2, sizeof(double), &bytesRead, NULL) &&
    bytesRead == sizeof(double))
    {
    double result = value1 + value2;
    WriteFile(hPipeWrite, &result, sizeof(double), &bytesWritten, NULL);
    }

    CloseHandle(hPipeRead);
    CloseHandle(hPipeWrite);
    return 0;
    }


    DWORD WINAPI sqrt_thread(LPVOID param)
    {
    HANDLE hPipeRead = CreateFile(PIPE, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
    HANDLE hPipeWrite = CreateFile(PIPE, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
    if (hPipeRead == INVALID_HANDLE_VALUE || hPipeWrite == INVALID_HANDLE_VALUE)
    {
    return 1;
    }

    EnterCriticalSection(&cs_finished);
    if (finished)
    {
    LeaveCriticalSection(&cs_finished);
    CloseHandle(hPipeRead);
    CloseHandle(hPipeWrite);
    return 0;
    }
    LeaveCriticalSection(&cs_finished);

    double value;
    DWORD bytesRead, bytesWritten;
    if (ReadFile(hPipeRead, &value, sizeof(double), &bytesRead, NULL)
    && bytesRead == sizeof(double))
    {
    double result = sqrt(value);
    WriteFile(hPipeWrite, &result, sizeof(double), &bytesWritten, NULL);
    }

    CloseHandle(hPipeRead);
    CloseHandle(hPipeWrite);
    return 0;
    }


    int main()
    {
    InitializeCriticalSection(&cs_finished);

    HANDLE hPipe = CreateNamedPipe(
    PIPE,
    PIPE_ACCESS_DUPLEX,
    PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
    PIPE_UNLIMITED_INSTANCES,
    4096,
    4096,
    0,
    NULL
    );

    if (hPipe == INVALID_HANDLE_VALUE)
    {
    return 1;
    }

    DWORD t1, t2, t3;
    HANDLE h1 = CreateThread(NULL, 0, square_thread, NULL, 0, &t1);
    HANDLE h2 = CreateThread(NULL, 0, sum_thread, NULL, 0, &t2);
    HANDLE h3 = CreateThread(NULL, 0, sqrt_thread, NULL, 0, &t3);


    if (!ConnectNamedPipe(hPipe, NULL) && GetLastError() != ERROR_PIPE_CONNECTED)
    {
    CloseHandle(hPipe);
    return 1;
    }
    double a, b;
    std::cout << "Enter a = ";
    std::cin >> a;
    std::cout << "Enter b = ";
    std::cin >> b;


    DWORD bytesWritten;
    WriteFile(hPipe, &a, sizeof(double), &bytesWritten, NULL);
    WriteFile(hPipe, &b, sizeof(double), &bytesWritten, NULL);

    double result;
    DWORD bytesRead;
    if (ReadFile(hPipe, &result, sizeof(double), &bytesRead, NULL) && bytesRead == sizeof(double))
    {
    std::cout << "result = " << result << std::endl;
    }

    EnterCriticalSection(&cs_finished);
    finished = true;
    LeaveCriticalSection(&cs_finished);

    WaitForSingleObject(h1, INFINITE);
    WaitForSingleObject(h2, INFINITE);
    WaitForSingleObject(h3, INFINITE);

    CloseHandle(h1);
    CloseHandle(h2);
    CloseHandle(h3);
    CloseHandle(hPipe);
    DeleteCriticalSection(&cs_finished);

    return 0;
    }
     
  2. H1M88D4S
    H1M88D4S 22 апр 2025 8 27 мар 2025
    винапи потоки дроч :fap:
     
  3. GreatestDreamer
    у тя прям большие проблемы с EnterCriticalSection и LeaveCriticalSection.
    Почитай про атомарные операции и что это такое. Это даст базовое понимание, что делают данные функции.
     
Top