Форум программистов, компьютерный форум, киберфорум
C/C++: WinAPI
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.88/8: Рейтинг темы: голосов - 8, средняя оценка - 4.88
0 / 0 / 0
Регистрация: 29.03.2016
Сообщений: 36
1

Реализовать моделирование "столкновений" на примере работы с критическими секциями

08.09.2018, 15:39. Показов 1480. Ответов 8
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Здравствуйте,кто может помочь с программой,как понимаю,проблема с выводом,наспех написал,что требуется в выводе:
результат должен быть один .один поток пишет что то в А,например 10.,через 50мс считывает А число. если гонок нет то в А 10. Если гонки есть то: 2 поток записывает 15,1 поток записал 10, 2 записал 15 и если 1 поток считывает вместо 10 15-это столкновение.войти в крит сеекцию и выйти когда 1 поток уже считает 10 т.е прекратит испольховать ресурс. записывает один что то читает.Все работает,но скорее всего просто не нравится как выглядит.Напишите кто сможет помочь,договоримся в лс или вк например.
Вот код
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
результат должен быть один .один поток что то в А,через 50мс считывает А число. если гонок нет то в А 10 если гонки есть то 2 поток записывает 15,1 поток записал 10, 2 записал 15 и 1 поток считавает .вместо 10 15-это столкновение.войти в крит сеекцию и выйти когда 1 поток уже считает 10 т.е прекратит испольховать ресурс. записывает один что то читает.
#include <iostream>
#include <windows.h>
#include <cstdlib>
//#include "stdafx.h"
using namespace std;
 
int ARRAY=500;                      // инициализация размера массива
CRITICAL_SECTION critsect;          // создание объекта синхронизации Критическая Секция
int *Res=new int[ARRAY];            // создание массива из ARRAY переменных (из 500)
int Middle=0;                       // переменная середины, средний эл-т (сумма всех эл-тов массива, деленная на их кол-во)
 
 
DWORD ThreadFunction1(int Time)     // функция первого потока - увеличивает каждый эл-т массива на 20
{
 
    int Summ=0;                         // инициализация переменной суммы
    Sleep(Time);                        // задержка в Time миллисекунд
    EnterCriticalSection(&critsect);    // вход в критическую секцию
    for(int i=0; i<ARRAY; i++)          // увеличение каждого эл-та массива на 20
    {
        Res[i]+=20;
    }
    for(int i=0; i<ARRAY; i++)          // суммирование всех эл-тов массива
    {
        Summ+=Res[i];
    }
    Middle=Summ/ARRAY;                  // вычисление среднего эл-та
    cout<< "Summ=" << Summ<< "::"<< "Middle=" << Middle<< "-First"<< endl;  // вывод информации о сумме, среднем эл-те и номере потока
    LeaveCriticalSection(&critsect);    // выход из критической секции
    return 0;
}
 
DWORD ThreadFunction2(int Time)     // функция второго потока - делит каждый элемент массива на 2
{
    int Summ=0;                         // инициализация переменной суммы
    Sleep(Time);                        // задержка в Time миллисекунд
    EnterCriticalSection(&critsect);    // вход в критическую секцию
    for(int i=0; i<ARRAY; i++)          // деление всех эл-тов массива на 2
    {
        Res[i]/=2;
    }
    for(int i=0; i<ARRAY; i++)          // суммирование всех эл-тов массива
    {
        Summ+=Res[i];
    }
    Middle=Summ/ARRAY;                  // вычисление среднего эл-та
    cout<< "Summ=" << Summ<< "::"<< "Middle=" << Middle<< "-Second"<< endl;     // вывод информации о сумме, среднем эл-те и номере потока
    LeaveCriticalSection(&critsect);    // выход из критической секции
    return 0;
}
 
int main()
{
    LPDWORD ID1, ID2;                               // инициализация переменных: идентификаторы потоков
    int Time1=1000,Time2=1000;                      //                           время выполнения потоков 
    HANDLE hThread1, hThread2;                      //                           указатели на потоки
    InitializeCriticalSection(&critsect);           // инициализация критической секции
    for(int i=0; i<20; i++)                         // 20 повторений всей программы - просто для наглядности, чтобы увидеть разные варианты
    {
        for(int i=0; i<ARRAY; i++)                  // инициализация и переинициализация массива при каждом проходе по циклу т.к. значения элементов массива меняются потоками
        {
            Res[i]=i;
        }
        hThread1=CreateThread(NULL,0, (LPTHREAD_START_ROUTINE)ThreadFunction1, (LPVOID)Time1, 0, (LPDWORD)&ID1);        // создание потока 1
        hThread2=CreateThread(NULL,0, (LPTHREAD_START_ROUTINE)ThreadFunction2, (LPVOID)Time2, 0, (LPDWORD)&ID2);        // создание потока 2
        if(hThread1==NULL || hThread2==NULL)            // проверка на ошибки при вызове ф-й CreateThread
        {
            cout << "Error" << GetLastError() << endl;      // выводи Error и номер последней системной ошибки WINapi
            cin.get();                                      // ожидание ввода
            return 0;
        }
        WaitForSingleObject(hThread1,INFINITE);             // ожидание завершения потока 1
        WaitForSingleObject(hThread2,INFINITE);             // ожидание завершения потока 2
        cout<< "_____________________________"<< endl;                      
        Middle=0;                                           // обнуление переменной середины
    }
    cin.get();                                              // ожидание ввода
    return 0;
}
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
08.09.2018, 15:39
Ответы с готовыми решениями:

Реализовать моделирование "столкновений" на примере работы с критическими секциями
Реализовать моделирование &quot;столкновений&quot; на примере работы с критическими секциями. Временные...

Реализовать моделирование "столкновений" на примере работы с критическими секциями
Реализовать моделирование &quot;столкновений&quot; на примере работы с критическими секциями. Временные...

Реализовать моделирование «гонок» на примере работы с критическими секциями
Приветствую всех) Помогите,пожалуйста Реализовать моделирование «гонок» на примере работы с...

Реализовать моделирование «тупика» на примере работы с критическими секциями
Приветствую всех) Помогите,пожалуйста Реализовать моделирование «тупика» на примере работы с...

8
2376 / 834 / 317
Регистрация: 10.02.2018
Сообщений: 1,969
09.09.2018, 09:52 2
Всё у вас как-то слишком сумбурно.
Задание одно - моделирование "столкновений", решение другое - исключение "столкновений".
Не понятно, что точно вам нужно и каким боком тут массив.
0
0 / 0 / 0
Регистрация: 29.03.2016
Сообщений: 36
09.09.2018, 21:52  [ТС] 3
просто надо наглядно показать ,что в ситуации когда присутствует критическая секция,то столкновений не наблюдается.А если ее убрать,то будут столкновения потоков.Проблема именно в реализации вывода,чтобы было наглядно показано это
0
2376 / 834 / 317
Регистрация: 10.02.2018
Сообщений: 1,969
09.09.2018, 23:15 4
Для наглядности можно сделать классический счётчик. Первый поток 10 миллионов раз увеличивает счётчик, второй поток 10 миллионов раз уменьшает счётчик. Если проблем не было, то должно получиться исходное число.
C++
1
2
3
4
5
6
7
8
9
10
11
volatile int cnt = 0;
void thread1()
{
  for (int i=0; i<10000000; i++)
    cnt++;
}
void thread2()
{
  for (int i=0; i<10000000; i++)
    cnt--;
}
Или можно 10 миллионов раз в одну переменную записывать и сразу считывать число характерное для потока. Если число не соответствует ожидаемому, то увеличивать счётчик ошибок потока.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
volatile int var = 0;
volatile int cnt1 = 0;
volatile int cnt2 = 0;
void thread1()
{
  for (int i=0; i<10000000; i++)
  {
    var = 1;
    if (var != 1)
      cnt1++;
  }
}
void thread2()
{
  for (int i=0; i<10000000; i++)
  {
    var = 2;
    if (var != 2)
      cnt2++;
  }
}
Операции над элементами массива, подсчёт суммы и среднего - это немного путано.

Откуда в вашем описании появилась задержка в 50 мс? Это громадное время. Возможно, по заданию вам нужно не получение реальных "столкновений", а именно моделирование с искусственными задержками между записью и чтением. Гадать можно до бесконечности. Будет эффективнее, если вы напишите точно, что от вас требуется.
0
0 / 0 / 0
Регистрация: 29.03.2016
Сообщений: 36
10.09.2018, 23:00  [ТС] 5
да насчет задержки это образно,рассказали как примерно должно выглядеть,задача та же:просто создать два потока и наглядно показать ,что без критических секций будут наблюдаться столкновения этих потоков,а с ними столкновения не будут наблюдаться.
0
2376 / 834 / 317
Регистрация: 10.02.2018
Сообщений: 1,969
10.09.2018, 23:49 6
как вариант
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
115
116
117
118
#include <iostream>
#include <windows.h>
#include <cstdlib>
 
using namespace std;
 
CRITICAL_SECTION cs;                // создание объекта синхронизации Критическая Секция
volatile int val = 0;               // общая переменная
volatile int cnt1 = 0;              // счётчик ошибок первого потока
volatile int cnt2 = 0;              // счётчик ошибок второго потока
 
// небезопасные потоки
DWORD WINAPI UnsafeThread1(LPVOID)
{
    for (int i=0; i<10000000; i++)
    {
        val = 1;
        if (val != 1)
            cnt1++;
    }
    return 0;
}
DWORD WINAPI UnsafeThread2(LPVOID)
{
    for (int i=0; i<10000000; i++)
    {
        val = 2;
        if (val != 2)
            cnt2++;
    }
    return 0;
}
 
// безопасные потоки
DWORD WINAPI SafeThread1(LPVOID)
{
    for (int i=0; i<10000000; i++)
    {
        EnterCriticalSection(&cs);
        val = 1;
        if (val != 1)
            cnt1++;
        LeaveCriticalSection(&cs);
    }
    return 0;
}
DWORD WINAPI SafeThread2(LPVOID)
{
    for (int i=0; i<10000000; i++)
    {
        EnterCriticalSection(&cs);
        val = 2;
        if (val != 2)
            cnt2++;
        LeaveCriticalSection(&cs);
    }
    return 0;
}
 
int main()
{
    DWORD dwID1, dwID2;
    HANDLE hThread1, hThread2;                // указатели на потоки
    InitializeCriticalSection(&cs);           // инициализация критической секции
 
    cout << "Unsafe threads:" << endl;
    for (int i=0; i<10; i++)                   // 10 повторений всей программы - просто для наглядности, чтобы увидеть разные варианты
    {
        cnt1 = cnt2 = 0;                                    // обнуление счётчиков
 
        hThread1=CreateThread(NULL,0, (LPTHREAD_START_ROUTINE)UnsafeThread1, 0, 0, &dwID1);        // создание потока 1
        hThread2=CreateThread(NULL,0, (LPTHREAD_START_ROUTINE)UnsafeThread2, 0, 0, &dwID2);        // создание потока 2
 
        if (hThread1==NULL || hThread2==NULL)                // проверка на ошибки при вызове ф-й CreateThread
        {
            cout << "Error: " << GetLastError() << endl;    // выводи Error и номер последней системной ошибки WINapi
            cin.get();                                      // ожидание ввода
            return 0;
        }
 
        WaitForSingleObject(hThread1,INFINITE);             // ожидание завершения потока 1
        CloseHandle(hThread1);
 
        WaitForSingleObject(hThread2,INFINITE);             // ожидание завершения потока 2
        CloseHandle(hThread2);
 
        cout << i+1 << ") " << cnt1 << " / " << cnt2 << endl; // количество ошибок чтения
    }
 
    cout << endl << "Safe threads:" << endl;
    for (int i=0; i<10; i++)                   // 10 повторений всей программы - просто для наглядности, чтобы увидеть разные варианты
    {
        cnt1 = cnt2 = 0;                                    // обнуление счётчиков
 
        hThread1=CreateThread(NULL,0, (LPTHREAD_START_ROUTINE)SafeThread1, 0, 0, &dwID1);        // создание потока 1
        hThread2=CreateThread(NULL,0, (LPTHREAD_START_ROUTINE)SafeThread2, 0, 0, &dwID2);        // создание потока 2
 
        if (hThread1==NULL || hThread2==NULL)                // проверка на ошибки при вызове ф-й CreateThread
        {
            cout << "Error: " << GetLastError() << endl;    // выводи Error и номер последней системной ошибки WINapi
            cin.get();                                      // ожидание ввода
            return 0;
        }
 
        WaitForSingleObject(hThread1,INFINITE);             // ожидание завершения потока 1
        CloseHandle(hThread1);
 
        WaitForSingleObject(hThread2,INFINITE);             // ожидание завершения потока 2
        CloseHandle(hThread2);
 
        cout << i+1 << ") " << cnt1 << " / " << cnt2 << endl; // количество ошибок чтения
    }
 
    DeleteCriticalSection(&cs);
 
    cin.get();                                              // ожидание ввода
    return 0;
}
0
0 / 0 / 0
Регистрация: 29.03.2016
Сообщений: 36
11.09.2018, 00:01  [ТС] 7
Спасибо,попробую разобраться с этим.
0
0 / 0 / 0
Регистрация: 29.03.2016
Сообщений: 36
12.09.2018, 16:50  [ТС] 8
А на чем вы писали данную программу?у меня вот такая ошибка выскакивает,(прошу прощения за суперскрин)
Миниатюры
Реализовать моделирование "столкновений" на примере работы с критическими секциями  
0
0 / 0 / 0
Регистрация: 29.03.2016
Сообщений: 36
12.09.2018, 16:56  [ТС] 9
Все нормально ,на dev++ 5.11 работает
0
12.09.2018, 16:56
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
12.09.2018, 16:56
Помогаю со студенческими работами здесь

Реализовать моделирование "гонок" на примере работы с критическими секциями
Здравствуйте! Можете помочь разобраться и подправить ошибки? Отправили на переделку, но я не понял...

Работа с критическими секциями
Мое приложение (еще не готово) имеет ошибки (не все еще исправил)... Главные (из тех, что нашел) -...

Работа с критическими секциями
Пытаюсь синхронизировать 2 потока: char TempWord; FILE *in1; FILE *in2; FILE *out; DWORD...

Работа с критическими секциями
Разбираюсь с потоками, пытаюсь сделать синхронизацию: #include &lt;windows.h&gt; #include &lt;stdio.h&gt;...

Работа с критическими секциями
Необходимо, используя механизм работы критических секций и два потока с циклами от 1 до 5, вывести...

Как работать с критическими секциями?
Нужно чтобы несколько потоков выдавало инфу в один ком-порт.Для этого пытаюсь использовать...

Научите меня обращаться с критическими секциями
С критическими СЕКЦИЯМИ, конечно же Здравствуйте, помогите мне, пожалуйста. У меня есть 2...


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

Или воспользуйтесь поиском по форуму:
9
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru