0 / 0 / 0
Регистрация: 27.10.2018
Сообщений: 27
1

Как синхронизировать потоки, чтобы сначала один поток, затем первый завершался и начинался второй

27.10.2018, 00:17. Показов 1051. Ответов 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
#include"stdafx.h"
#include<iostream>
#include<windows.h>
#include<string>
#include<io.h>
#include<thread>
#include<mutex>
#include<fstream>
using namespace std;
 
int _nextOrder = 0;
mutex _m;
 
bool lock(int currentOrder)
{
    for (;;)
    {
        _m.lock();
 
        if (_nextOrder == currentOrder)
            break;
 
        _m.unlock();
    }
 
    return false;
}
 
void unlock(int nextOrder)
{
    _nextOrder = nextOrder;
    _m.unlock();
}
 
void func(ifstream &file, mutex &mtx, int len, const  string & name)
{
    string str;//строковая переменная
    while (!file.eof())//проверочка на наличие строк 
    {
        mtx.lock(); //Блокирует мьютекс
        for (int i = 0; i < len; i++) // len - сколько строк должно быть выведено
        {
            if (!getline(file, str))  //Получение строки из файла
                break;
 
            cout << name << str << endl;//Вывод
        }
        mtx.unlock(); //Разблокирует мьютекс
        Sleep(1000);//приостановка программы
    }
}
 
 
int main()
{
    setlocale(LC_ALL, "rus");//Подключение русского языка
    mutex mtx; //Переменная типа мьютекс
    ifstream file("1.txt"); //Открытие файла для чтения строк
    
    if (!file.is_open())//проверка наличия файла
 
        cout << "Файл не существует!";
    else if (file.peek() == EOF)//проверка на наличие строк
        cout << "Файл пуст!";
    else
    {
        
        thread t(func, ref(file), ref(mtx), 3, "\tДочерний поток: ");
        
        func(file, mtx, 2, "Родительский поток: ");
        t.join();
    }
    file.close();//закрытие файла
    cout << endl;
 
    system("pause");
}
__________________
Помощь в написании контрольных, курсовых и дипломных работ, диссертаций здесь
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
27.10.2018, 00:17
Ответы с готовыми решениями:

Как сделать так что бы выводился сначала один cout а затем второй а не вместе?
cout &lt;&lt; &quot;Введите 1: &quot;; cout &lt;&lt; &quot;Введите 2: &quot;; как сделать так что бы они выводились поочерёдно?

Объединить массивы: разместить в новый массив сначала первый по убыванию, затем второй по возрастанию
Прошу расписать задачу полностью (от вара до энда) в рамках 7-ого класса. Спасибо! 1) Объединить ...

Как сделать, чтобы один поток не закончил работу, пока второй работает?
Подскажите, есть например 2 потока, которые ну например отсчитывают в цикле до 100. Как сделать...

Как сделать так, чтобы при добавлении класса active к последнему элементу в наборе, отсчет начинался сначала?
как можно при кликке начать отсчет сначала набора, когда доходит до последнего элемента, помогите...

8
1378 / 405 / 144
Регистрация: 22.10.2014
Сообщений: 872
27.10.2018, 00:36 2
Jonior, В идеале тут одним мьютексом не обойтись, ибо у нас есть не просто синхронизация на доступ, но и очерёдность, т.е. присутствует событие, то Вам нужен ещё и std::condition_variable или костыль в виде while(isAnotherThreadCompleted) иначе вы не можете дать гарантии очерёдности вывода.
Посмотрите пример в приведённой ссылке. По нему сделайте две функции для обоих потоков с двумя condition_variable на один мютекс. (с одним condition_variable опять же нет гарантии соблюдения очереди).
0
1386 / 1016 / 323
Регистрация: 28.07.2012
Сообщений: 2,804
27.10.2018, 01:19 3
Цитата Сообщение от Nosey Посмотреть сообщение
с одним condition_variable опять же нет гарантии соблюдения очереди
Задача вполне решается одним cv, но с ожиданием по разным условиям.
1
1378 / 405 / 144
Регистрация: 22.10.2014
Сообщений: 872
27.10.2018, 01:39 4
Цитата Сообщение от nonedark2008 Посмотреть сообщение
но с ожиданием по разным условиям.
И с красивой лапшой на повторное пробуждение, против академических двух cv. . Но да, это возможно, я вверху наврал немного.
0
2282 / 780 / 299
Регистрация: 10.02.2018
Сообщений: 1,829
27.10.2018, 02:37 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
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
#include <mutex>
#include <thread>
#include <chrono>
#include <string>
#include <iostream>
#include <sstream>
#include <vector>
using namespace std;
 
struct Buff
{
    vector<string> list;
    mutex mtx;
    int next;
    int cnt;
 
    Buff()
    {
        next = cnt = 0;
    }
 
    void add(string str)
    {
        list.push_back(str);
    }
 
    string lock(int order)
    {
        for (;;)
        {
            mtx.lock();
 
            if (list.size() == 0)
            {
                mtx.unlock();
                return string();
            }
 
            if (order == next)
                break;
 
            mtx.unlock();
 
            this_thread::sleep_for(chrono::milliseconds(1));
        }
 
        string str = list.front();
        list.erase(list.begin());
        return str;
    }
 
    void unlock()
    {
        cnt++;
        if (((next == 0) && (cnt == 3)) || ((next == 1) && (cnt == 2)))
        {
            cnt = 0;
            next = next ^ 1;
        }
 
        mtx.unlock();
    }
};
 
void OrderPrint(Buff *buf, int order)
{
    for (;;)
    {
        string str = buf->lock(order);
 
        if (str.empty())
            break;
 
        cout << this_thread::get_id() << ") " << str << endl;
 
        buf->unlock();
    }
}
 
int main()
{
    Buff buf;
 
    for (int i=0; i<10; i++)
    {
        stringstream ss;
        ss << "line" << (i+1);
        buf.add(ss.str());
    }
 
    thread t(OrderPrint, &buf, 1);
 
    OrderPrint(&buf, 0);
 
    t.join();
 
    return 0;
}
0
1386 / 1016 / 323
Регистрация: 28.07.2012
Сообщений: 2,804
27.10.2018, 03:16 6
Цитата Сообщение от Ygg Посмотреть сообщение
Извращение на одном мьютексе
Ну, второй мьютекс просто заменился на спинлок...
0
1378 / 405 / 144
Регистрация: 22.10.2014
Сообщений: 872
27.10.2018, 10:52 7
del
0
0 / 0 / 0
Регистрация: 27.10.2018
Сообщений: 27
28.10.2018, 01:13  [ТС] 8
Добавлено через 1 минуту
Nosey, А подскажите, пожалуйста, как все это реализовать в коде, просто хотелось бы понять, как это все делается, в этом не очень силен и на словах пока сложновато
0
1378 / 405 / 144
Регистрация: 22.10.2014
Сообщений: 872
28.10.2018, 12:37 9
Цитата Сообщение от Jonior Посмотреть сообщение
А подскажите, пожалуйста, как все это реализовать в коде
Неа
Если вы сами написали то, что написано в первом посте, то после изучения примера приведённого по ссылке вам не составит труда всё это сделать самому и порадоваться достижению (пс. там есть русская версия, переключите внизу на неё, но в русской приведённый пример для вас возможно будет сложнее, т.е. лучше используйте пример из английской версии).
Ну а если не сами сделали, то отнесите пиво и пиццу тому кто это делал, как это делал я в свои весёлые годы
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
28.10.2018, 12:37
Помогаю со студенческими работами здесь

Заполнить Y таким образом, чтобы в его начале оказался первый элемент X, затем в его конце – второй, затем в начале – 3
Привет, помогите, пожалуйста. Выполнить действия над одномерными массивами. Заполнить массив Y...

Из массива переписать числа во второй массив так, чтобы сначала шли четные элементы, затем нули, потом нечетные элементы
Доброго времени суток! Помогите решить задание на с#: Из одномерного целочисленного массива...

Переписать все числа во второй массив так, чтобы сначала шли четные элементы, затем нули, потом нечетные элементы
Парни, нуждаюсь в ваших советах. Из одномерного целочисленного массива переписать все числа во...

Переставить элементы массива так, чтобы сначала располагались все 0, затем 1, затем 2
Общие указания при составлении программ к данной теме: 1. Размер массива задать константой в блоке...


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

Или воспользуйтесь поиском по форуму:
9
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2022, CyberForum.ru