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

Проверка

07.11.2020, 12:44. Показов 1271. Ответов 5
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
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
#include <iostream> //ввод-вывод
#include <Windows.h> //объявления для всех функций в API Windows
#include <cmath> //выполнение математических операций
#include <algorithm> //алгоритмические операции
using namespace std; // использовать область пространства std
const int N = 40; //Количество равных частей отреза a,b
const double n = 8; //номер студента в группе по списку Медов
const double a = 0; //Левая граница отреза
const double b = 1; //Правая граница отрезка
static double h = (b - a) / N; //шаг разбиения
int main() //главная функция
{
    double* y = new double[N + 1]; //приближённая производная для аналитического решения
    double* yx = new double[N + 1]; //приближённая производная для численного решения
    y[0] = 1;
    yx[0] = 1;
    double max = NULL; //изначально 0, требуется для выполнения 4 пункта
    double C = 1 - ((n / (n - 2))); //из начального условия
    for (int g = 0; g < N; g++) //цикл для y(x)
    {
        y[g + 1] = round((h * n * (a + g * h) * exp(-(pow((a + g * h), 2))) - h * n * (a + g * h) * y[g] + y[g]) * 1000) / 1000;
    }
    for (int g = 0; g < N + 1; g++) //цикл для y(xi)
    {
        yx[g] = round(((n / (n - 2)) * exp(((n / 2) - 1) * pow(a + g * h, 2)) + (C)) * exp(-(n / 2) * pow(a + g * h, 2)) * 1000) / 1000;
    }
    
    for (int g = 0; g < N + 1; g++) //цикл для полученных y(xi) и y(x) 4 пункт
    {
        
        if ((fabs(yx[g] - y[g]) >= 0.005) && (fabs(yx[g] - y[g]) <= 0.01)) //смотрим, чтобы шаг удовлетворял условию
        {
            if (max < fabs(yx[g] - y[g])) //если максимальное изначальное значение (0) меньше полученного шага
            {
                max = fabs(yx[g] - y[g]); //то записываем новое максимальное значение
            }
        }
    }
    cout << "_________________________________________" << endl;
    cout << "|#\t" << "|" << "yx(xi)" << "\t|" << "y(i)" << "\t|" << "y(xi)-y(i)\t" << "|" << endl; //выводим заголовок таблицы
    cout << "_________________________________________" << endl;
    for (int g = 0; g < N; g++)
    {
        if (g-9 < 0)
        {
            cout << "|0" << g+1 << "\t";
        }
        else
        {
            cout << "|" << g+1 << "\t";
        }
        cout << "|" << yx[g] << "\t|" << y[g] << "\t|" << fabs(yx[g] - y[g]) << "\t\t|" << endl; // выводим таблицу
    }
    
    cout << "_________________________________________" << endl;
    cout << endl << "max(y(xi)-yi) = " << max << endl; //отображаем конец четвертого пункта, ответ
}
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
07.11.2020, 12:44
Ответы с готовыми решениями:

Проверка на четность
Есть восьмизначное число, проверить входят ли в запись этого числа четные цифры. Как реализовать условие?(if, else)

Проверка ввода
Здравствуйте! как произвести проверку на ввод данных чтоб только числа можно было ввести, т.е если у нас есть цикл и я ввожу например...

Проверка ввода. на С
Ребят помогите пожалуйста организовать проверку ввода. Ситуация следующая. Мне нужно организовать проверку ввода следующим образом. ...

5
2 / 2 / 0
Регистрация: 24.02.2019
Сообщений: 138
16.11.2020, 20:07  [ТС]
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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
#include <iostream>
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <windows.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILEstatic char THIS_FILE[] = __FILE__;
#endif
using namespace std; 
static DWORD WINAPI FirstThread(void* pv); // Прототипы функций
static DWORD WINAPI SecondThread(void* pv); // которые будут участвовать в гонке потоков
HANDLE g_hSemaphore; // Обьявляем Хендл семафора
HANDLE hStdout; // Хендл вывода информации в консоли
int Lid = 0, g_nIndex = 0; // Флаг, определяющий поток завершённый первым(лидерство), количество синхронизируемых потоков
int a[20], IndexResours = 0; // Общий ресурс и его индекс
LONG MaxCount = 3;  // Максимальное количество синхронизируемых семафором потоков
static DWORD WINAPI FirstThread(void* pv) //Функция FirstThread для работы с потоком (static - сохраняет значение во время работы программы)
{
    COORD pos; // Переменная, которая будет хранить текущую координату курсора  
    pos.X = 3; // Столбец отображения задержки первого потока    
    BOOL fDone = FALSE; // Флаг отработки потока  
    while (!fDone) //запуск цикла, работает пока fDone = FALSE
    {
        ::WaitForSingleObject(g_hSemaphore, INFINITE); // Ожидание запуска семафора на длительном интервале времени        
        if (g_nIndex >= MaxCount) // Проверяю, не создано ли потоков больше чем максимальное кол-во потоков         
            fDone = TRUE; //выходим из цикла
        else //или
        {
                g_nIndex++; // Количество потоков увеличиваю на 1  
                for (int i = 0; i <= 10; i++) // Начинаю цикл для инициализации массива 10 временных задержек          
                {
                    srand(time(NULL)); // Включаю генератор случайных чисел  
                    IndexResours++;
                    a[IndexResours - 1] = rand() % 1000;// Генерирую задержку первого потока (от 0 до 1000 миллисекунд)
                    pos.Y = i;
                    SetConsoleCursorPosition(hStdout, pos); // Устанавливаю курсор в i - тую строку 
                    cout << a[IndexResours - 1] << " First"; // Вывожу текущую задержку для первого потока     
                    Sleep(a[IndexResours - 1]);  // Осуществляю задерку на текущее количество миллисекунд          
                }
        }
            ::ReleaseSemaphore(g_hSemaphore, 1, 0); // Освобождаю семафор от данного потока   
    }
    if (!Lid) // Если лидирующий поток не определён, то делаю данный лидирующим        
        Lid = 1;    
    return 0;
}
static DWORD WINAPI SecondThread(void* pv)
{
    COORD pos;// Переменная, которая будет хранить текущую координату курсора    
    int Speed2[10]; // Массив задержек второго потока    
    pos.X = 25;// Столбец отображения задержки второго потока    
    BOOL fDone = FALSE;// Флаг отработки потока    
    while (!fDone)
    {
        ::WaitForSingleObject(g_hSemaphore, INFINITE);// Ожидание запуска семафора на длительном интервале времени        
        if (g_nIndex >= MaxCount)// Проверяю, не создано ли потоков больше чем максимальное кол-во потоков            
            fDone = TRUE;
        else
        {
            g_nIndex++;// Количество потоков увеличиваю на 1 
            for (int i = 0; i <= 10; i++)// Начинаю цикл для инициализации массива 10-ти временных задержек            
            {
                IndexResours++;
                a[IndexResours - 1] = rand() % 1000;// Генерирую задержку второго потока (от 0 до 1000 миллисекунд) 
                pos.Y = i;
                SetConsoleCursorPosition(hStdout, pos);// Устанавливаю курсор в i - тую строку  
                cout << a[IndexResours - 1] << " Second"; // Вывожу текущую задержку для второго потока 
                Sleep(a[IndexResours - 1]); // Осуществляю задерку на текущее количество миллисекунд 
            }
        }
        ::ReleaseSemaphore(g_hSemaphore, 1, 0);// Освобождаю семафор от данного потока   
    }
    if (!Lid)// Если лидирующий поток не определён, то делаю данный лидирующим        
        Lid = 2;
    return 0;
}
static DWORD WINAPI ThirdThread(void* pv)
{
    COORD pos;// Переменная, которая будет хранить текущую координату курсора    
    int Speed3[10]; // Массив задержек второго потока    
    pos.X = 45;// Столбец отображения задержки второго потока    
    BOOL fDone = FALSE;// Флаг отработки потока    
    while (!fDone)
    {
        ::WaitForSingleObject(g_hSemaphore, INFINITE);// Ожидание запуска семафора на длительном интервале времени        
        if (g_nIndex >= MaxCount)// Проверяю, не создано ли потоков больше чем максимальное кол-во потоков            
            fDone = TRUE;
        else
        {
            g_nIndex++;// Количество потоков увеличиваю на 1 
            for (int i = 0; i <= 10; i++)// Начинаю цикл для инициализации массива 10-ти временных задержек           
            {
                IndexResours++;
                a[IndexResours - 1] = rand() % 1000;// Генерирую задержку второго потока (от 0 до 1000 миллисекунд)  
                pos.Y = i;
                SetConsoleCursorPosition(hStdout, pos);// Устанавливаю курсор в i - тую строку     
                cout << a[IndexResours - 1] << " Third";// Вывожу текущую задержку для третьего потока     
                Sleep(a[IndexResours - 1]);// Осуществляю задерку на текущее количество миллисекунд    
            }
        }
        ::ReleaseSemaphore(g_hSemaphore, 1, 0);// Освобождаю семафор от данного потока    
    }
    if (!Lid)// Если лидирующий поток не определён, то делаю данный лидирующим        
        Lid = 3;
    return 0;
}
int main()
{
    int nRetCode = 0;    
    hStdout = GetStdHandle(STD_OUTPUT_HANDLE);   
    DWORD dw; // Обьект синхронизации        
    LONG g_iCount = 3; // начальное значение семафора        
    HANDLE hThreads[3]; // Массив Хендлов потоков        
    g_hSemaphore = ::CreateSemaphore(NULL, g_iCount, MaxCount, NULL); // Создаем семафор и инициализируем его Хендл      
    hThreads[0] = ::CreateThread(NULL, 0, FirstThread, NULL, 0, &dw); // Создаем потоки        
    hThreads[1] = ::CreateThread(NULL, 0, SecondThread, NULL, 0, &dw);
    hThreads[2] = ::CreateThread(NULL, 0, ThirdThread, NULL, 0, &dw); // и инициализируем Массив Хендлов потоков
    ::ResumeThread(hThreads[0]); //Запускаем потоки        
    ::ResumeThread(hThreads[1]);
    ::ResumeThread(hThreads[2]);
    ::WaitForMultipleObjects(3, hThreads, TRUE, INFINITE); // Ожидаем окончание работы 3 потоков на очень длительном интервале времени        
    ::CloseHandle(hThreads[0]); // Закрываем созданные потоки        
    ::CloseHandle(hThreads[1]);
    ::CloseHandle(hThreads[2]);
    ::CloseHandle(g_hSemaphore); // и сам семафор        
    switch (Lid)                                                                                                                                                                                    //определяем поток, который завершился первым        {            case 1 : cout << "n nepBbIu' noTok *I*uHuLLIupoBaJI nepBbIM!!!n"; break;            
    {
    case 1: 
        cout << "\n FirstThread finished\n"; 
        break;
    case 2: 
        cout << "\n SecondThread finished\n";
        break;
    case 3:
        cout << "\n ThirdThread finished\n";
        break;
    default: 
        break;  
    return 0;
    }
}
Добавлено через 4 минуты
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
#include <iostream> //библиотека для ввода-вывода
#include <windows.h> //подключаем библиотеку windows.h
int g_nIndex = 0; //создание переменной для работы с массивом
const int MAX_TIMES = 1000; //размер массива данных
DWORD g_dwTimes[MAX_TIMES]; //создание массива, с которым работают потоки
HANDLE g_hMutex = NULL; // переменная для создания мьютекса
DWORD  dwThreadID; // ID потока
int a = 10;
static DWORD WINAPI FirstThread(void* pv) //Функция FirstThread для работы с потоком (static - сохраняет значение во время работы программы)
{
    BOOL fDone = FALSE; //переменная, работает с циклом, когда FALSE
    while (!fDone) //запуск цикла, работает пока fDone = FALSE
    {
        ::WaitForSingleObject(g_hMutex, INFINITE); /*g_hMutex,  ID объекта
            INFINITE время ожидания в миллисекундах
            WaitForSingleObject ждём появление потока, потом Mutex  блокирует доступ другим потокам*/
        if (g_nIndex >= MAX_TIMES) //когда переменная больше (1000)
            fDone = TRUE; //выходим из цикла
        else // или
        {
            g_dwTimes[g_nIndex++] = a++; //заполняется массив временем с начала работы системы
            std::cout << "FirstThread " << g_dwTimes[g_nIndex - 1] << std::endl; // Вывожу текущее значение для первого потока 
        }
        ::ReleaseMutex(g_hMutex); //Освобождаем Mutex
    }
    return 0; //выход из функции FirstThread
}
static DWORD WINAPI SecondThread(void* pv) //Функция SecondThread для работы с потоком (static - сохраняет значение во время работы программы
{
    BOOL fDone = FALSE; //переменная, работает с циклом, когда FALSE
    while (!fDone) //запуск цикла, работает пока fDone = FALSE
    {
        ::WaitForSingleObject(g_hMutex, INFINITE); /*g_hMutex,  ID объекта
            INFINITE время ожидания в миллисекундах
            WaitForSingleObject ждём появление потока, потом Mutex  блокирует доступ другим потокам*/
        if (g_nIndex >= MAX_TIMES) //когда переменная больше (1000)
            fDone = TRUE; //выходим из цикла
        else // или
        {
            g_dwTimes[g_nIndex++] = a++; //заполняется массив временем с начала работы системы
            std::cout << "SecondThread " << g_dwTimes[g_nIndex - 1] << std::endl; // Вывожу текущее значение для первого потока 
        }
        ::ReleaseMutex(g_hMutex); //Освобождаем Mutex
    }
    return 0;
}
int main(int argc, char* argv[]) //главная функция для работы с потоком
{
    HANDLE hThreads[2]; //создание массива типа HANDLE (любой тип данных)
    g_hMutex = ::CreateMutex(NULL, FALSE, NULL); //Создаем Mutex, атрибут безопастности, флаг начального владельца, имя объекта
    hThreads[0] = ::CreateThread(NULL, 0, FirstThread, NULL, 0,
        &dwThreadID); /*создание первого потока (дескриптор безопасности (по умолчанию - NULL),
                                      размер стека в байтах (по умолчанию - 0),
                                      указатель на процедуру (с которого начинается выполнение потока),
                                      аргумент с предыдущего потока,
                                      флаг, записать dwThreadID созданного потока)*/
    hThreads[1] = ::CreateThread(NULL, 0, SecondThread, NULL,
        0, &dwThreadID); /*создание первого потока (дескриптор безопасности (по умолчанию - NULL),
                                      размер стека в байтах (по умолчанию - 0),
                                      указатель на процедуру (с которого начинается выполнение потока),
                                      аргумент с предыдущего потока,
                                      флаг, записать dwThreadID созданного потока)*/
    ::WaitForMultipleObjects(2, hThreads, TRUE, INFINITE);  // (кол-во ожидаемых объектов, тип ожидаемых объектов, ожидать все объекты, максимальное время ожидания)
    ::CloseHandle(hThreads[0]); // закрываем первый поток
    ::CloseHandle(hThreads[1]); // закрываем второй поток
    ::CloseHandle(g_hMutex); // закрываем Mutex
    return 0;
}
Добавлено через 12 минут
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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
#include <windows.h> //подключаем библиотеку windows.h
#include <iostream> //библиотека для ввода-вывода
int g_nIndex = 0; //создание переменной для работы с массивом
const int MAX_TIMES = 50; //размер массива данных
DWORD g_dwTimes[MAX_TIMES]; //создание массива, с которым работают потоки
HANDLE g_hMutex; // переменная для создания мьютекса
int a = 1;
static DWORD WINAPI FirstThread(void* pv) //Функция FirstThread для работы с потоком (static - сохраняет значение во время работы программы)
{
    BOOL fDone = FALSE; //переменная, работает с циклом, когда FALSE
    while (!fDone) //запуск цикла, работает пока fDone = FALSE
    {
        ::WaitForSingleObject(g_hMutex, INFINITE); /*g_hMutex,  ID объекта
            INFINITE время ожидания в миллисекундах
            WaitForSingleObject ждём появление потока, потом Mutex  блокирует доступ другим потокам*/
        if (g_nIndex >= MAX_TIMES) //если g_nIndex больше (1000)
            fDone = TRUE; //выходим из цикла
        else //или
        {
            g_dwTimes[g_nIndex++] = a++; //заполняется массив временем с начала работы системы
            HANDLE hOUTPUT = GetStdHandle(STD_OUTPUT_HANDLE);
            SetConsoleTextAttribute(hOUTPUT, FOREGROUND_GREEN | FOREGROUND_INTENSITY);
            std::cout << "FirstThread " << g_dwTimes[g_nIndex - 1] << std::endl; // Вывожу текущее значение для первого потока 
        }
        ::ReleaseMutex(g_hMutex); //Освобождаю Mutex
    }
    return 0; //выход из функции FirstThread
}
static DWORD WINAPI SecondThread(void* pv) //Функция SecondThread для работы с потоком (static - сохраняет значение во время работы программы)
{
    BOOL fDone = FALSE; //переменная, работает с циклом, когда FALSE
    while (!fDone) //запуск цикла, работает пока fDone = FALSE
    {
        ::WaitForSingleObject(g_hMutex, INFINITE); /*g_hMutex,  ID объекта
            INFINITE время ожидания в миллисекундах
            WaitForSingleObject ждём появление потока, потом Mutex  блокирует доступ другим потокам*/
        if (g_nIndex >= MAX_TIMES) //если g_nIndex больше (1000)
            fDone = TRUE; //выходим из цикла
        else //или
        {
            g_dwTimes[g_nIndex++] = a++; //заполняется массив временем с начала работы системы
            HANDLE hOUTPUT = GetStdHandle(STD_OUTPUT_HANDLE);
            SetConsoleTextAttribute(hOUTPUT, FOREGROUND_GREEN | FOREGROUND_BLUE);
            std::cout << "SecondThread " << g_dwTimes[g_nIndex - 1] << std::endl; // Вывожу текущее значение для второго потока 
        }
        ::ReleaseMutex(g_hMutex); //Освобождаю Mutex
    }
    return 0; //выход из функции SecondThread
}
static DWORD WINAPI ThirdThread(void* pv) //Функция ThirdThread для работы с потоком (static - сохраняет значение во время работы программы)
{
    BOOL fDone = FALSE; //переменная, работает с циклом, когда FALSE
    while (!fDone) //запуск цикла, работает пока fDone = FALSE
    {
        ::WaitForSingleObject(g_hMutex, INFINITE); /*g_hMutex,  ID объекта
            INFINITE время ожидания в миллисекундах
            WaitForSingleObject ждём появление потока, потом Mutex  блокирует доступ другим потокам*/
        if (g_nIndex >= MAX_TIMES) //если g_nIndex больше (1000)
            fDone = TRUE; //выходим из цикла
        else //или
        {
            g_dwTimes[g_nIndex++] = a++; //заполняется массив временем с начала работы системы
            HANDLE hOUTPUT = GetStdHandle(STD_OUTPUT_HANDLE);
            SetConsoleTextAttribute(hOUTPUT, FOREGROUND_RED | FOREGROUND_INTENSITY);
            std::cout << "ThirdThread " << g_dwTimes[g_nIndex - 1] << std::endl; // Вывожу текущее значение для третьего потока 
        }
        ::ReleaseMutex(g_hMutex); //Освобождаю Mutex
    }
    return 0; //выход из функции ThirdThread
}
static DWORD WINAPI FourThread(void* pv) //Функция FourThread для работы с потоком (static - сохраняет значение во время работы программы)
{
    BOOL fDone = FALSE; //переменная, работает с циклом, когда FALSE
    while (!fDone) //запуск цикла, работает пока fDone = FALSE
    {
        ::WaitForSingleObject(g_hMutex, INFINITE); /*g_hMutex,  ID объекта
            INFINITE время ожидания в миллисекундах
            WaitForSingleObject ждём появление потока, потом Mutex  блокирует доступ другим потокам*/
        if (g_nIndex >= MAX_TIMES) //если g_nIndex больше (1000)
            fDone = TRUE; //выходим из цикла
        else //или
        {
            HANDLE hOUTPUT = GetStdHandle(STD_OUTPUT_HANDLE);
            SetConsoleTextAttribute(hOUTPUT, FOREGROUND_BLUE | FOREGROUND_INTENSITY);
            g_dwTimes[g_nIndex++] = a++; //заполняется массив временем с начала работы системы
            std::cout << "FourThread " << g_dwTimes[g_nIndex - 1] << std::endl; // Вывожу текущее значение для четвёртого потока 
        }
        ::ReleaseMutex(g_hMutex); //Освобождаю Mutex
    }
    return 0; //выход из функции FourThread
}
 
static DWORD WINAPI FiveThread(void* pv) //Функция FiveThread для работы с потоком (static - сохраняет значение во время работы программы)
{
    BOOL fDone = FALSE; //переменная, работает с циклом, когда FALSE
    while (!fDone) //запуск цикла, работает пока fDone = FALSE
    {
        ::WaitForSingleObject(g_hMutex, INFINITE); /*g_hMutex,  ID объекта
            INFINITE время ожидания в миллисекундах
            WaitForSingleObject ждём появление потока, потом Mutex  блокирует доступ другим потокам*/
        if (g_nIndex >= MAX_TIMES) //если g_nIndex больше (1000)
            fDone = TRUE; //выходим из цикла
        else //или
        {
            HANDLE hOUTPUT = GetStdHandle(STD_OUTPUT_HANDLE);
            SetConsoleTextAttribute(hOUTPUT, FOREGROUND_INTENSITY | FOREGROUND_INTENSITY);
            g_dwTimes[g_nIndex++] = a++; //заполняется массив временем с начала работы системы
            std::cout << "FiveThread " << g_dwTimes[g_nIndex - 1] << std::endl; // Вывожу текущее значение для пятого потока
        }
        ::ReleaseMutex(g_hMutex); //Освобождаю Mutex
    }
    return 0; //выход из функции FiveThread
}
 
int main(int argc, char* argv[]) //главная функция для работы с потоком
{
    HANDLE hThreads[5]; //создание массива типа HANDLE (любой тип данных)
    DWORD dwThreadID; // ID потока
    hThreads[0] = ::CreateThread(NULL, 0, FirstThread, NULL,
        CREATE_SUSPENDED, &dwThreadID);/*создание первого потока (дескриптор безопасности (по умолчанию - NULL),
                                      размер стека в байтах (по умолчанию - 0),
                                      указатель на процедуру (с которого начинается выполнение потока),
                                      аргумент с предыдущего потока,
                                     CREATE_SUSPENDED позволяет создаёт поток в спящем режиме, и он
                                    не запускается до тех пор пока не будет вызвана функция ResumeThread,
                                    записать dwThreadID созданного потока*/
    hThreads[1] = ::CreateThread(NULL, 0, SecondThread, NULL,
        CREATE_SUSPENDED, &dwThreadID); /*создание второго потока (дескриптор безопасности (по умолчанию - NULL),
                                      размер стека в байтах (по умолчанию - 0),
                                      указатель на процедуру (с которого начинается выполнение потока),
                                      аргумент с предыдущего потока,
                                     CREATE_SUSPENDED позволяет создаёт поток в спящем режиме, и он
                                    не запускается до тех пор пока не будет вызвана функция ResumeThread,
                                    записать dwThreadID созданного потока*/
    hThreads[2] = ::CreateThread(NULL, 0, ThirdThread, NULL,
        CREATE_SUSPENDED, &dwThreadID); /*создание третьего потока (дескриптор безопасности (по умолчанию - NULL),
                                      размер стека в байтах (по умолчанию - 0),
                                      указатель на процедуру (с которого начинается выполнение потока),
                                      аргумент с предыдущего потока,
                                     CREATE_SUSPENDED позволяет создаёт поток в спящем режиме, и он
                                    не запускается до тех пор пока не будет вызвана функция ResumeThread,
                                    записать dwThreadID созданного потока*/
    hThreads[3] = ::CreateThread(NULL, 0, FourThread, NULL,
        CREATE_SUSPENDED, &dwThreadID); /*создание четвёртого потока (дескриптор безопасности (по умолчанию - NULL),
                                      размер стека в байтах (по умолчанию - 0),
                                      указатель на процедуру (с которого начинается выполнение потока),
                                      аргумент с предыдущего потока
                                    записать dwThreadID созданного потока*/
    g_hMutex = ::CreateMutex(NULL, FALSE, NULL);//создаем мьютекс после 3 потока
    hThreads[4] = ::CreateThread(NULL, 0, FiveThread, NULL,
        0, &dwThreadID); /*создание пятого потока (дескриптор безопасности (по умолчанию - NULL),
                                      размер стека в байтах (по умолчанию - 0),
                                      указатель на процедуру (с которого начинается выполнение потока),
                                      аргумент с предыдущего потока
                                    записать dwThreadID созданного потока*/
    ::ResumeThread(hThreads[0]);//запускаем наши  потоки
    ::ResumeThread(hThreads[1]);
    ::ResumeThread(hThreads[2]);
    ::ResumeThread(hThreads[3]);
    ::WaitForMultipleObjects(5, hThreads, TRUE, INFINITE);
    ::CloseHandle(hThreads[0]);
    ::CloseHandle(hThreads[1]);
    ::CloseHandle(hThreads[2]);
    ::CloseHandle(hThreads[3]);
    ::CloseHandle(hThreads[4]);
    ::CloseHandle(g_hMutex);
    return 0;
}
0
Модератор
Эксперт С++
 Аватар для zss
13769 / 10962 / 6491
Регистрация: 18.12.2011
Сообщений: 29,240
16.11.2020, 20:16
DREDON, И в чем заключается вопрос?
0
2 / 2 / 0
Регистрация: 24.02.2019
Сообщений: 138
18.11.2020, 20:51  [ТС]
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
#include <iostream> //библиотека для ввода-вывода
#include <windows.h> //подключаем библиотеку windows.h
int g_nIndex = 0; //создание переменной для работы с массивом
const int MAX_TIMES = 1000; //размер массива данных
DWORD g_dwTimes[MAX_TIMES]; //создание массива, с которым работают потоки
CRITICAL_SECTION g_CriticalSection; //создаём критическую секцию для синхронизации
int a = 50; //начинаем работу со значения 50
using namespace std; //использовать область std
static DWORD WINAPI FirstThread(void* pv) //Функция FirstThread для работы с потоком (static - сохраняет значение во время работы программы)
{
    BOOL fDone = FALSE; //переменная, работает с циклом, когда FALSE
    while (!fDone) // запуск цикла, работает пока fDone = FALSE
    {
        ::EnterCriticalSection(&g_CriticalSection); //вход в критическую секцию
        if (g_nIndex >= MAX_TIMES) //когда переменная больше (1000)
            fDone = TRUE; //выходим из цикла
        else // или
        {
            g_dwTimes[g_nIndex++] = a++; //заполняется массив временем с начала работы системы
            std::cout << "FirstThread " << g_dwTimes[g_nIndex - 1] << std::endl; // Вывожу текущее значение для первого потока 
        }
        ::LeaveCriticalSection(&g_CriticalSection); // выход из критической секции
    }
    return 0; //выход из функции FirstThread
}
static DWORD WINAPI SecondThread(void* pv) //Функция SecondThread для работы с потоком (static - сохраняет значение во время работы программы
{
    BOOL fDone = FALSE; //переменная, работает с циклом, когда FALSE
    while (!fDone) //запуск цикла, работает пока fDone = FALSE
    {
        ::EnterCriticalSection(&g_CriticalSection); //вход в критическую секцию
        if (g_nIndex >= MAX_TIMES) //когда переменная больше (1000)
            fDone = TRUE; //выходим из цикла
        else // или
        {
            g_dwTimes[g_nIndex++] = a++; //заполняется массив временем с начала работы системы
            std::cout << "SecondThread " << g_dwTimes[g_nIndex - 1] << std::endl; // Вывожу текущее значение для первого потока 
        }
        ::LeaveCriticalSection(&g_CriticalSection); // выход из критической секции
    }
    return 0; //выход из функции SecondThread
}
int main(int argc, char* argv[]) //главная функция для работы с потоком
{
    HANDLE hThreads[2]; //создание массива типа HANDLE (любой тип данных)
    ::InitializeCriticalSection(&g_CriticalSection); //инициализация критической секции
 
    DWORD dwThreadID; //создание персонального ID потокам
    hThreads[0] = ::CreateThread(NULL, 0, FirstThread,
        &dwThreadID, 0, &dwThreadID); /*создание первого потока (дескриптор безопасности (по умолчанию - NULL),
                                      размер стека в байтах (по умолчанию - 0),
                                      указатель на процедуру (с которого начинается выполнение потока),
                                      аргумент с предыдущего потока,
                                      флаг, записать dwThreadID созданного потока)*/
    hThreads[1] = ::CreateThread(NULL, 0, SecondThread,
        &dwThreadID, 0, &dwThreadID); /*создание первого потока (дескриптор безопасности (по умолчанию - NULL),
                                      размер стека в байтах (по умолчанию - 0),
                                      указатель на процедуру (с которого начинается выполнение потока),
                                      аргумент с предыдущего потока,
                                      флаг, записать dwThreadID созданного потока)*/
    ::WaitForMultipleObjects(2, hThreads, TRUE, INFINITE); // (кол-во ожидаемых объектов, тип ожидаемых объектов, ожидать все объекты, максимальное время ожидания)
    ::CloseHandle(hThreads[0]); // закрываем первый поток
    ::CloseHandle(hThreads[1]); // закрываем второй поток
    ::DeleteCriticalSection(&g_CriticalSection); //удаление критической функции
    return 0;
}
Добавлено через 8 минут
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
#include <iostream> //библиотека для ввода-вывода
#include <windows.h> //подключаем библиотеку windows.h
int g_nIndex = 0; //создание переменной для работы с массивом
const int MAX_TIMES = 300; //размер массива данных
DWORD g_dwTimes[MAX_TIMES]; //создание массива, с которым работают потоки
CRITICAL_SECTION g_CriticalSection; //создаём критическую секцию для синхронизации
int a = 10; //начинаем работу со значения 10
using namespace std; //использовать область std
static DWORD WINAPI FirstThread(void* pv) //Функция FirstThread для работы с потоком (static - сохраняет значение во время работы программы)
{
    BOOL fDone = FALSE; //переменная, работает с циклом, когда FALSE
    while (!fDone) // запуск цикла, работает пока fDone = FALSE
    {
        ::EnterCriticalSection(&g_CriticalSection); //вход в критическую секцию
        if (g_nIndex >= MAX_TIMES) //когда переменная больше (1000)
            fDone = TRUE; //выходим из цикла
        else // или
        {
            g_dwTimes[g_nIndex++] = a++; //заполняется массив временем с начала работы системы
            std::cout << "FirstThread " << g_dwTimes[g_nIndex - 1] << std::endl; // Вывожу текущее значение для первого потока 
        }
        ::LeaveCriticalSection(&g_CriticalSection); // выход из критической секции
    }
    return 0; //выход из функции FirstThread
}
static DWORD WINAPI SecondThread(void* pv) //Функция SecondThread для работы с потоком (static - сохраняет значение во время работы программы
{
    BOOL fDone = FALSE; //переменная, работает с циклом, когда FALSE
    while (!fDone) //запуск цикла, работает пока fDone = FALSE
    {
        ::EnterCriticalSection(&g_CriticalSection); //вход в критическую секцию
        if (g_nIndex >= MAX_TIMES) //когда переменная больше (1000)
            fDone = TRUE; //выходим из цикла
        else // или
        {
            g_dwTimes[g_nIndex++] = a++; //заполняется массив временем с начала работы системы
            std::cout << "\t                 SecondThread " << g_dwTimes[g_nIndex - 1] << std::endl; // Вывожу текущее значение для первого потока 
        }
        ::LeaveCriticalSection(&g_CriticalSection); // выход из критической секции
    }
    return 0; //выход из функции SecondThread
}
int main(int argc, char* argv[]) //главная функция для работы с потоком
{
    HANDLE hThreads[2]; //создание массива типа HANDLE (любой тип данных)
    ::InitializeCriticalSection(&g_CriticalSection); //инициализация критической секции
 
    DWORD dwThreadID; //создание персонального ID потокам
    hThreads[0] = ::CreateThread(NULL, 0, FirstThread,
        &dwThreadID, 0, &dwThreadID); /*создание первого потока (дескриптор безопасности (по умолчанию - NULL),
                                      размер стека в байтах (по умолчанию - 0),
                                      указатель на процедуру (с которого начинается выполнение потока),
                                      аргумент с предыдущего потока,
                                      флаг, записать dwThreadID созданного потока)*/
    hThreads[1] = ::CreateThread(NULL, 0, SecondThread,
        &dwThreadID, 0, &dwThreadID); /*создание первого потока (дескриптор безопасности (по умолчанию - NULL),
                                      размер стека в байтах (по умолчанию - 0),
                                      указатель на процедуру (с которого начинается выполнение потока),
                                      аргумент с предыдущего потока,
                                      флаг, записать dwThreadID созданного потока)*/
    ::WaitForMultipleObjects(2, hThreads, TRUE, INFINITE); // (кол-во ожидаемых объектов, тип ожидаемых объектов, ожидать все объекты, максимальное время ожидания)
    ::CloseHandle(hThreads[0]); // закрываем первый поток
    ::CloseHandle(hThreads[1]); // закрываем второй поток
    ::DeleteCriticalSection(&g_CriticalSection); //удаление критической функции
    return 0;
}
Добавлено через 8 минут
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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
#pragma warning (disable:4786)
#include <iostream>
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <windows.h>
#include <iomanip>
 
using namespace std;
 
static DWORD WINAPI FirstThread(void* pv); // Прототипы функций
static DWORD WINAPI SecondThread(void* pv); // которые будут участвовать в гонке потоков
static DWORD WINAPI ThirdThread(void* pv);
 
HANDLE g_hSemaphore; // Обьявляем Хендл семафора
HANDLE hStdout; // Хендл вывода информации в консоли
 
int Lid = 0, g_nIndex = 0; // Флаг, определяющий поток завершённый первым(лидерство), количество синхронизируемых потоков
int a[20], IndexResours = 0; // Общий ресурс и его индекс
 
LONG MaxCount = 3;  // Максимальное количество синхронизируемых семафором потоков
 
static DWORD WINAPI FirstThread(void* pv) {
 
    BOOL fDone = FALSE; // Флаг отработки потока  
 
    while (!fDone) { //запуск цикла, работает пока fDone = FALSE
 
        ::WaitForSingleObject(g_hSemaphore, INFINITE); // Ожидание запуска семафора на длительном интервале времени   
 
        if (g_nIndex >= MaxCount) // Проверяю, не создано ли потоков больше чем максимальное кол-во потоков         
            fDone = TRUE; //выходим из цикла
 
        else { //или
 
            g_nIndex++; // Количество потоков увеличиваю на 1  
 
            for (int i = 0; i <= 10; i++) { // Начинаю цикл для инициализации массива 10 временных задержек          
 
                IndexResours++;
                a[IndexResours - 1] = rand() % 1000;// Генерирую задержку первого потока (от 0 до 1000 миллисекунд)
                cout << setw(5) << a[IndexResours - 1] << " First "; // Вывожу текущую задержку для первого потока     
                Sleep(a[IndexResours - 1]);  // Осуществляю задерку на текущее количество миллисекунд          
            }
 
        }
 
        ::ReleaseSemaphore(g_hSemaphore, 1, 0); // Освобождаю семафор от данного потока   
    }
 
    if (!Lid) // Если лидирующий поток не определён, то делаю данный лидирующим        
        Lid = 1;
 
    return 0;
 
} //Функция (первый поток) FirstThread для работы с потоком (static - сохраняет значение во время работы программы)
 
static DWORD WINAPI SecondThread(void* pv) {
 
    BOOL fDone = FALSE;// Флаг отработки потока  
 
    while (!fDone) {
 
        ::WaitForSingleObject(g_hSemaphore, INFINITE);// Ожидание запуска семафора на длительном интервале времени      
 
        if (g_nIndex >= MaxCount)// Проверяю, не создано ли потоков больше чем максимальное кол-во потоков            
            fDone = TRUE;
 
        else {
 
            g_nIndex++;// Количество потоков увеличиваю на 1 
 
            for (int i = 0; i <= 10; i++) {// Начинаю цикл для инициализации массива 10-ти временных задержек            
 
                IndexResours++;
                a[IndexResours - 1] = rand() % 1000;// Генерирую задержку второго потока (от 0 до 1000 миллисекунд) 
                cout << setw(5) << a[IndexResours - 1] << " Second  "; // Вывожу текущую задержку для второго потока 
                Sleep(a[IndexResours - 1]); // Осуществляю задерку на текущее количество миллисекунд 
            }
 
        }
 
        ::ReleaseSemaphore(g_hSemaphore, 1, 0);// Освобождаю семафор от данного потока   
    }
 
    if (!Lid)// Если лидирующий поток не определён, то делаю данный лидирующим        
        Lid = 2;
 
    return 0;
 
} // второй поток
 
static DWORD WINAPI ThirdThread(void* pv) {
 
    BOOL fDone = FALSE;// Флаг отработки потока    
    while (!fDone) {
 
        ::WaitForSingleObject(g_hSemaphore, INFINITE);// Ожидание запуска семафора на длительном интервале времени        
        if (g_nIndex >= MaxCount)// Проверяю, не создано ли потоков больше чем максимальное кол-во потоков            
            fDone = TRUE;
 
        else {
 
            g_nIndex++;// Количество потоков увеличиваю на 1 
 
            for (int i = 0; i <= 10; i++) {// Начинаю цикл для инициализации массива 10-ти временных задержек           
 
                IndexResours++;
                a[IndexResours - 1] = rand() % 1000;// Генерирую задержку второго потока (от 0 до 1000 миллисекунд)      
                cout << setw(5) << a[IndexResours - 1] << " Third  ";// Вывожу текущую задержку для третьего потока     
                Sleep(a[IndexResours - 1]);// Осуществляю задерку на текущее количество миллисекунд 
                cout << "\n\n";
            }
 
        }
        ::ReleaseSemaphore(g_hSemaphore, 1, 0);// Освобождаю семафор от данного потока    
    }
 
    if (!Lid)// Если лидирующий поток не определён, то делаю данный лидирующим        
        Lid = 3;
 
    return 0;
 
} // третий поток
 
int main(void) {
 
    srand(time(NULL)); // Включаю генератор случайных чисел
 
    system("title Лабораторная работа by Дмитрий Иванов");
 
    SetConsoleCP(1251);
    SetConsoleOutputCP(1251); // кириллица в консоли
 
    const int CountReload = 3; // кол-во перезапусков алгоритмы 
 
    const int ThreadCount = 3; // кол-во потоков
    int FinishCounts[ThreadCount]; // массив счетчик кол-ва первых завершенных потоков
 
    for (int i = 0; i < ThreadCount; i++)
        FinishCounts[i] = 0;
 
    hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
    DWORD dw; // Обьект синхронизации        
    LONG g_iCount = 3; // начальное значение семафора        
    HANDLE hThreads[ThreadCount]; // Массив Хендлов потоков
 
    for (int i = 0; i < CountReload; i++) {
 
        cout << "Счетчик запуска алгоритма: " << i + 1 << "\n---------------------------------------------\n\n";
 
        g_hSemaphore = ::CreateSemaphore(NULL, g_iCount, MaxCount, NULL); // Создаем семафор и инициализируем его Хендл
        hThreads[0] = ::CreateThread(NULL, 0, FirstThread, NULL, 0, &dw); // Создаем потоки        
        hThreads[1] = ::CreateThread(NULL, 0, SecondThread, NULL, 0, &dw);
        hThreads[2] = ::CreateThread(NULL, 0, ThirdThread, NULL, 0, &dw); // и инициализируем Массив Хендлов потоков
 
        for (int c = 0; c < ThreadCount; c++)
            ::ResumeThread(hThreads[c]); //Запускаем потоки        
 
        ::WaitForMultipleObjects(3, hThreads, TRUE, INFINITE); // Ожидаем окончание работы 3 потоков на очень длительном интервале времени        
 
        cout << "\n";
 
        switch (Lid) { //определяем поток, который завершился первым          
 
        case 1:
            cout << "\n Первый";
            FinishCounts[0]++;
            break;
        case 2:
            cout << "\n Второй";
            FinishCounts[1]++;
            break;
        case 3:
            cout << "\n Третий";
            FinishCounts[2]++;
            break;
 
        }
 
        cout << " поток завершился первым\n";
 
        g_nIndex = 0;
        IndexResours = 0;
 
        for (int c = 0; c < ThreadCount; c++)
            ::CloseHandle(hThreads[c]); // Закрываем созданные потоки  
 
        ::CloseHandle(g_hSemaphore); // и сам семафор   
        Sleep(5000);
        system("cls");
 
    }
 
    cout << "Программа завершила свою работу\n---------------------------------------------\n\n";
 
    for (int c = 0; c < ThreadCount; c++) {
 
        if (c == 0)
            cout << "Первый ";
 
        else if (c == 1)
            cout << "Второй ";
 
        else if (c == 2)
            cout << "Третий ";
 
        cout << "поток завершился первым: " << FinishCounts[c] << " раз\n\n";
 
    }
 
    system("pause");
    return 0; // завершение программы
}
Добавлено через 22 минуты
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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#include <iostream>
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <windows.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILEstatic char THIS_FILE[] = __FILE__;
#endif
using namespace std; static DWORD WINAPI FirstThread(void* pv);       // Прототипы функций
static DWORD WINAPI SecondThread(void* pv);      // которые будут участвовать в гонке <designtimesp=21150> потоков
HANDLE g_hSemaphore;       // Обьявляем Хендл семафора
HANDLE hStdout;            // Хендл вывода информации в консоли
int Lid = 0, g_nIndex = 0;     // Флаг, определяющий поток завершённый первым(лидерство), количество синхронизируемых потоков
int a[10], IndexResours = 0;  // Общий ресурс и его индекс
LONG MaxCount = 3;         // Максимальное количество синхронизируемых семафором потоков
 
 
static DWORD WINAPI FirstThread(void* pv)
 
{
    COORD pos;          // Переменная, которая будет хранить текущую координату курсора  
    pos.X = 3;                     // Столбец отображения значений первого потока     
    BOOL fDone = FALSE;                       // Флаг отработки потока  
    while (!fDone)
    {
        ::WaitForSingleObject(g_hSemaphore, INFINITE);    // Ожидание запуска семафора на длительном интервале времени        
        if (g_nIndex >= MaxCount)                          // Проверяю, не создано ли потоков больше чем максимальное кол-во потоков          
            fDone = TRUE;
        else
        {
            g_nIndex++;                              // Количество потоков увеличиваю на 1            
            for (int i = 0; i <= 10; i++)                // Начинаю цикл для инициализации массива         
            {
 
                IndexResours++;
 
                a[IndexResours - 1] = rand() % 200;          // Генерирую значения     
 
                pos.Y = i;
                SetConsoleCursorPosition(hStdout, pos); // Устанавливаю курсор в i - тую строку          
                printf("%d", a[IndexResours - 1]);         // Выводим значения
                Sleep(a[IndexResours - 1]);                  // Осуществляю задерку  
 
 
            }
        }
        ::ReleaseSemaphore(g_hSemaphore, 1, 0);           // Освобождаю семафор от данного потока    
    }
    return 0;
}
static DWORD WINAPI SecondThread(void* pv)
{
    COORD pos;          // Переменная, которая будет хранить текущую координату курсора                     // Массив задержек второго потока    
    pos.X = 25;       // Столбец отображения значений второго потока   
    BOOL fDone = FALSE;                              // Флаг отработки потока    
    while (!fDone)
    {
        ::WaitForSingleObject(g_hSemaphore, INFINITE);    // Ожидание запуска семафора на длительном интервале времени        
        if (g_nIndex >= MaxCount)      // Проверяю, не создано ли потоков больше чем максимальное кол-во потоков            
            fDone = TRUE;
        else
        {
            g_nIndex++;             // Количество потоков увеличиваю на 1            
            for (int i = 0; i <= 10; i++)          // Начинаю цикл для инициализации массива            
            {
                IndexResours++;
 
                a[IndexResours - 1] = i + 1;              // заполняем массив значениями
                pos.Y = i;
                SetConsoleCursorPosition(hStdout, pos);     // Устанавливаю курсор в i - тую строку                       // Выводим значения 
                printf("%d", a[IndexResours - 1]);       //  Выводим значения 
                Sleep(100);
 
            }
        }
        ::ReleaseSemaphore(g_hSemaphore, 1, 0); // Освобождаю семафор от данного потока    
    }
    return 0;
}
static DWORD WINAPI FirstThread1(void* pv)
{
    COORD pos;         // Переменная, которая будет хранить текущую координату курсора
    pos.X = 50;      // Столбец отображения значений третьего потока 
    BOOL fDone = FALSE;    // Флаг отработки потока
    while (!fDone)
    {
        ::WaitForSingleObject(g_hSemaphore, INFINITE); // Ожидание запуска семафора на длительном интервале времени  
        if (g_nIndex >= MaxCount)
            fDone = TRUE;
        else
        {
            g_nIndex++;           // Количество потоков увеличиваю на 1  
            for (int i = 0; i <= 10; i++)            // Начинаю цикл для инициализации массива 
            {
                IndexResours++;
                a[IndexResours - 1] = i + 3;        // заполняем массив значениями
                pos.Y = i;
                SetConsoleCursorPosition(hStdout, pos); // Устанавливаю курсор в i - тую строку                     
                printf("%d", a[IndexResours - 1]);       // Выводим значения
                Sleep(100);
 
            }
        }
        ::ReleaseSemaphore(g_hSemaphore, 1, 0);   // Освобождаю семафор от данного потока
    }
    return 0;
}
 
int main(int argc, TCHAR* argv[], TCHAR* envp[])
{
    int nRetCode = 0;
    hStdout = GetStdHandle(STD_OUTPUT_HANDLE); // дискриптор
    {
        DWORD dw;                                    // Обьект синхронизации        
        LONG g_iCount = 3;                           // начальное значение семафора        
        HANDLE hThreads[3];                          // Массив Хендлов потоков        
        g_hSemaphore = ::CreateSemaphore(NULL, g_iCount, MaxCount, NULL);    // Создаем семафор и инициализируем его Хендл      
        hThreads[0] = ::CreateThread(NULL, 0, FirstThread, NULL, 0, &dw);   // Создаем потоки        
        hThreads[1] = ::CreateThread(NULL, 0, SecondThread, NULL, 0, &dw);  // и инициализируем Массив Хендлов потоков    
        hThreads[2] = ::CreateThread(NULL, 0, FirstThread1, NULL, 0, &dw);
        ::ResumeThread(hThreads[0]);                           //Запускаем потоки        
        ::ResumeThread(hThreads[1]);
        ::ResumeThread(hThreads[2]);
        ::WaitForMultipleObjects(3, hThreads, TRUE, INFINITE);   // Ожидаем окончание работы 3 потоков на очень длительном интервале времени        
        ::CloseHandle(hThreads[0]);              // Закрываем созданные потоки        
        ::CloseHandle(hThreads[1]);
        ::CloseHandle(hThreads[2]);
        ::CloseHandle(g_hSemaphore);                      // и сам семафор        
 
    }
    return 0;
}
0
2 / 2 / 0
Регистрация: 24.02.2019
Сообщений: 138
18.11.2020, 20:57  [ТС]
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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
#include <windows.h> //подключаем библиотеку windows.h
#include <iostream> //библиотека для ввода-вывода
#include <time.h>
#include <queue>
#include <cstring>
#include <sstream>
using namespace std;
int g_nIndex = 0; //создание переменной для работы с массивом
const int MAX_TIMES = 100; //размер массива данных
DWORD g_dwTimes[MAX_TIMES]; //создание массива, с которым работают потоки
HANDLE g_hMutex; // переменная для создания мьютекса
int a = 1;
 
queue <string> Que; // очередь сообщений
 
const static std::string Convert_Int_toString (int Number) {
 
    std::ostringstream ConverInt_ToString;
    ConverInt_ToString << Number;
 
    return std::string(ConverInt_ToString.str());
 
} // функция преобразования из int в string
 
int RandNumColor (void) {
    
    int min = 1;
    int max = 15;
    
    return min + rand () % (max - min + 1);
    
} // функция рандома номера цвета
 
static DWORD WINAPI FirstThread(void* pv) //Функция FirstThread для работы с потоком (static - сохраняет значение во время работы программы)
{
    BOOL fDone = FALSE; //переменная, работает с циклом, когда FALSE
    while (!fDone) //запуск цикла, работает пока fDone = FALSE
    {
        ::WaitForSingleObject(g_hMutex, INFINITE); /*g_hMutex,  ID объекта 
            INFINITE время ожидания в миллисекундах
            WaitForSingleObject ждём появление потока, потом Mutex  блокирует доступ другим потокам*/
        if (g_nIndex >= MAX_TIMES) //если g_nIndex больше (1000)
            fDone = TRUE; //выходим из цикла
        else //или
        {
            g_dwTimes[g_nIndex++] = a++; //заполняется массив временем с начала работы системы
                        
            //std::cout << "FirstThread " << g_dwTimes[g_nIndex - 1] << std::endl; // Вывожу текущее значение для первого потока 
            Que.push ("FirstThread: " + Convert_Int_toString(g_dwTimes[g_nIndex - 1]));
 
        }
        ::ReleaseMutex(g_hMutex); //Освобождаю Mutex
    }
    return 0; //выход из функции FirstThread
}
static DWORD WINAPI SecondThread(void* pv) //Функция SecondThread для работы с потоком (static - сохраняет значение во время работы программы)
{
    BOOL fDone = FALSE; //переменная, работает с циклом, когда FALSE
    while (!fDone) //запуск цикла, работает пока fDone = FALSE
    {
        ::WaitForSingleObject(g_hMutex, INFINITE); /*g_hMutex,  ID объекта 
            INFINITE время ожидания в миллисекундах
            WaitForSingleObject ждём появление потока, потом Mutex  блокирует доступ другим потокам*/
        if (g_nIndex >= MAX_TIMES) //если g_nIndex больше (1000)
            fDone = TRUE; //выходим из цикла
        else //или
        {
            g_dwTimes[g_nIndex++] = a++; //заполняется массив временем с начала работы системы
            
            //std::cout << "SecondThread " << g_dwTimes[g_nIndex - 1] << std::endl; // Вывожу текущее значение для второго потока 
            Que.push ("SecondThread: " + Convert_Int_toString(g_dwTimes[g_nIndex - 1]));
            
        }
        ::ReleaseMutex(g_hMutex); //Освобождаю Mutex
    }
    return 0; //выход из функции SecondThread
}
static DWORD WINAPI ThirdThread(void* pv) //Функция ThirdThread для работы с потоком (static - сохраняет значение во время работы программы)
{
    BOOL fDone = FALSE; //переменная, работает с циклом, когда FALSE
    while (!fDone) //запуск цикла, работает пока fDone = FALSE
    {
        ::WaitForSingleObject(g_hMutex, INFINITE); /*g_hMutex,  ID объекта 
            INFINITE время ожидания в миллисекундах
            WaitForSingleObject ждём появление потока, потом Mutex  блокирует доступ другим потокам*/
        if (g_nIndex >= MAX_TIMES) //если g_nIndex больше (1000)
            fDone = TRUE; //выходим из цикла
        else //или
        {
            g_dwTimes[g_nIndex++] = a++; //заполняется массив временем с начала работы системы
            
            //std::cout << "ThirdThread " << g_dwTimes[g_nIndex - 1] << std::endl; // Вывожу текущее значение для третьего потока 
            Que.push ("ThirdThread: " + Convert_Int_toString(g_dwTimes[g_nIndex - 1]));
            
        }
        ::ReleaseMutex(g_hMutex); //Освобождаю Mutex
    }
    return 0; //выход из функции ThirdThread
}
static DWORD WINAPI FourThread(void* pv) //Функция FourThread для работы с потоком (static - сохраняет значение во время работы программы)
{
    BOOL fDone = FALSE; //переменная, работает с циклом, когда FALSE
    while (!fDone) //запуск цикла, работает пока fDone = FALSE
    {
        ::WaitForSingleObject(g_hMutex, INFINITE); /*g_hMutex,  ID объекта 
            INFINITE время ожидания в миллисекундах
            WaitForSingleObject ждём появление потока, потом Mutex  блокирует доступ другим потокам*/
        if (g_nIndex >= MAX_TIMES) //если g_nIndex больше (1000)
            fDone = TRUE; //выходим из цикла
        else //или
        {
    
            g_dwTimes[g_nIndex++] = a++; //заполняется массив временем с начала работы системы
            //std::cout << "FourThread " << g_dwTimes[g_nIndex - 1] << std::endl; // Вывожу текущее значение для четвёртого потока 
            Que.push ("FourThread: " + Convert_Int_toString(g_dwTimes[g_nIndex - 1]));
            
        }
        ::ReleaseMutex(g_hMutex); //Освобождаю Mutex
    }
    return 0; //выход из функции FourThread
}
 
static DWORD WINAPI FiveThread(void* pv) //Функция FiveThread для работы с потоком (static - сохраняет значение во время работы программы)
{
    BOOL fDone = FALSE; //переменная, работает с циклом, когда FALSE
    while (!fDone) //запуск цикла, работает пока fDone = FALSE
    {
        ::WaitForSingleObject(g_hMutex, INFINITE); /*g_hMutex,  ID объекта 
            INFINITE время ожидания в миллисекундах
            WaitForSingleObject ждём появление потока, потом Mutex  блокирует доступ другим потокам*/
        if (g_nIndex >= MAX_TIMES) //если g_nIndex больше (1000)
            fDone = TRUE; //выходим из цикла
        else //или
        {
            
            g_dwTimes[g_nIndex++] = a++; //заполняется массив временем с начала работы системы
            //std::cout << "FiveThread " << g_dwTimes[g_nIndex - 1] << std::endl; // Вывожу текущее значение для пятого потока
            Que.push ("FiveThread: " + Convert_Int_toString(g_dwTimes[g_nIndex - 1]));
            
        }
        ::ReleaseMutex(g_hMutex); //Освобождаю Mutex
    }
    return 0; //выход из функции FiveThread
}
 
int main(void) //главная функция для работы с потоком
{
    srand(time(NULL));
    HANDLE hThreads[5]; //создание массива типа HANDLE (любой тип данных)
    DWORD dwThreadID; // ID потока
    hThreads[0] = ::CreateThread(NULL, 0, FirstThread, NULL,
        CREATE_SUSPENDED, &dwThreadID);/*создание первого потока (дескриптор безопасности (по умолчанию - NULL), 
                                      размер стека в байтах (по умолчанию - 0), 
                                      указатель на процедуру (с которого начинается выполнение потока), 
                                      аргумент с предыдущего потока, 
                                     CREATE_SUSPENDED позволяет создаёт поток в спящем режиме, и он
                                    не запускается до тех пор пока не будет вызвана функция ResumeThread, 
                                    записать dwThreadID созданного потока*/
    hThreads[1] = ::CreateThread(NULL, 0, SecondThread, NULL,
        CREATE_SUSPENDED, &dwThreadID); /*создание второго потока (дескриптор безопасности (по умолчанию - NULL), 
                                      размер стека в байтах (по умолчанию - 0), 
                                      указатель на процедуру (с которого начинается выполнение потока), 
                                      аргумент с предыдущего потока, 
                                     CREATE_SUSPENDED позволяет создаёт поток в спящем режиме, и он
                                    не запускается до тех пор пока не будет вызвана функция ResumeThread, 
                                    записать dwThreadID созданного потока*/
    hThreads[2] = ::CreateThread(NULL, 0, ThirdThread, NULL,
        CREATE_SUSPENDED, &dwThreadID); /*создание третьего потока (дескриптор безопасности (по умолчанию - NULL), 
                                      размер стека в байтах (по умолчанию - 0), 
                                      указатель на процедуру (с которого начинается выполнение потока), 
                                      аргумент с предыдущего потока, 
                                     CREATE_SUSPENDED позволяет создаёт поток в спящем режиме, и он
                                    не запускается до тех пор пока не будет вызвана функция ResumeThread, 
                                    записать dwThreadID созданного потока*/
    hThreads[3] = ::CreateThread(NULL, 0, FourThread, NULL,
        CREATE_SUSPENDED, &dwThreadID); /*создание четвёртого потока (дескриптор безопасности (по умолчанию - NULL),
                                      размер стека в байтах (по умолчанию - 0), 
                                      указатель на процедуру (с которого начинается выполнение потока), 
                                      аргумент с предыдущего потока
                                    записать dwThreadID созданного потока*/
    g_hMutex = ::CreateMutex(NULL, FALSE, NULL);//создаем мьютекс после 3 потока
    hThreads[4] = ::CreateThread(NULL, 0, FiveThread, NULL,
        0, &dwThreadID); /*создание пятого потока (дескриптор безопасности (по умолчанию - NULL), 
                                      размер стека в байтах (по умолчанию - 0), 
                                      указатель на процедуру (с которого начинается выполнение потока), 
                                      аргумент с предыдущего потока
                                    записать dwThreadID созданного потока*/
    ::ResumeThread(hThreads[0]);//запускаем наши  потоки
    ::ResumeThread(hThreads[1]);
    ::ResumeThread(hThreads[2]);
    ::ResumeThread(hThreads[3]);
    ::WaitForMultipleObjects(5, hThreads, TRUE, INFINITE);
    ::CloseHandle(hThreads[0]);
    ::CloseHandle(hThreads[1]);
    ::CloseHandle(hThreads[2]);
    ::CloseHandle(hThreads[3]);
    ::CloseHandle(hThreads[4]);
    ::CloseHandle(g_hMutex);
    
        while (!Que.empty()) {
            
            SetConsoleTextAttribute (GetStdHandle (STD_OUTPUT_HANDLE), (WORD) ((0 << 4) | RandNumColor()));
                
            int min = 1;
            int max = 1024;
                
                for (int i = 0; i < (min + rand () % (max - min + 1)); i++)
                    cout << " ";
            
            cout << Que.front () << "\n";
            Que.pop ();
            
        } // отображаем очередь из сообщений с рандомизацией цвета для каждого
        
    SetConsoleTextAttribute (GetStdHandle (STD_OUTPUT_HANDLE), (WORD) ((0 << 4) | 7));
 
    return 0;
}
Добавлено через 17 секунд
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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
#include <windows.h> //подключаем библиотеку windows.h
#include <iostream> //библиотека для ввода-вывода
#include <time.h>
#include <queue>
#include <cstring>
#include <sstream>
using namespace std;
int g_nIndex = 0; //создание переменной для работы с массивом
const int MAX_TIMES = 100; //размер массива данных
DWORD g_dwTimes[MAX_TIMES]; //создание массива, с которым работают потоки
HANDLE g_hMutex; // переменная для создания мьютекса
int a = 1;
 
queue <string> Que; // очередь сообщений
 
const static std::string Convert_Int_toString (int Number) {
 
    std::ostringstream ConverInt_ToString;
    ConverInt_ToString << Number;
 
    return std::string(ConverInt_ToString.str());
 
} // функция преобразования из int в string
 
int RandNumColor (void) {
    
    int min = 1;
    int max = 15;
    
    return min + rand () % (max - min + 1);
    
} // функция рандома номера цвета
 
static DWORD WINAPI FirstThread(void* pv) //Функция FirstThread для работы с потоком (static - сохраняет значение во время работы программы)
{
    BOOL fDone = FALSE; //переменная, работает с циклом, когда FALSE
    while (!fDone) //запуск цикла, работает пока fDone = FALSE
    {
        ::WaitForSingleObject(g_hMutex, INFINITE); /*g_hMutex,  ID объекта 
            INFINITE время ожидания в миллисекундах
            WaitForSingleObject ждём появление потока, потом Mutex  блокирует доступ другим потокам*/
        if (g_nIndex >= MAX_TIMES) //если g_nIndex больше (1000)
            fDone = TRUE; //выходим из цикла
        else //или
        {
            g_dwTimes[g_nIndex++] = a++; //заполняется массив временем с начала работы системы
                        
            //std::cout << "FirstThread " << g_dwTimes[g_nIndex - 1] << std::endl; // Вывожу текущее значение для первого потока 
            Que.push ("FirstThread: " + Convert_Int_toString(g_dwTimes[g_nIndex - 1]));
 
        }
        ::ReleaseMutex(g_hMutex); //Освобождаю Mutex
    }
    return 0; //выход из функции FirstThread
}
static DWORD WINAPI SecondThread(void* pv) //Функция SecondThread для работы с потоком (static - сохраняет значение во время работы программы)
{
    BOOL fDone = FALSE; //переменная, работает с циклом, когда FALSE
    while (!fDone) //запуск цикла, работает пока fDone = FALSE
    {
        ::WaitForSingleObject(g_hMutex, INFINITE); /*g_hMutex,  ID объекта 
            INFINITE время ожидания в миллисекундах
            WaitForSingleObject ждём появление потока, потом Mutex  блокирует доступ другим потокам*/
        if (g_nIndex >= MAX_TIMES) //если g_nIndex больше (1000)
            fDone = TRUE; //выходим из цикла
        else //или
        {
            g_dwTimes[g_nIndex++] = a++; //заполняется массив временем с начала работы системы
            
            //std::cout << "SecondThread " << g_dwTimes[g_nIndex - 1] << std::endl; // Вывожу текущее значение для второго потока 
            Que.push ("SecondThread: " + Convert_Int_toString(g_dwTimes[g_nIndex - 1]));
            
        }
        ::ReleaseMutex(g_hMutex); //Освобождаю Mutex
    }
    return 0; //выход из функции SecondThread
}
static DWORD WINAPI ThirdThread(void* pv) //Функция ThirdThread для работы с потоком (static - сохраняет значение во время работы программы)
{
    BOOL fDone = FALSE; //переменная, работает с циклом, когда FALSE
    while (!fDone) //запуск цикла, работает пока fDone = FALSE
    {
        ::WaitForSingleObject(g_hMutex, INFINITE); /*g_hMutex,  ID объекта 
            INFINITE время ожидания в миллисекундах
            WaitForSingleObject ждём появление потока, потом Mutex  блокирует доступ другим потокам*/
        if (g_nIndex >= MAX_TIMES) //если g_nIndex больше (1000)
            fDone = TRUE; //выходим из цикла
        else //или
        {
            g_dwTimes[g_nIndex++] = a++; //заполняется массив временем с начала работы системы
            
            //std::cout << "ThirdThread " << g_dwTimes[g_nIndex - 1] << std::endl; // Вывожу текущее значение для третьего потока 
            Que.push ("ThirdThread: " + Convert_Int_toString(g_dwTimes[g_nIndex - 1]));
            
        }
        ::ReleaseMutex(g_hMutex); //Освобождаю Mutex
    }
    return 0; //выход из функции ThirdThread
}
static DWORD WINAPI FourThread(void* pv) //Функция FourThread для работы с потоком (static - сохраняет значение во время работы программы)
{
    BOOL fDone = FALSE; //переменная, работает с циклом, когда FALSE
    while (!fDone) //запуск цикла, работает пока fDone = FALSE
    {
        ::WaitForSingleObject(g_hMutex, INFINITE); /*g_hMutex,  ID объекта 
            INFINITE время ожидания в миллисекундах
            WaitForSingleObject ждём появление потока, потом Mutex  блокирует доступ другим потокам*/
        if (g_nIndex >= MAX_TIMES) //если g_nIndex больше (1000)
            fDone = TRUE; //выходим из цикла
        else //или
        {
    
            g_dwTimes[g_nIndex++] = a++; //заполняется массив временем с начала работы системы
            //std::cout << "FourThread " << g_dwTimes[g_nIndex - 1] << std::endl; // Вывожу текущее значение для четвёртого потока 
            Que.push ("FourThread: " + Convert_Int_toString(g_dwTimes[g_nIndex - 1]));
            
        }
        ::ReleaseMutex(g_hMutex); //Освобождаю Mutex
    }
    return 0; //выход из функции FourThread
}
 
static DWORD WINAPI FiveThread(void* pv) //Функция FiveThread для работы с потоком (static - сохраняет значение во время работы программы)
{
    BOOL fDone = FALSE; //переменная, работает с циклом, когда FALSE
    while (!fDone) //запуск цикла, работает пока fDone = FALSE
    {
        ::WaitForSingleObject(g_hMutex, INFINITE); /*g_hMutex,  ID объекта 
            INFINITE время ожидания в миллисекундах
            WaitForSingleObject ждём появление потока, потом Mutex  блокирует доступ другим потокам*/
        if (g_nIndex >= MAX_TIMES) //если g_nIndex больше (1000)
            fDone = TRUE; //выходим из цикла
        else //или
        {
            
            g_dwTimes[g_nIndex++] = a++; //заполняется массив временем с начала работы системы
            //std::cout << "FiveThread " << g_dwTimes[g_nIndex - 1] << std::endl; // Вывожу текущее значение для пятого потока
            Que.push ("FiveThread: " + Convert_Int_toString(g_dwTimes[g_nIndex - 1]));
            
        }
        ::ReleaseMutex(g_hMutex); //Освобождаю Mutex
    }
    return 0; //выход из функции FiveThread
}
 
int main(void) //главная функция для работы с потоком
{
    srand(time(NULL));
    HANDLE hThreads[5]; //создание массива типа HANDLE (любой тип данных)
    DWORD dwThreadID; // ID потока
    hThreads[0] = ::CreateThread(NULL, 0, FirstThread, NULL,
        CREATE_SUSPENDED, &dwThreadID);/*создание первого потока (дескриптор безопасности (по умолчанию - NULL), 
                                      размер стека в байтах (по умолчанию - 0), 
                                      указатель на процедуру (с которого начинается выполнение потока), 
                                      аргумент с предыдущего потока, 
                                     CREATE_SUSPENDED позволяет создаёт поток в спящем режиме, и он
                                    не запускается до тех пор пока не будет вызвана функция ResumeThread, 
                                    записать dwThreadID созданного потока*/
    hThreads[1] = ::CreateThread(NULL, 0, SecondThread, NULL,
        CREATE_SUSPENDED, &dwThreadID); /*создание второго потока (дескриптор безопасности (по умолчанию - NULL), 
                                      размер стека в байтах (по умолчанию - 0), 
                                      указатель на процедуру (с которого начинается выполнение потока), 
                                      аргумент с предыдущего потока, 
                                     CREATE_SUSPENDED позволяет создаёт поток в спящем режиме, и он
                                    не запускается до тех пор пока не будет вызвана функция ResumeThread, 
                                    записать dwThreadID созданного потока*/
    hThreads[2] = ::CreateThread(NULL, 0, ThirdThread, NULL,
        CREATE_SUSPENDED, &dwThreadID); /*создание третьего потока (дескриптор безопасности (по умолчанию - NULL), 
                                      размер стека в байтах (по умолчанию - 0), 
                                      указатель на процедуру (с которого начинается выполнение потока), 
                                      аргумент с предыдущего потока, 
                                     CREATE_SUSPENDED позволяет создаёт поток в спящем режиме, и он
                                    не запускается до тех пор пока не будет вызвана функция ResumeThread, 
                                    записать dwThreadID созданного потока*/
    hThreads[3] = ::CreateThread(NULL, 0, FourThread, NULL,
        CREATE_SUSPENDED, &dwThreadID); /*создание четвёртого потока (дескриптор безопасности (по умолчанию - NULL),
                                      размер стека в байтах (по умолчанию - 0), 
                                      указатель на процедуру (с которого начинается выполнение потока), 
                                      аргумент с предыдущего потока
                                    записать dwThreadID созданного потока*/
    g_hMutex = ::CreateMutex(NULL, FALSE, NULL);//создаем мьютекс после 3 потока
    hThreads[4] = ::CreateThread(NULL, 0, FiveThread, NULL,
        0, &dwThreadID); /*создание пятого потока (дескриптор безопасности (по умолчанию - NULL), 
                                      размер стека в байтах (по умолчанию - 0), 
                                      указатель на процедуру (с которого начинается выполнение потока), 
                                      аргумент с предыдущего потока
                                    записать dwThreadID созданного потока*/
    ::ResumeThread(hThreads[0]);//запускаем наши  потоки
    ::ResumeThread(hThreads[1]);
    ::ResumeThread(hThreads[2]);
    ::ResumeThread(hThreads[3]);
    ::WaitForMultipleObjects(5, hThreads, TRUE, INFINITE);
    ::CloseHandle(hThreads[0]);
    ::CloseHandle(hThreads[1]);
    ::CloseHandle(hThreads[2]);
    ::CloseHandle(hThreads[3]);
    ::CloseHandle(hThreads[4]);
    ::CloseHandle(g_hMutex);
    
        while (!Que.empty()) {
            
            SetConsoleTextAttribute (GetStdHandle (STD_OUTPUT_HANDLE), (WORD) ((0 << 4) | RandNumColor()));
                
            int min = 1;
            int max = 1024;
                
                for (int i = 0; i < (min + rand () % (max - min + 1)); i++)
                    cout << " ";
            
            cout << Que.front () << "\n";
            Que.pop ();
            
        } // отображаем очередь из сообщений с рандомизацией цвета для каждого
        
    SetConsoleTextAttribute (GetStdHandle (STD_OUTPUT_HANDLE), (WORD) ((0 << 4) | 7));
 
    return 0;
}
0
2 / 2 / 0
Регистрация: 24.02.2019
Сообщений: 138
18.11.2020, 20:57  [ТС]
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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
#include <windows.h> //подключаем библиотеку windows.h
#include <iostream> //библиотека для ввода-вывода
#include <time.h>
#include <queue>
#include <cstring>
#include <sstream>
using namespace std;
int g_nIndex = 0; //создание переменной для работы с массивом
const int MAX_TIMES = 100; //размер массива данных
DWORD g_dwTimes[MAX_TIMES]; //создание массива, с которым работают потоки
HANDLE g_hMutex; // переменная для создания мьютекса
int a = 1;
 
queue <string> Que; // очередь сообщений
 
const static std::string Convert_Int_toString (int Number) {
 
    std::ostringstream ConverInt_ToString;
    ConverInt_ToString << Number;
 
    return std::string(ConverInt_ToString.str());
 
} // функция преобразования из int в string
 
int RandNumColor (void) {
    
    int min = 1;
    int max = 15;
    
    return min + rand () % (max - min + 1);
    
} // функция рандома номера цвета
 
static DWORD WINAPI FirstThread(void* pv) //Функция FirstThread для работы с потоком (static - сохраняет значение во время работы программы)
{
    BOOL fDone = FALSE; //переменная, работает с циклом, когда FALSE
    while (!fDone) //запуск цикла, работает пока fDone = FALSE
    {
        ::WaitForSingleObject(g_hMutex, INFINITE); /*g_hMutex,  ID объекта 
            INFINITE время ожидания в миллисекундах
            WaitForSingleObject ждём появление потока, потом Mutex  блокирует доступ другим потокам*/
        if (g_nIndex >= MAX_TIMES) //если g_nIndex больше (1000)
            fDone = TRUE; //выходим из цикла
        else //или
        {
            g_dwTimes[g_nIndex++] = a++; //заполняется массив временем с начала работы системы
                        
            //std::cout << "FirstThread " << g_dwTimes[g_nIndex - 1] << std::endl; // Вывожу текущее значение для первого потока 
            Que.push ("FirstThread: " + Convert_Int_toString(g_dwTimes[g_nIndex - 1]));
 
        }
        ::ReleaseMutex(g_hMutex); //Освобождаю Mutex
    }
    return 0; //выход из функции FirstThread
}
static DWORD WINAPI SecondThread(void* pv) //Функция SecondThread для работы с потоком (static - сохраняет значение во время работы программы)
{
    BOOL fDone = FALSE; //переменная, работает с циклом, когда FALSE
    while (!fDone) //запуск цикла, работает пока fDone = FALSE
    {
        ::WaitForSingleObject(g_hMutex, INFINITE); /*g_hMutex,  ID объекта 
            INFINITE время ожидания в миллисекундах
            WaitForSingleObject ждём появление потока, потом Mutex  блокирует доступ другим потокам*/
        if (g_nIndex >= MAX_TIMES) //если g_nIndex больше (1000)
            fDone = TRUE; //выходим из цикла
        else //или
        {
            g_dwTimes[g_nIndex++] = a++; //заполняется массив временем с начала работы системы
            
            //std::cout << "SecondThread " << g_dwTimes[g_nIndex - 1] << std::endl; // Вывожу текущее значение для второго потока 
            Que.push ("SecondThread: " + Convert_Int_toString(g_dwTimes[g_nIndex - 1]));
            
        }
        ::ReleaseMutex(g_hMutex); //Освобождаю Mutex
    }
    return 0; //выход из функции SecondThread
}
static DWORD WINAPI ThirdThread(void* pv) //Функция ThirdThread для работы с потоком (static - сохраняет значение во время работы программы)
{
    BOOL fDone = FALSE; //переменная, работает с циклом, когда FALSE
    while (!fDone) //запуск цикла, работает пока fDone = FALSE
    {
        ::WaitForSingleObject(g_hMutex, INFINITE); /*g_hMutex,  ID объекта 
            INFINITE время ожидания в миллисекундах
            WaitForSingleObject ждём появление потока, потом Mutex  блокирует доступ другим потокам*/
        if (g_nIndex >= MAX_TIMES) //если g_nIndex больше (1000)
            fDone = TRUE; //выходим из цикла
        else //или
        {
            g_dwTimes[g_nIndex++] = a++; //заполняется массив временем с начала работы системы
            
            //std::cout << "ThirdThread " << g_dwTimes[g_nIndex - 1] << std::endl; // Вывожу текущее значение для третьего потока 
            Que.push ("ThirdThread: " + Convert_Int_toString(g_dwTimes[g_nIndex - 1]));
            
        }
        ::ReleaseMutex(g_hMutex); //Освобождаю Mutex
    }
    return 0; //выход из функции ThirdThread
}
static DWORD WINAPI FourThread(void* pv) //Функция FourThread для работы с потоком (static - сохраняет значение во время работы программы)
{
    BOOL fDone = FALSE; //переменная, работает с циклом, когда FALSE
    while (!fDone) //запуск цикла, работает пока fDone = FALSE
    {
        ::WaitForSingleObject(g_hMutex, INFINITE); /*g_hMutex,  ID объекта 
            INFINITE время ожидания в миллисекундах
            WaitForSingleObject ждём появление потока, потом Mutex  блокирует доступ другим потокам*/
        if (g_nIndex >= MAX_TIMES) //если g_nIndex больше (1000)
            fDone = TRUE; //выходим из цикла
        else //или
        {
    
            g_dwTimes[g_nIndex++] = a++; //заполняется массив временем с начала работы системы
            //std::cout << "FourThread " << g_dwTimes[g_nIndex - 1] << std::endl; // Вывожу текущее значение для четвёртого потока 
            Que.push ("FourThread: " + Convert_Int_toString(g_dwTimes[g_nIndex - 1]));
            
        }
        ::ReleaseMutex(g_hMutex); //Освобождаю Mutex
    }
    return 0; //выход из функции FourThread
}
 
static DWORD WINAPI FiveThread(void* pv) //Функция FiveThread для работы с потоком (static - сохраняет значение во время работы программы)
{
    BOOL fDone = FALSE; //переменная, работает с циклом, когда FALSE
    while (!fDone) //запуск цикла, работает пока fDone = FALSE
    {
        ::WaitForSingleObject(g_hMutex, INFINITE); /*g_hMutex,  ID объекта 
            INFINITE время ожидания в миллисекундах
            WaitForSingleObject ждём появление потока, потом Mutex  блокирует доступ другим потокам*/
        if (g_nIndex >= MAX_TIMES) //если g_nIndex больше (1000)
            fDone = TRUE; //выходим из цикла
        else //или
        {
            
            g_dwTimes[g_nIndex++] = a++; //заполняется массив временем с начала работы системы
            //std::cout << "FiveThread " << g_dwTimes[g_nIndex - 1] << std::endl; // Вывожу текущее значение для пятого потока
            Que.push ("FiveThread: " + Convert_Int_toString(g_dwTimes[g_nIndex - 1]));
            
        }
        ::ReleaseMutex(g_hMutex); //Освобождаю Mutex
    }
    return 0; //выход из функции FiveThread
}
 
int main(void) //главная функция для работы с потоком
{
    srand(time(NULL));
    HANDLE hThreads[5]; //создание массива типа HANDLE (любой тип данных)
    DWORD dwThreadID; // ID потока
    hThreads[0] = ::CreateThread(NULL, 0, FirstThread, NULL,
        CREATE_SUSPENDED, &dwThreadID);/*создание первого потока (дескриптор безопасности (по умолчанию - NULL), 
                                      размер стека в байтах (по умолчанию - 0), 
                                      указатель на процедуру (с которого начинается выполнение потока), 
                                      аргумент с предыдущего потока, 
                                     CREATE_SUSPENDED позволяет создаёт поток в спящем режиме, и он
                                    не запускается до тех пор пока не будет вызвана функция ResumeThread, 
                                    записать dwThreadID созданного потока*/
    hThreads[1] = ::CreateThread(NULL, 0, SecondThread, NULL,
        CREATE_SUSPENDED, &dwThreadID); /*создание второго потока (дескриптор безопасности (по умолчанию - NULL), 
                                      размер стека в байтах (по умолчанию - 0), 
                                      указатель на процедуру (с которого начинается выполнение потока), 
                                      аргумент с предыдущего потока, 
                                     CREATE_SUSPENDED позволяет создаёт поток в спящем режиме, и он
                                    не запускается до тех пор пока не будет вызвана функция ResumeThread, 
                                    записать dwThreadID созданного потока*/
    hThreads[2] = ::CreateThread(NULL, 0, ThirdThread, NULL,
        CREATE_SUSPENDED, &dwThreadID); /*создание третьего потока (дескриптор безопасности (по умолчанию - NULL), 
                                      размер стека в байтах (по умолчанию - 0), 
                                      указатель на процедуру (с которого начинается выполнение потока), 
                                      аргумент с предыдущего потока, 
                                     CREATE_SUSPENDED позволяет создаёт поток в спящем режиме, и он
                                    не запускается до тех пор пока не будет вызвана функция ResumeThread, 
                                    записать dwThreadID созданного потока*/
    hThreads[3] = ::CreateThread(NULL, 0, FourThread, NULL,
        CREATE_SUSPENDED, &dwThreadID); /*создание четвёртого потока (дескриптор безопасности (по умолчанию - NULL),
                                      размер стека в байтах (по умолчанию - 0), 
                                      указатель на процедуру (с которого начинается выполнение потока), 
                                      аргумент с предыдущего потока
                                    записать dwThreadID созданного потока*/
    g_hMutex = ::CreateMutex(NULL, FALSE, NULL);//создаем мьютекс после 3 потока
    hThreads[4] = ::CreateThread(NULL, 0, FiveThread, NULL,
        0, &dwThreadID); /*создание пятого потока (дескриптор безопасности (по умолчанию - NULL), 
                                      размер стека в байтах (по умолчанию - 0), 
                                      указатель на процедуру (с которого начинается выполнение потока), 
                                      аргумент с предыдущего потока
                                    записать dwThreadID созданного потока*/
    ::ResumeThread(hThreads[0]);//запускаем наши  потоки
    ::ResumeThread(hThreads[1]);
    ::ResumeThread(hThreads[2]);
    ::ResumeThread(hThreads[3]);
    ::WaitForMultipleObjects(5, hThreads, TRUE, INFINITE);
    ::CloseHandle(hThreads[0]);
    ::CloseHandle(hThreads[1]);
    ::CloseHandle(hThreads[2]);
    ::CloseHandle(hThreads[3]);
    ::CloseHandle(hThreads[4]);
    ::CloseHandle(g_hMutex);
    
        while (!Que.empty()) {
            
            SetConsoleTextAttribute (GetStdHandle (STD_OUTPUT_HANDLE), (WORD) ((0 << 4) | RandNumColor()));
                
            int min = 1;
            int max = 1024;
                
                for (int i = 0; i < (min + rand () % (max - min + 1)); i++)
                    cout << " ";
            
            cout << Que.front () << "\n";
            Que.pop ();
            
        } // отображаем очередь из сообщений с рандомизацией цвета для каждого
        
    SetConsoleTextAttribute (GetStdHandle (STD_OUTPUT_HANDLE), (WORD) ((0 << 4) | 7));
 
    return 0;
}
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
18.11.2020, 20:57
Помогаю со студенческими работами здесь

Проверка на ввод
Знаю, что есть проверка, которая попросту блокирует нажатия букв. Как такую сделать?

Проверка на число
Здравствуйте! У меня такой вопрос: я считываю 2 аргумента функцией scanf() и хочу проверить, являются ли они оба числами/целыми числами....

Проверка программы
#include &lt;stdio.h&gt; #include &lt;stdlib.h&gt; int main() {int a; do { printf(&quot;Wybierz opcje:\n&quot;); printf(&quot;1.Opcja 1\n&quot;); ...

проверка на полидром
требуется ввод строки с клавиатуры а проверка ее на полидром. вроде все правильно написал ,но все равно работает не правильно ...

Посимвольная проверка
Программа должна проверять, есть ли среди введенных символов числа отличительные от единицы, и если нет, то выводить t, а если есть, то f....


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

Или воспользуйтесь поиском по форуму:
6
Ответ Создать тему
Новые блоги и статьи
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост.
Programma_Boinc 28.12.2025
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост. Налог на собак: https:/ / **********/ gallery/ V06K53e Финансовый отчет в Excel: https:/ / **********/ gallery/ bKBkQFf Пост отсюда. . .
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США.
Programma_Boinc 26.12.2025
Нашел на реддите интересную статью под названием Anyone know where to get a free Desktop or Laptop? Ниже её машинный перевод. После долгих разбирательств я наконец-то вернула себе. . .
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Рецензия / Мнение/ Перевод Нашел на реддите интересную статью под названием The Thinkpad X220 Tablet is the best budget school laptop period . Ниже её машинный перевод. Thinkpad X220 Tablet —. . .
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru