Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.68/19: Рейтинг темы: голосов - 19, средняя оценка - 4.68
0 / 0 / 1
Регистрация: 15.08.2012
Сообщений: 6

Синхронизация потоков, события, WinAPI

02.08.2013, 12:33. Показов 3742. Ответов 3
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Уважаемые программисты!
Решается такая задача: 5 потоков генерируют псевдослучайные числа, главный поток выводит их, при нажатии "enter" все должно быть остановлено и выведена сумма всех этих чисел.
Я написала это так:
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
#include <windows.h>
#include <stdio.h>
#include <process.h>
#include <ctime> 
#define n 5
int i, data[n]; //i-я ячейка массива соответствует i-му потоку
HANDLE hThread[n], hEvent1, hEvent2;
DWORD  hThreadID[n];
 
void Func (void * pParams) // стартовая функция потоков
{
    srand(GetCurrentThreadId()+time(0));
    while (1)
    { 
        WaitForSingleObject( hEvent2, INFINITE );
        *((int*)pParams) = rand()%100;
        SetEvent( hEvent1 );
    }
}
 
void main()
{
    int sum = 0; // переменная, хранящая сумму всех выводимых чисел
    for(i = 0; i < n; i++)
        data[i] = 0;
 
    hEvent1=CreateEvent( NULL, FALSE, TRUE, NULL );
    hEvent2=CreateEvent( NULL, FALSE, FALSE, NULL );
 
    for(i = 0; i < n; i++)
        hThread[i] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)Func, &data[i], 0, &hThreadID[i]);
    
    while(1)
    {
        WaitForSingleObject( hEvent1, INFINITE );
        for(i = 0; i < n; i++)
            sum += data[i];
        printf("%d %d %d %d %d\n", data[0], data[1], data[2], data[3], data[4]);
        SetEvent( hEvent2 );
        if(GetAsyncKeyState(VK_RETURN)) // при нажатии клавиши "enter" потоки останавливается, выводится сумма
        {
            for(i = 0; i < n; i++)
                SuspendThread(hThread[i]);
            for(i = 0; i < n; i++)
                WaitForSingleObject(hThread[i], 1000); // ждем пока потоки выведут последние числа
            printf("Summ = %d\n", sum);
        }
    }
    for(i = 0; i < n; i++)
        CloseHandle(hThread[i]);
}
В результате получаю либо:

либо:

что не есть правильно.

Подскажите, пожалуйста, как избавиться от последней ситуации?
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
02.08.2013, 12:33
Ответы с готовыми решениями:

Синхронизация потоков
Есть статический класс к которому я хочу обращаться из разных потоков static class MyLog { public: static int log(std::string,...

синхронизация потоков
проблема в следующем: есть 2 потока один считает некоторую сумму в цикле по столбцам матрицы второй должен выводить промежуточную...

Синхронизация потоков
Снова привет. Есть у меня код, который требуется раскидать на потоки. Ниже код: #include &lt;iostream&gt; #include &lt;Windows.h&gt; ...

3
Модератор
 Аватар для vxg
3409 / 2180 / 354
Регистрация: 13.01.2012
Сообщений: 8,454
02.08.2013, 12:51
удивительно что вообще работает... несколько потоков выбрасывают одно и то же событие которое ожидает основной поток который думает что выброс этого события означает что отработали ВСЕ потоки хотя по факту отработать может только один. потом при нажатии клавиши потоки останавливаются и при этом мы ожидаем что они завершаться - интересно когда если они стоят... очень все это интересно
0
0 / 0 / 1
Регистрация: 15.08.2012
Сообщений: 6
02.08.2013, 13:00  [ТС]
vxg, значит надо создать событие для каждого потока?

P.S. Извините, если я туплю
0
Модератор
 Аватар для vxg
3409 / 2180 / 354
Регистрация: 13.01.2012
Сообщений: 8,454
02.08.2013, 13:11
я бы вообще это как то по другому сделал. пальцем в небо - каждый поток формирует число, входит в критическую секцию, пишет в глобальную переменную свой номер, выбрасывает событие 1, ожидает событие 2, выходит из критической секции. основной поток ловит событие 1, читает из переменной номер потока выбросившего это событие, выводит число сформированное этим потоком, выбрасывает событие 2. когда пользователь нажал кнопку основной поток входит во вторую критическую секцию, пишет в глобальную переменную "пора заканчивать", выходит из критической секции и ожидает событие 3. внутри потоков в цикле кроме формирования числа осуществляется вход во вторую критическую секцию, анализ глобальной переменной "пора заканчивать", если действительно пора - увеличение глобального счетчика завершенных потоков, когда счетчик достигает значения количества потока - идет выброс события 3, выход из критической секции. может можно лучше - просто от балды придумал
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
02.08.2013, 13:11
Помогаю со студенческими работами здесь

Синхронизация потоков
Добрый день. Как синхронизировать потоки, чтобы вывод в stdout был поочередным: foo bar foo bar? Делаю так, но что-то не получается,...

Синхронизация потоков
На собеседовании поставили такую задачу: есть 3 потока, в каждом из которых вызывается функция, в которую передаётся символ. В...

Синхронизация потоков - C++
Что это? Как это исправить? &quot;ConsoleApplication2.exe&quot; (Win32). Загружено...

Синхронизация потоков в c++
Совершенно не понятно что не так и как правильно. Задача: Отсортировать массив целых чисел. Программу разбить на два синхронизированных...

Синхронизация процессов и потоков
Помогите с заданием, пожалуйста.


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

Или воспользуйтесь поиском по форуму:
4
Ответ Создать тему
Новые блоги и статьи
Символьное дифференцирование
igorrr37 13.02.2026
/ * Логарифм записывается как: (x-2)log(x^2+2) - означает логарифм (x^2+2) по основанию (x-2). Унарный минус обозначается как ! в-строка - входное арифметическое выражение в инфиксной(обычной). . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL3_image
8Observer8 10.02.2026
Содержание блога Библиотека SDL3_image содержит инструменты для расширенной работы с изображениями. Пошагово создадим проект для загрузки изображения формата PNG с альфа-каналом (с прозрачным. . .
Установка Qt-версии Lazarus IDE в Debian Trixie Xfce
volvo 10.02.2026
В общем, достали меня глюки IDE Лазаруса, собранной с использованием набора виджетов Gtk2 (конкретно: если набирать текст в редакторе и вызвать подсказку через Ctrl+Space, то после закрытия окошка. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru