Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Операционные системы > Linux (Ubuntu, Debian, Red Hat, CentOS, Mint)
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 18.05.2018, 01:08   #1
Alexis_777
Пользователь
 
Регистрация: 08.11.2017
Сообщений: 48
Лампочка Процессы в Linux не могу понять

Не могу никак распараллелить процессы. Дочерний и родительский.
Если в дочернем процессе - реверс файла, если нет, то поиск следующего файла для реверса. Помогите как это можно сделать. Не могу понять, т.к. у меня один цикл, а как это разграничить(
Код:
#include <unistd.h>
#include <iostream>
#include <fstream>
#include <algorithm>
#include <iterator>
#include <experimental/filesystem>
#include <sys/time.h>
#include <sys/types.h>

namespace fs = std::experimental::filesystem;

void reverseFile(fs::path pfile, fs::path const& pdir)
{
	std::fstream ifs(pfile, std::ios::in | std::ios::binary), ofs(pdir / pfile.filename(), std::ios::out | std::ios::binary);
	if (ifs.is_open() && ofs.is_open())
	{
		ifs.seekg(0, ifs.end);
		if (ifs.tellg() >= std::streampos(1))
		{
			for (ifs.seekg(-1, ifs.cur); ; ifs.seekg(-2, ifs.cur))
			{
				ofs.put(ifs.get());
				if (ifs.tellg() == std::streampos(1))
				{
					break;
				}
			}
		}
	}
	else
	{
		std::cerr << "Unable to open file(s): " << pfile << "  " << pdir / pfile.filename() << "\n\n";
	}
	ifs.close();
	ofs.close();
}

int main()
{
	try
	{
		fs::path pd1("/home/student/dir1"); // каталог с исходными файлами
		fs::path pd2("/home/student/dir5"); // каталог с инвертированными файлами

		struct timeval ts; gettimeofday(&ts, NULL);

		pid_t pid;

		pid = fork();       // процесс разветвился

		if (!fs::exists(pd2))
		{
			fs::create_directory(pd2); // может кинуть исключение
		}
		for (fs::recursive_directory_iterator ib(pd1), ie; ib != ie; ++ib) // перебираем все файлы в dir 1
		{
			if (fs::is_regular_file(ib->path())) // инвертируем каждый файл 
			{
				reverseFile(ib->path(), pd2);
			}
		}

		struct timeval te; gettimeofday(&te, NULL);

		printf("Total time: %f sec\n", (double)(te.tv_usec - ts.tv_usec) / 1000000 + (double)(te.tv_sec - ts.tv_sec));

	}
	catch (std::exception const& exc)
	{
		std::cerr << "Exception: " << exc.what() << std::endl;
	}
}
Alexis_777 вне форума Ответить с цитированием
Старый 18.05.2018, 07:55   #2
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,493
По умолчанию

Проверяйте значение pid, которое вернул fork()
waleri вне форума Ответить с цитированием
Старый 18.05.2018, 07:58   #3
p51x
Старожил
 
Регистрация: 15.02.2010
Сообщений: 15,695
По умолчанию

Очередная тема без попыток разобраться...

Цитата:
Return Value
On success, the PID of the child process is returned in the parent, and 0 is returned in the child. On failure, -1 is returned in the parent, no child process is created, and errno is set appropriately.
Так где вы используете потоки?
p51x вне форума Ответить с цитированием
Старый 18.05.2018, 09:27   #4
Alexis_777
Пользователь
 
Регистрация: 08.11.2017
Сообщений: 48
По умолчанию

Цитата:
Сообщение от waleri Посмотреть сообщение
Проверяйте значение pid, которое вернул fork()
Код:
void reverseFile(fs::path pfile, fs::path const& pdir)
{
	pid_t pid;
	pid = fork();
	if (pid == -1) perror("fork"), exit(EXIT_FAILURE);
	if (pid == 0) {
		std::fstream ifs(pfile, std::ios::in | std::ios::binary), ofs(pdir / pfile.filename(), std::ios::out | std::ios::binary);
		if (ifs.is_open() && ofs.is_open())
		{
			if (pid > 0)
			{
				ifs.seekg(0, ifs.end);
				if (ifs.tellg() >= std::streampos(1))
				{
					for (ifs.seekg(-1, ifs.cur); ; ifs.seekg(-2, ifs.cur))
					{
						ofs.put(ifs.get());
						if (ifs.tellg() == std::streampos(1))
						{
							break;
						}
					}
				}
			}
		}
		else
		{
			std::cerr << "Unable to open file(s): " << pfile << "  " << pdir / pfile.filename() << "\n\n";
		}
		ifs.close();
		ofs.close();
	}
}
Так должно быть?
Alexis_777 вне форума Ответить с цитированием
Старый 18.05.2018, 09:35   #5
p51x
Старожил
 
Регистрация: 15.02.2010
Сообщений: 15,695
По умолчанию

Почти, только:
1. У вас есть две задачи - для главного потока и второго. Какая логика вас заставила создавать новый поток, проверять ошибки создания и т.д. в функции для выполнения второй задачи? Разве это не работа главного потока?
2. Главный поток то, что делает в это время? Завершается?
p51x вне форума Ответить с цитированием
Старый 18.05.2018, 10:18   #6
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,493
По умолчанию

Цитата:
Сообщение от Alexis_777 Посмотреть сообщение
Так должно быть?
Откуда я знаю - запустите да проверьте...
waleri вне форума Ответить с цитированием
Старый 18.05.2018, 11:22   #7
Alexis_777
Пользователь
 
Регистрация: 08.11.2017
Сообщений: 48
По умолчанию

Цитата:
Сообщение от p51x Посмотреть сообщение
Почти, только:
1. У вас есть две задачи - для главного потока и второго. Какая логика вас заставила создавать новый поток, проверять ошибки создания и т.д. в функции для выполнения второй задачи? Разве это не работа главного потока?
2. Главный поток то, что делает в это время? Завершается?
Да, я также подумал когда это делал. Просто никак не могу нормально разграничить, т.к. у меня всё по сути должно в одном процессе работать. Как их разбить я не могу понять.
Alexis_777 вне форума Ответить с цитированием
Старый 18.05.2018, 11:34   #8
p51x
Старожил
 
Регистрация: 15.02.2010
Сообщений: 15,695
По умолчанию

Так у вас же уже разбито, только не там.
Код:
switch(pid = fork()){
  case -1:
   !!!ERROR

  case 0:
    reverseFile...
    exit(rv);

  default:
    searchNewFile...
    wait/waitpid
}
И не забывайте про wait/waitpid, а то наплодите зомби.
p51x вне форума Ответить с цитированием
Старый 18.05.2018, 11:42   #9
Alexis_777
Пользователь
 
Регистрация: 08.11.2017
Сообщений: 48
По умолчанию

Хорошо. Как быть с
Код:
default:
    searchNewFile...
    wait/waitpid
Поставить метку на цикл
Код:
 for (fs::recursive_directory_iterator ib(pd1), ie; ib != ie; ++ib) // перебираем все файлы в dir 1
чтобы туда перескакивало?
Alexis_777 вне форума Ответить с цитированием
Старый 18.05.2018, 11:43   #10
Alexis_777
Пользователь
 
Регистрация: 08.11.2017
Сообщений: 48
По умолчанию

Что-то такое делал, не знаю так или нет
Код:
void reverseFile(fs::path pfile, fs::path const& pdir)
{
	pid_t pid;
	pid = fork();
	if (pid < 0)
		printf("can't fork\n");
	exit(-1);;
	while ((pid = fork()) >= 0)
	{
		std::fstream ifs(pfile, std::ios::in | std::ios::binary), ofs(pdir / pfile.filename(), std::ios::out | std::ios::binary);
		if (ifs.is_open() && ofs.is_open())
		{
			if (pid > 0) {

				waitpid(pid, NULL, 0);
				ifs.seekg(0, ifs.end);
				if (ifs.tellg() >= std::streampos(1))
				{
					for (ifs.seekg(-1, ifs.cur); ; ifs.seekg(-2, ifs.cur))
					{
						ofs.put(ifs.get());
						if (ifs.tellg() == std::streampos(1))
						{
							break;
						}
					}
				}
				exit(EXIT_SUCCESS);
			}
		}
		else
		{
			std::cerr << "Unable to open file(s): " << pfile << "  " << pdir / pfile.filename() << "\n\n";
		}
		ifs.close();
		ofs.close();
	}
}
Ну тут вообще не работает процесс

Последний раз редактировалось Alexis_777; 18.05.2018 в 11:47.
Alexis_777 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Паскаль: Помогите понять основу для написания простейшей программы. Не могу понять суть. romanya Паскаль, Turbo Pascal, PascalABC.NET 2 18.03.2016 20:35
не могу понять Fantomka92 Общие вопросы C/C++ 4 27.11.2011 18:32
пайпы и процессы, Linux 5ive Общие вопросы C/C++ 2 27.08.2011 21:18
Не могу понять spaun88 Общие вопросы Delphi 0 15.04.2010 00:41
Не могу понять Superlotles Помощь студентам 8 31.08.2009 20:39