Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Лабы, Разумовский / 4_laba / ООПЛинукс_4л

.docx
Скачиваний:
0
Добавлен:
30.09.2026
Размер:
24 Кб
Скачать
☆

МИНОБРНАУКИ РОССИИ

Санкт-Петербургский государственный

электротехнический университет

«ЛЭТИ» им. В.И. Ульянова (Ленина)

Кафедра ВТ

отчет

по лабораторной работе №4

по дисциплине «Организация процессов и программирование в среде Linux»

Тема: Управление потоками

Студент гр.

Преподаватель

Разумовский Г.В.

Санкт-Петербург

2026

Цель работы

Знакомство с организацией потоков и способами синхронизации предков и потомков.

Задание

Написать программу, которая открывает входной файл и 2 выходных файла. Затем она должна в цикле построчно читать входной файл и порождать 2 потока. Одному потоку предавать нечетную строку, а другому - четную. Оба потока должны работать параллельно. Каждый поток записывает в свой выходной файл полученную строку и завершает работу. Программа должна ожидать завершения работы каждого повторять цикл порождения потоков и чтения строк входного файла, пока не прочтет последнюю строку, после чего закрыть все файлы.

Распечатка тестовой программы

own_prog.cpp

#include <iostream>

#include <fstream>

#include <pthread.h>

#include <string>

#include <unistd.h>

using namespace std;

// Структура для передачи данных потоку

struct ThreadData {

    string line;  

    ofstream* outFile;  

    int threadNum;

};

// Функция потока

void* threadFunction(void* arg) {

    ThreadData* data = (ThreadData*)arg;

   

    // Записываем строку в файл

    if (data->outFile->is_open()) {

        *data->outFile << data->line << endl;

        cout << "Поток " << data->threadNum

             << " записал строку: " << data->line << endl;

    }

   

    delete data;

   

    return NULL;

}

int main(int argc, char* argv[]) {

    if (argc != 4) {

        cerr << "Использование: " << argv[0]

             << " <входной_файл> <выходной_файл_1> <выходной_файл_2>" << endl;

        return 1;

    }

   

    string inputFile = argv[1];

    string outputFile1 = argv[2];

    string outputFile2 = argv[3];

   

    ifstream inFile(inputFile);

    if (!inFile.is_open()) {

        cerr << "Ошибка открытия входного файла: " << inputFile << endl;

        return 1;

    }

   

    ofstream out1(outputFile1);

    ofstream out2(outputFile2);

   

    if (!out1.is_open()) {

        cerr << "Ошибка открытия файла: " << outputFile1 << endl;

        inFile.close();

        return 1;

    }

   

    if (!out2.is_open()) {

        cerr << "Ошибка открытия файла: " << outputFile2 << endl;

        inFile.close();

        out1.close();

        return 1;

    }

   

    cout << "Файлы открыты. Начинаем обработку..." << endl;

   

    string line1, line2;

    int lineNumber = 0;

   

    // Читаем файл попарно (нечетная + четная строки)

    while (true) {

        // Читаем нечетную строку

        if (getline(inFile, line1)) {

            lineNumber++;

            cout << "\n--- Обработка пары строк ---" << endl;

            cout << "Нечетная строка (" << lineNumber << "): " << line1 << endl;

           

            // Создаем данные для первого потока

            ThreadData* data1 = new ThreadData;

            data1->line = line1;

            data1->outFile = &out1;

            data1->threadNum = 1;

           

            pthread_t thread1;

            pthread_create(&thread1, NULL, threadFunction, data1);

           

            // Читаем четную строку (если есть)

            if (getline(inFile, line2)) {

                lineNumber++;

                cout << "Четная строка (" << lineNumber << "): " << line2 << endl;

               

                // Создаем данные для второго потока

                ThreadData* data2 = new ThreadData;

                data2->line = line2;

                data2->outFile = &out2;

                data2->threadNum = 2;

               

                pthread_t thread2;

                pthread_create(&thread2, NULL, threadFunction, data2);

               

                // Ждем завершения обоих потоков

                pthread_join(thread1, NULL);

                pthread_join(thread2, NULL);

               

            } else {

                // Если нечетная строка была последней

                pthread_join(thread1, NULL);

                break;

            }

           

        } else {

            // Файл закончился

            break;

        }

    }

   

    inFile.close();

    out1.close();

    out2.close();

   

    cout << "\n=== Обработка завершена ===" << endl;

    cout << "Всего обработано строк: " << lineNumber << endl;

    cout << "Результаты записаны в файлы:" << endl;

    cout << "  - Нечетные строки: " << outputFile1 << endl;

    cout << "  - Четные строки: " << outputFile2 << endl;

   

    return 0;

}

Вывод

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

В работе были использованы функции pthread_create для срздания новых потоков выполнения, pthread_join для синхронизации и ожидания завершения потоков, pthread_exit для корректного завершения потока.Функция потока имеет фиксированный прототип, принимающий только один параметр типа void*. Для передачи нескольких значений в поток данные упаковываются в структуру, которая передаётся через указатель, а память для структуры должна выделяться в куче, чтобы данные оставались доступными после создания потока.

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

Синхронизация осуществляется с помощью функции pthread_join, которая блокирует родительский процесс до завершения указанного потока. Это гарантирует, что все потоки завершат работу до перехода к следующей итерации цикла.

В результате выполнения заданий были разработаны и отлажены программы, которые открывают входной файл и два выходных файла, в цикле построчно читают входной файл, порождаются два потока, которым передают нечетную и четную строки соответственно. Оба потока работают параллельно и записывают данные в свои файлы, родительский процесс ожидает завершения потоков через pthread_join, а после обработки всех строк закрывает все файлы.

10

Соседние файлы в папке 4_laba