В файлике у меня в столбик перечислены цифры от 1 до 10.Мне нужно, чтобы сначала родительский поток выводил сначала 2 строки, затем дочерний три строки, далее опять родительский 2 строки, а дочерний три
Как исправить код или адаптировать с использованием флага, я сделал наброски, но это какая-то ерунда
Само задание звучит так: Напишите программу, которая создает поток. Используйте атрибуты по умолчанию. Родительский и вновь созданный поток должны распечатать десять строчек текста так, чтобы вывод родительского и дочернего потока был синхронизован: сначала родительский поток выводил бы две строки, затем дочерний три строки текста, затем родительский две строки и т.д. Используйте мьютексы.
То есть по сути флаги нужды, чтобы избеждать гонки между потоками, как это реализовать в коде, используя сами флаги?
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
| #include <iostream>
#include <fstream>
#include <string>
#include <windows.h>
#include "function.h"
using namespace std;
int flag;
bool func;
Mutex mutexOne, mutexTwo; //объявление мьютексов
HANDLE console = GetStdHandle(STD_OUTPUT_HANDLE); //объявление консоли
//Функция вывода строчек и окрашивание их
//Принимает: true/false для цвета и файл потока
//Возвращает: строки из файла или false, если открыть не удалось
bool line(bool iscolor, ifstream &file)
{
string line;
if (!getline(file, line))
return false;
if (iscolor)
{
SetConsoleTextAttribute(console, (WORD)(1)); cout <<"Родительский поток: " << line << endl;
}
else
{
SetConsoleTextAttribute(console, (WORD)(3)); cout << "\t\tДочерний поток: " << line << endl;
}
return true;
}
bool empty(ifstream& file) {
return file.peek() == EOF;
}
DWORD WINAPI process(LPVOID) {
ifstream file("1.txt");
do {
if (flag)
{
lock(mutexOne);
for (int i = 0; i < 3; i++)
func = line(false, file); //Вызов функции
flag = true;
unlock(mutexTwo);
}
} while (func);
return 0;
}
int main()
{
flag = false;
setlocale(LC_ALL,"Russian");
ifstream file("11.txt");
if (!file.is_open())
{
SetConsoleTextAttribute(console, (WORD)(4)); cout << "Файл не найден!" << endl;
SetConsoleTextAttribute(console, (WORD)(7)); system("pause");
return -1;
}
if (empty(file))
{
SetConsoleTextAttribute(console, (WORD)(4)); cout << "Файл пуст" << endl;
SetConsoleTextAttribute(console, (WORD)(7)); system("pause");
return -1;
}
DWORD dwThreadId;// идентификатор потока
mutexOne = mutex(FALSE);
mutexTwo = mutex(TRUE);
HANDLE pThreadHandle = CreateThread(NULL, 0, process, NULL, 0, &dwThreadId); //Объявление процесса
do //Дочерний процесс
{
if (!flag)
{
lock(mutexTwo);
for (int i = 0; i < 2; i++)
func = line(true, file);
flag = true;
unlock(mutexOne);
}
} while (func);
join(pThreadHandle);
CloseHandle(mutexOne);
CloseHandle(mutexTwo);
cout << endl;
SetConsoleTextAttribute(console, (WORD)(7)); system("pause");
return 0;
} |
|
function.h
C++ |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| #include <windows.h>
typedef HANDLE Mutex;
DWORD WINAPI lock(Mutex mtx) {
return WaitForSingleObject(mtx, INFINITE); //Идентификатор объекта, время задержки
}
DWORD WINAPI unlock(Mutex mtx) {
return ReleaseMutex(mtx); //После завершения работы с ресурсом поток увеличивает значение счетчика
}
BOOL WINAPI join(HANDLE pThreadHandle) { //Завершение процесса
WaitForSingleObject(pThreadHandle, INFINITE);
return CloseHandle(pThreadHandle);
}
Mutex mutex(int c) {
return CreateMutex(NULL, c, (LPCWSTR)"Mutex");
} |
|