Форум программистов, компьютерный форум CyberForum.ru

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 9, средняя оценка - 4.89
udjee
0 / 0 / 0
Регистрация: 15.08.2012
Сообщений: 6
#1

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

02.08.2013, 12:33. Просмотров 1304. Ответов 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]);
}
В результате получаю либо:
Синхронизация потоков, события, WinAPI
либо:
Синхронизация потоков, события, WinAPI
что не есть правильно.

Подскажите, пожалуйста, как избавиться от последней ситуации?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
02.08.2013, 12:33     Синхронизация потоков, события, WinAPI
Посмотрите здесь:

C++ Синхронизация
C++ Синхронизация потоков в c++
C++ Создание и завершение процессов и потоков. Приоритеты выполнения потоков
Синхронизация потоков на семафорах C++
C++ Буферы и синхронизация потоков
Создать разное количество потоков с возможностью ожидания события из одного потока в другом C++
Синхронизация потоков - уведомление о событии C++
Общие разговоры на тему плюсов, потоков данных, классов, и winapi C++
Синхронизация потоков C++
Синхронизация потоков ввода и вывода в Eclipce CDT C++
C++ синхронизация потоков
Синхронизация потоков Event c++ C++

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

Или воспользуйтесь поиском по форуму:
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
vxg
Модератор
3062 / 1864 / 196
Регистрация: 13.01.2012
Сообщений: 7,087
02.08.2013, 12:51     Синхронизация потоков, события, WinAPI #2
удивительно что вообще работает... несколько потоков выбрасывают одно и то же событие которое ожидает основной поток который думает что выброс этого события означает что отработали ВСЕ потоки хотя по факту отработать может только один. потом при нажатии клавиши потоки останавливаются и при этом мы ожидаем что они завершаться - интересно когда если они стоят... очень все это интересно
udjee
0 / 0 / 0
Регистрация: 15.08.2012
Сообщений: 6
02.08.2013, 13:00  [ТС]     Синхронизация потоков, события, WinAPI #3
vxg, значит надо создать событие для каждого потока?

P.S. Извините, если я туплю
vxg
Модератор
3062 / 1864 / 196
Регистрация: 13.01.2012
Сообщений: 7,087
02.08.2013, 13:11     Синхронизация потоков, события, WinAPI #4
я бы вообще это как то по другому сделал. пальцем в небо - каждый поток формирует число, входит в критическую секцию, пишет в глобальную переменную свой номер, выбрасывает событие 1, ожидает событие 2, выходит из критической секции. основной поток ловит событие 1, читает из переменной номер потока выбросившего это событие, выводит число сформированное этим потоком, выбрасывает событие 2. когда пользователь нажал кнопку основной поток входит во вторую критическую секцию, пишет в глобальную переменную "пора заканчивать", выходит из критической секции и ожидает событие 3. внутри потоков в цикле кроме формирования числа осуществляется вход во вторую критическую секцию, анализ глобальной переменной "пора заканчивать", если действительно пора - увеличение глобального счетчика завершенных потоков, когда счетчик достигает значения количества потока - идет выброс события 3, выход из критической секции. может можно лучше - просто от балды придумал
Yandex
Объявления
02.08.2013, 13:11     Синхронизация потоков, события, WinAPI
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru