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

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

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 9, средняя оценка - 4.89
udjee
0 / 0 / 0
Регистрация: 15.08.2012
Сообщений: 6
02.08.2013, 12:33     Синхронизация потоков, события, WinAPI #1
Уважаемые программисты!
Решается такая задача: 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
что не есть правильно.

Подскажите, пожалуйста, как избавиться от последней ситуации?
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
vxg
Модератор
 Аватар для vxg
2663 / 1674 / 157
Регистрация: 13.01.2012
Сообщений: 6,251
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
Модератор
 Аватар для vxg
2663 / 1674 / 157
Регистрация: 13.01.2012
Сообщений: 6,251
02.08.2013, 13:11     Синхронизация потоков, события, WinAPI #4
я бы вообще это как то по другому сделал. пальцем в небо - каждый поток формирует число, входит в критическую секцию, пишет в глобальную переменную свой номер, выбрасывает событие 1, ожидает событие 2, выходит из критической секции. основной поток ловит событие 1, читает из переменной номер потока выбросившего это событие, выводит число сформированное этим потоком, выбрасывает событие 2. когда пользователь нажал кнопку основной поток входит во вторую критическую секцию, пишет в глобальную переменную "пора заканчивать", выходит из критической секции и ожидает событие 3. внутри потоков в цикле кроме формирования числа осуществляется вход во вторую критическую секцию, анализ глобальной переменной "пора заканчивать", если действительно пора - увеличение глобального счетчика завершенных потоков, когда счетчик достигает значения количества потока - идет выброс события 3, выход из критической секции. может можно лучше - просто от балды придумал
Yandex
Объявления
02.08.2013, 13:11     Синхронизация потоков, события, WinAPI
Ответ Создать тему
Опции темы

Текущее время: 08:37. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru