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

Работа с потоками для 2 файлов

05.06.2018, 22:19. Показов 1629. Ответов 5
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Всем привет.
Мог бы кто то обьяснить хотябы на простом примере.
Есть 2 файла, один открываем и читаем по блокам заданного размера, само собою юзаем поток.
Читаем до конца файла.
Второй поток пишет эту куски в другой файл.
Получается если дошли до конца файла то наверное сообщили потоку что дальше пусто и закрываем поток.

Пишу под линукс, можно юзать 14 стандарт.
Как понимаю там нужны mutex и condition_values но с этим я на вы(

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
    std::ifstream iFile(pathToFileRead_.c_str(), std::ios::binary);
    if (!iFile)
    {
        throw std::runtime_error("Can not open file \"" + getPathToFileToRead() + "\" !");
    }
 
    std::ofstream oFile(pathToFileWrite_.c_str());
    if (!oFile)
    {
        throw std::runtime_error("Can not open file \"" + getPathToFileToWrite() + "\" !");
    }
 
 
    if (iFile.eof())
    {
//      iFile.read(ddd, threadCount * getSize());  // threadCount - 2 потока, getSize - возвращает размер блока по сколко надо читать
    }
Подскажите пожалуйста как к этому правильно подойти для реализации?
Спасибо большое.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
05.06.2018, 22:19
Ответы с готовыми решениями:

Обработка файлов потоками
Здравствуйте, столкнулась вот с какой проблемой. Пользователь с клавиатуры вводит количество...

Работа с потоками
Здравствуйте. Имеется такое задание: Лаунчер написал такой: // Launcher.cpp: определяет точку...

Работа с потоками...
Понимаю, что тема проезжена и не раз, однако спрошу:-[: Есть консольное приложение, оно занимается...

Работа с потоками
В общем, сделал рекурсивное удаление файлов и папок в несколько потоков, но вылетают эксепшены что...

5
474 / 426 / 290
Регистрация: 10.03.2015
Сообщений: 1,782
05.06.2018, 22:30 2
Цитата Сообщение от BlinCT Посмотреть сообщение
Есть 2 файла, один открываем и читаем по блокам заданного размера, само собою юзаем поток
Зачем поток, если fstream - сам файловый поток ввода/вывода.
Открываешь 1 файл для чтения ifstream fin("file1", ios::binary);
Открываешь 2 файл для записи ofstream fout("file1", ios::binary);
В 1 читаешь сколько надо блоков определенного размера
Во 2 записываешь эти блоки или измененные.
0
1 / 1 / 0
Регистрация: 01.11.2010
Сообщений: 216
05.06.2018, 23:17  [ТС] 3
Потому что именно надо заюзать 2 потока для чтения с файла и для записи в другой.
Просто дальше будет это разрастаться и будет дальше идти работа с потоками.
Иначе я бы так давно сделал а не сидел и не ломал голову над этим))
0
474 / 426 / 290
Регистрация: 10.03.2015
Сообщений: 1,782
06.06.2018, 15:12 4
BlinCT, Хорошо, как происходит обмен информацией между потоками? Как поток 1 проверяет, что поток 2 считал и блок можно обрабатывать? Как синхронизируются работы потоков? Как отслеживается, что поток 1 выполнил задачу раньше потока 2?
0
2848 / 1997 / 986
Регистрация: 21.12.2010
Сообщений: 3,705
Записей в блоге: 10
07.06.2018, 04:31 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
#include <iostream>
#include <string>
#include <fstream>
#include <exception>
#include <thread>
#include <queue>
#include <memory>
#include <utility>
#include <mutex>
#include <atomic>
 
std::atomic<bool> readComplete { false };
int const blockSize { 3 };
std::queue<std::pair<std::streamsize, std::shared_ptr<char[]>>> que;
std::mutex mque, mcout;
 
// чтение из входного файла блоками в очередь
void readFile(std::string const& sifs)
{
    try
    {
        std::ifstream ifs{ sifs, std::ios::binary };
        if (!ifs.is_open())
        {
            throw std::runtime_error("Unable to open file\n");
        }
        do
        {
            std::shared_ptr<char[]> sp{ new char[blockSize] };
            ifs.read(sp.get(), blockSize);
            mque.lock();
            que.push(std::make_pair(ifs.gcount(), sp));
            mque.unlock();
        } while (ifs);
 
        
        ifs.close();
    }
    catch (std::exception const& exc)
    {
        mcout.lock();
        std::cerr << exc.what() << std::endl;
        mcout.unlock();
    }
 
    readComplete = true;
}
 
// запись блоков из очереди в выходной файл
void writeFile(std::string const& sofs)
{
    std::ofstream ofs{ sofs, std::ios::binary };
    while (!que.empty() || !readComplete)
    {
        if (!que.empty())
        {
            mque.lock();
            ofs.write(que.front().second.get(), que.front().first);
            que.pop();
            mque.unlock();
        }
    }
    ofs.close();
}
 
 
int main()
{
    std::string sifs{ "in.jpg" }, sofs{ "out.jpg" };
    std::thread tw{ writeFile, std::cref(sofs) };
    std::thread tr{ readFile, std::cref(sifs) };
    tr.join();
    tw.join();
}
1
1 / 1 / 0
Регистрация: 01.11.2010
Сообщений: 216
13.06.2018, 16:32  [ТС] 6
В принципе сейчас в таком виде обе функции для каждого из потоков, чтение и запись
C++ (Qt)
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
void Menu::readFile(string file)
{
    std::ifstream iFile{ pathToFileRead_, std::ios::binary };
    if (!iFile.is_open())
    {
        throw std::runtime_error("Unable to open file\n");
    }
 
    while (iFile)
    {
        std::shared_ptr<char> sp(new char[getSize()]);
        iFile.read(sp.get(), getSize());
        auto tmp = iFile.gcount();
 
        if (tmp > 0)
        {
            std::unique_lock<std::mutex> ulm(mutex_que);
            que.push(std::make_pair(tmp, sp));
            cv.notify_one();
        }
    }
    
    {
        std::unique_lock<std::mutex> ulm(mutex_que);
        var_ = true;
        cv.notify_one();
    }
    iFile.close();
}
 
 
void Menu::writeFile(string file)
{
    std::unique_lock<std::mutex> ulm(mutex_que);
 
    while (!var_ && que.empty())
    {
        cv.wait(ulm);
    }
 
    if (var_)
        return;
 
    std::ofstream oFile{ file, std::ios::binary };
    if (!que.empty())
    {
        std::pair<std::streamsize, std::shared_ptr<char>> pr;
                ////
        pr.second.swap(que.front().second);
        pr.first = que.front().first;
        que.pop();
        mutex_que.unlock();
                ////
        oFile.write(pr.second.get(), pr.first);
    }
 
    oFile.close();
}
У меня осталось не решеной одна проблема, если вы возьмете этот код и затестите например на файле фотографии, то получите что записывается в файл только один блок. И все. И почему то еще и при дебаге вылетает ошибка на мютекс который надо разлочить. Я пробую читать блоками по 1 метру или половине.
По логике цикл который надо как бы вставить это если переменная var_ или пустая или нет очередь.
Но не могу понять как правильно.

Добавлено через 10 минут
Такая ошибка unlock of unowned mutex
Но про какой мютекс идет речь я понять не смог.
0
13.06.2018, 16:32
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
13.06.2018, 16:32
Помогаю со студенческими работами здесь

работа с потоками
Возможно ли приостановить все потоки на заданное время из процедуры не из которых они были созданы...

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

Работа с потоками
Добрый вечер, форумчане. Пишу программу-бота и столкнулся с проблемой: После запуска программы...

Работа с потоками
Задание Разработать программу, реализующую многопочность средствами среды Win32. Программа должна...


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

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