Форум программистов, компьютерный форум, киберфорум
C/C++: WinAPI
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.67/9: Рейтинг темы: голосов - 9, средняя оценка - 4.67
0 / 0 / 0
Регистрация: 26.02.2018
Сообщений: 125

Синхронизация потоков

06.06.2018, 14:45. Показов 2022. Ответов 11
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Добрый день. Помогите пожалуйста написать программу на С++ по синхронизации потоков. Задание такое: поток А формирует общий ресурс - текстовый файл вещественных чисел. Поток В обращается к общему ресурсу для считывания данных и находит их общее среднее арифметическое. поток С выводит результат в окно программы. Потоки принадлежат двум процессам. Защиту общего ресурса выполнить с помощью мьютекса. Заранее благодарна за помощь.
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
06.06.2018, 14:45
Ответы с готовыми решениями:

Синхронизация потоков
Здравствуйте, уважаемые форумчане! Нужно мне написать прогу на синхронизацию. Задача такая: есть поток, пишущий в канал по-байтно (вернее...

Синхронизация потоков
Нужно: Выполнение нескольких арифметических операций разного приоритета. Оперировать с помощью мьютексов и кретических секций, как...

Синхронизация потоков
Помогите обеспечить синхронизацию потоков const int j=20; hSemaphore = CreateSemaphore(NULL, 0, 1, NULL); DWORD __stdcall...

11
2735 / 890 / 331
Регистрация: 10.02.2018
Сообщений: 2,111
06.06.2018, 15:27
Как поток А формирует файл, откуда он берёт числа?
0
0 / 0 / 0
Регистрация: 26.02.2018
Сообщений: 125
06.06.2018, 15:52  [ТС]
Думаю, что их можно или функцией srand () генерировать или другим удобным Вам способом. В задании не указано конкретно.

Добавлено через 7 минут
Если Вы сможете написать такую программу, то напишите пожалуйста комментарии к ней и описание программы (входные/выходные данные, логическая структура программы). Буду очень благодарна.
0
2735 / 890 / 331
Регистрация: 10.02.2018
Сообщений: 2,111
06.06.2018, 16:07
Программу написать не сложно, только я её логику не понимаю.
Если сможете объяснить, то можно и написать.
Вот запускаете вы пишущую часть. Она, например, записывает 2 случайных числа в файл и завершается. Какой тут смысл что-то блокировать мьютексом? А читающая программа при запуске считывает файл, считает, выводит результат и завершается. То же смысла в отдельной блокировке никакого нет. Вы даже не успеете запустить две программы одновременно. Первая успеет закончить свою работу до запуска второй.

Или программа должна записывать 100500 миллионов чисел в текстовый файл, или запись и чтение должны как-то работать на постоянной основе передавая друг другу эстафету.
0
0 / 0 / 0
Регистрация: 26.02.2018
Сообщений: 125
06.06.2018, 16:23  [ТС]
Программа не обязательно должна сработать, как бы глупо это не звучало. Главное записать правильно все прототипы API функций и правильно их скомпоновать для выполнения всех условий задания.

Добавлено через 4 минуты
И первый процесс, то есть пишущая часть, будет же вызываться из второго процесса - читающей части. То есть, может, блокировку мьютексом нужно сделать только один раз в какой-то из частей?
0
2735 / 890 / 331
Регистрация: 10.02.2018
Сообщений: 2,111
06.06.2018, 17:50
Вот такой вариант могу предложить
Писатель
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#include "stdafx.h"
#include <windows.h>
 
// ожидание нового нажатия любой кнопки
void WaitAnyKey()
{
    // хендл ввода
    HANDLE hin = GetStdHandle(STD_INPUT_HANDLE);
 
    // чистим буфер
    FlushConsoleInputBuffer(hin);
 
    // цикл ожидания
    while (true)
    {
        DWORD num;
        INPUT_RECORD rec;
        // ждём события
        WaitForSingleObject(hin, INFINITE);
        // проверяем, что событие соответствует нажатию кнопки
        if (ReadConsoleInput(hin, &rec, 1, &num) && (rec.EventType == KEY_EVENT) && (rec.Event.KeyEvent.bKeyDown))
            break;
    }
}
 
// точка входа
int main()
{
    // подготовка генератора случайных чисел
    srand(GetTickCount());
 
    // создание именованного (межпроцессорного) мьютекса без его блокировки
    HANDLE hMutex = CreateMutex(0, FALSE, TEXT("My Multi Process Mutex"));
 
    // подтверждение запуска
    printf("Writer\r\nPress any key for start and lock\r\n");
    WaitAnyKey();
 
    // пытаемся получить доступ к общему ресурсу (бесконечно долго)
    printf("Wait...");
    DWORD ret = WaitForSingleObject(hMutex, INFINITE);
    printf("done\r\n");
 
    // создаём файл
    FILE* file = fopen("test.txt", "w");
    if (!file)
    {
        // сообщаем об ошибке
        printf("Can't create file 'test.txt'\r\n");
    }
    else
    {
        // записываем 100 случайных чисел от -100 до +100
        for (int i = 0; i < 100; i++)
            fprintf(file, "%0.1f ", ((rand() % 2000) - 1000) / 10.0);
 
        // закрытие файла
        fclose(file);
    }
 
    // подтверждение окончания
    printf("Press any key for finish and unlock\r\n");
    WaitAnyKey();
 
    // освобождение мьютекса, позволяем другому процессу получить доступ к общему ресурсу
    ReleaseMutex(hMutex);
 
    // закрытие мьютекса
    CloseHandle(hMutex);
 
    return 0;
}
Читатель
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
#include "stdafx.h"
#include <windows.h>
 
// ожидание нового нажатия любой кнопки
void WaitAnyKey()
{
    // хендл ввода
    HANDLE hin = GetStdHandle(STD_INPUT_HANDLE);
 
    // чистим буфер
    FlushConsoleInputBuffer(hin);
 
    // цикл ожидания
    while (true)
    {
        DWORD num;
        INPUT_RECORD rec;
        // ждём события
        WaitForSingleObject(hin, INFINITE);
        // проверяем, что событие соответствует нажатию кнопки
        if (ReadConsoleInput(hin, &rec, 1, &num) && (rec.EventType == KEY_EVENT) && (rec.Event.KeyEvent.bKeyDown))
            break;
    }
}
 
// структура для потока
struct SThreadData
{
    int cnt;
    double sum;
};
 
// глупый поток вывода результата
DWORD WINAPI MyOutThread(LPVOID ptr)
{
    SThreadData* pData = (SThreadData*)ptr;
 
    // вывод результата
    if (pData)
    {
        printf("count=%d\r\n", pData->cnt);
        if (pData->cnt > 0)
            printf("average=%.2f\r\n", pData->sum / pData->cnt);
    }
 
    return 0;
}
 
// точка входа
int main()
{
    // создание именованного (межпроцессорного) мьютекса без его блокировки
    HANDLE hMutex = CreateMutex(0, FALSE, TEXT("My Multi Process Mutex"));
 
    // подтверждение запуска
    printf("Reader\r\nPress any key for start and lock\r\n");
    WaitAnyKey();
 
    // пытаемся получить доступ к общему ресурсу (бесконечно долго)
    printf("Wait...");
    DWORD ret = WaitForSingleObject(hMutex, INFINITE);
    printf("done\r\n");
 
    // открываем файл
    FILE* file = fopen("test.txt", "r");
    if (!file)
    {
        // сообщаем об ошибке
        printf("Can't open file 'test.txt'\r\n");
    }
    else
    {
        int cnt = 0;
        double num, sum = 0;
 
        // читаем числа и считаем их сумму
        while (fscanf(file, "%lf ", &num) == 1)
        {
            cnt++;
            sum += num;
        }
 
        // вывод результата через поток
        {
            // структура передаваемая потоку
            SThreadData td;
            td.cnt = cnt;
            td.sum = sum;
            // тут будет ID потока
            DWORD id;
            // запуск потока
            HANDLE hThread = CreateThread(0, 0, MyOutThread, &td, 0, &id);
            // ждём пока поток завершится (бесконечно долго)
            WaitForSingleObject(hThread, INFINITE);
            // закрываем хендл потока
            CloseHandle(hThread);
        }
 
        // закрытие файла
        fclose(file);
    }
 
    // подтверждение окончания
    printf("Press any key for finish and unlock\r\n");
    WaitAnyKey();
 
    // освобождение мьютекса, позволяем другому процессу получить доступ к общему ресурсу
    ReleaseMutex(hMutex);
 
    // закрытие мьютекса
    CloseHandle(hMutex);
 
    return 0;
}
Вложения
Тип файла: zip Mutex.zip (137.9 Кб, 8 просмотров)
0
0 / 0 / 0
Регистрация: 26.02.2018
Сообщений: 125
06.06.2018, 21:28  [ТС]
Спасибо большое! То есть, если в задании указано, что потоки принадлежат двум процессам, то должно быть создано 2 программы или лучше все-таки вызвать одну из другой?

Добавлено через 3 минуты
Чтобы реализовать эти 2 процесса в одной программе

Добавлено через 14 минут
Еще такой момент, мьютекс нужен для того, чтобы защитить общий ресурс - текстовый файл, то есть, чтобы с ним работали потоки только одного процесса в конкретный промежуток времени.

Добавлено через 2 минуты
В код еще нужно вписать как-то переменную типа volatile и присвоить ей имя файла

Добавлено через 1 час 11 минут
Буду очень благодарна, если Вы пришлете мне скрины работы программы. У меня морока с запуском чужих программ.
0
2735 / 890 / 331
Регистрация: 10.02.2018
Сообщений: 2,111
07.06.2018, 13:00
лучше все-таки вызвать одну из другой?
Вызов одной из другой не отменяет создания двух разных программ.

Чтобы реализовать эти 2 процесса в одной программе
Это возможно, но это не проще и не наглядней. Нужно делать обработку аргументов командной строки или запрашивать пользователя, что он хочет от запущенной программы.

В код еще нужно вписать как-то переменную типа volatile и присвоить ей имя файла
Не нужно, но если хотите, то можете вписать
1
0 / 0 / 0
Регистрация: 26.02.2018
Сообщений: 125
30.06.2018, 13:02  [ТС]
Спасибо за ответы и за помощь!
0
0 / 0 / 0
Регистрация: 25.02.2020
Сообщений: 3
25.02.2020, 17:33
Извините, у меня ошибка выходит в коде именно на fopen
0
2735 / 890 / 331
Регистрация: 10.02.2018
Сообщений: 2,111
25.02.2020, 18:16
Цитата Сообщение от Khan33 Посмотреть сообщение
Извините, у меня ошибка выходит в коде именно на fopen
Что за ошибка? Неправильный порядок работы программ, читатель запускается раньше писателя? Иногда компилятор ругается на fopen как на не безопасную функцию, и предлагает заменить её на fopen_s.
0
0 / 0 / 0
Регистрация: 23.06.2019
Сообщений: 1
25.02.2020, 23:05
Ygg, почему у меня ошибка с stdafx.h

Добавлено через 2 минуты
Khan33, используйте библиотеки #include <iostream>, #include <fstream>
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
25.02.2020, 23:05
Помогаю со студенческими работами здесь

Синхронизация потоков
Здравствуйте. Подскажите пожалуйста. У меня есть три потока. Мне нужно чтобы они запускались последовательно (1 - 2 -3). Подскажите как это...

Синхронизация потоков
Помогите синхронизировать два потока на Win32 Api. 1й выводит числовую последовательность, 2й - числа Фибоначчи. Выполняются по кругу. ...

Синхронизация потоков
Вот код: #include &quot;iostream&quot; #include &quot;windows.h&quot; using namespace std; char* hydrogenContainer; char* oxygenContainer; int...

Синхронизация потоков
в общем есть код: DWORD WINAPI IndexSystemFile::GetFileFromDrive(void *DriveName){ long hFile = 0; int fRes = 0; ...

Синхронизация потоков
Как переделать с использованием mutex или еще чего нибудь? /*Три нити. Одна генерирует тройки чисел, вторая решает...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
12
Ответ Создать тему
Новые блоги и статьи
Реалии
Hrethgir 01.03.2026
Нет, я не закончил до сих пор симулятор. Эта задача сложнее. Не получилось уйти в плавсостав, но оно и к лучшему, возможно. Точнее получалось - но сварщиком в палубную команду, а это значит, в моём. . .
Ритм жизни
kumehtar 27.02.2026
Иногда приходится жить в ритме, где дел становится всё больше, а вовлечения в происходящее — всё меньше. Плотный график не даёт вниманию закрепиться ни на одном событии. Утро начинается с быстрых,. . .
SDL3 для Web (WebAssembly): Сборка библиотек: SDL3, Box2D, FreeType, SDL3_ttf, SDL3_mixer и SDL3_image из исходников с помощью CMake и Emscripten
8Observer8 27.02.2026
Недавно вышла версия 3. 4. 2 библиотеки SDL3. На странице официальной релиза доступны исходники, готовые DLL (для x86, x64, arm64), а также библиотеки для разработки под Android, MinGW и Visual Studio. . . .
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru