Форум программистов, компьютерный форум, киберфорум
Наши страницы
C# для начинающих
Войти
Регистрация
Восстановить пароль
 
 
Outwork
4 / 4 / 3
Регистрация: 05.08.2014
Сообщений: 54
#1

Прошу консультации экспертов (ООП, многопоточность) - C#/.NET 4.x

16.11.2016, 13:02. Просмотров 2465. Ответов 45

Здравствуйте уважаемые форумчане! Давеча пытался устроиться на работу и прислали мне тестовое задание, далее привожу его текст:
Требуется написать консольную программу на C# для генерации сигнатуры указанного файла. Сигнатура генерируется следующим образом: исходный файл делится на блоки заданной длины (кроме последнего блока), для каждого блока вычисляется значение hash-функции SHA256, и вместе с его номером выводится в консоль.
Программа должна уметь обрабатывать файлы, размер которых превышает объем оперативной памяти, и при этом максимально эффективно использовать вычислительные мощности многопроцессорной системы. При работе с потоками допускается использовать только стандартные классы и библиотеки из .Net 3.5 (исключая ThreadPool, BackgroundWorker, TPL). Ожидается реализация с использованием Thread-ов. Путь до входного файла и размер блока задаются в командной строке. В случае возникновения ошибки во время выполнения программы ее текст и StackTrace необходимо вывести в консоль.
В общем посидел пару вечеров и наваял прогу на сколько позволяли знания и навыки. Поскольку ранее ничего подобного не делал, поначалу даже показалось, что задание несложное. Однако отправляя проект не оставляло ощущение, что сделал не так как надо.
Так в итоге и оказалось. Мне вежливо отказали дополнив комментариями касательно кода:
1. Вся программа в одном файле, двух классах и нескольких статических методах. ООП нет.
Классы не являются лишними, если у них есть понятная область отвественности.
В данном случае, если бы выделили класс для запуска потоков и отслеживания их завершения – то это не было бы лишним.

2.Алгоритм работы не эффективный. Файл сразу бьется на блоки и для каждого блока стартует новый поток. Все сразу. Никого thread pool нет.
Для подсчета хэша каждого блока запускается отдельный поток. Запуск потока трудоемкая операция, которая требует много ресурсов. Вариантов решения этой проблемы возможно несколько. Или реализовывать свою вариацию threadPool или использовать долгоживущие потоки.
Кроме того, сейчас никак не ограничивается число запущенных потоков. При их большом количестве, они будут бороться за процессорное время и значительная часть ресурсов будет тратиться на переключение контекстов между потоками.

3.Ожидание окончания всех потоков на Thread.Sleep
Ожидание завершения на Thread.Sleep является ресурсоемким. Поскольку основной поток, ждущий завершения, постоянно просыпается и занимает процессорное время, которое можно было потратить на обсчет следующего блока. Для решения этих проблем используют примитивы синхронизации.
Проверка окончания всех потоков происходит на статической перемерной threadCount. К ней осуществляется доступ из нескольких потоков, и доступ никак не синхронизирован.
Это стандартная проблема разделения ресурсов между и не исключена ситуация, что threadCount никогда не достигнет 0.
Собственно чтобы я хотел попросить: прокомментировать код, указать на проблемные места и предложить пример более удачной реализации. Хочу понять где слабые места и что надо подтянуть в плане знаний и навыков. Заранее всем благодарен!
0
Вложения
Тип файла: rar Program.rar (1.2 Кб, 40 просмотров)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
16.11.2016, 13:02
Я подобрал для вас темы с готовыми решениями и ответами на вопрос .NET 4.x Прошу консультации экспертов (ООП, многопоточность) (C#):

Прошу мнения экспертов
Всем здрасте! 'Недавно начал изучать PHP' короче бла-бла-бла=) Прислали мне...

Прошу консультации!
Ребятки всем привет. Собственно чуть в краткрости раскажу.. Я всю жизнь имел...

Прошу совета экспертов о смене провайдера интернет
Здравствуйте. Сейчас тормозящий оптоволоконный ДжиПон 70 Мбит (реально до 30),...

Прошу консультации по iptables
Доброго всем времени суток! Установлена у меня ubuntu 10.04. Поставлен...

Прошу консультации в выборе!
Добрый день уважаемые форумчане! Нужна ваша квалифицированная помощь в выборе...

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

45
insite2012
Модератор
Эксперт .NET
4795 / 3754 / 1083
Регистрация: 12.10.2013
Сообщений: 11,000
Записей в блоге: 2
16.11.2016, 15:34 #2
Цитата Сообщение от Outwork Посмотреть сообщение
предложить пример более удачной реализации
Не буду утверждать, что самая удачная, но по-быстрому сделал.
Аргумент против - пока все потоки (по количеству ядер) не закончат просчет, программа стоит. Логичнее было бы динамически менять количество (если какой-то закончит просчет раньше). Но с учетом того, что размер блоков одинаков, то и время завершения всех потоков +- одно и то же. Так что если такой вопрос возникнет - можете так и сказать. Ятд, динамическое регулирование усложнит код. На мой взгляд, тут можно применить Producer/Consumer, но захотелось повелосипедить, без шаблонов.
Цитата Сообщение от Outwork Посмотреть сообщение
что надо подтянуть в плане знаний и навыков
Достаточно многое, по правде говоря.
Самого файла для просчета нет, допишите это в программе. И можете проверку поставить, если размер блока больше чем размер файла, выдать об этом сообщение.
0
Вложения
Тип файла: rar Архив WinRAR.rar (43.6 Кб, 36 просмотров)
freeba
Неадекват
1222 / 1024 / 193
Регистрация: 02.04.2010
Сообщений: 2,360
Записей в блоге: 2
Завершенные тесты: 2
16.11.2016, 16:19 #3
Цитата Сообщение от insite2012 Посмотреть сообщение
Не буду утверждать, что самая удачная, но по-быстрому сделал.
Совсем не удачная Так же как и у ТСа количество потоков не контролируется, их количество растет очень быстро, что приводит к:
а) затраты на переключение контекста очень быстро начинают превалировать над полезной работой.
б) Где-то на 10-тысячном блоке программа свалится с нехваткой памяти (для х86)
Цитата Сообщение от Outwork Посмотреть сообщение
Хочу понять где слабые места и что надо подтянуть в плане знаний и навыков.
По сути вас просят написать свою реализацию ThreadPool'а - соответственно следует почитать про параллельность в .NET и про устройство этого самого ThreadPool (CLR via C# Рихтера подойдет). Собственно и все.

Не по теме:

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



Ну и свой вариант реализации:
0
Вложения
Тип файла: 7z ConsoleApplication23.7z (25.6 Кб, 45 просмотров)
insite2012
Модератор
Эксперт .NET
4795 / 3754 / 1083
Регистрация: 12.10.2013
Сообщений: 11,000
Записей в блоге: 2
16.11.2016, 16:27 #4
Цитата Сообщение от freeba Посмотреть сообщение
Так же как и у ТСа количество потоков не контролируется, их количество растет очень быстро
Вот и нет. Их количество в каждый момент времени всегда равно количеству ядер. Пока все потоки (по количеству ядер, например 4) не просчитают каждый свой блок, больше их не создается (вы пропустили строку с WaitHandle.WaitAll()?)
0
freeba
Неадекват
1222 / 1024 / 193
Регистрация: 02.04.2010
Сообщений: 2,360
Записей в блоге: 2
Завершенные тесты: 2
16.11.2016, 16:41 #5
insite2012, Эм... Небольшой скрин. В крайнем случае скормите 4х гиговый файл программе и убедитесь.
0
Миниатюры
Прошу консультации экспертов (ООП, многопоточность)  
IamRain
1279 / 1171 / 360
Регистрация: 02.08.2011
Сообщений: 3,416
16.11.2016, 16:42 #6
Outwork, видимо, задача проверят, знаете ли вы, что создание Thread - дорогостоящая операция.
Вы создаете Thread-ы в неограниченном кол-ве, надо было фиксировать какое-то конкретное количество и не создавать больше, а оставшиеся должны продолжать работу над общим ресурсом.
+ Знание Producer-Consumer.
Проверка знаний и/или адекватности. freeba, Вовсе не значит, что нужно бегать от таких контор.
0
insite2012
Модератор
Эксперт .NET
4795 / 3754 / 1083
Регистрация: 12.10.2013
Сообщений: 11,000
Записей в блоге: 2
16.11.2016, 16:54 #7
Цитата Сообщение от freeba Посмотреть сообщение
Эм... Небольшой скрин.
freeba, просчет происходит быстро. Поставьте в методе просчета задержку секунд в 5-6 и увидите, что вывод идет блоками по количеству потоков.
0
freeba
Неадекват
1222 / 1024 / 193
Регистрация: 02.04.2010
Сообщений: 2,360
Записей в блоге: 2
Завершенные тесты: 2
16.11.2016, 17:12 #8
Цитата Сообщение от insite2012 Посмотреть сообщение
freeba, просчет происходит быстро. Поставьте в методе просчета задержку секунд в 5-6 и увидите, что вывод идет блоками по количеству потоков.
Любопытно. Т.е. или несколько секунд задержки или падение... Имхо, так себе решение.

Не по теме:


Цитата Сообщение от IamRain Посмотреть сообщение
freeba, Вовсе не значит, что нужно бегать от таких контор.
Еще как значит. Для проверки работы с многопотоком обычно сервер какой нибудь просят написать. А тут какая то мечта велосипедостроителя :)

0
TopLayer
725 / 548 / 290
Регистрация: 23.10.2016
Сообщений: 1,286
Завершенные тесты: 7
16.11.2016, 17:27 #9
freeba, Ваш диспетчер задач гонит
1
Usaga
Эксперт .NET
3730 / 3022 / 549
Регистрация: 21.01.2016
Сообщений: 11,993
Завершенные тесты: 2
16.11.2016, 17:27 #10
freeba, реализация своего варианта ThreadPool - хорошая задача, интересная.

А вот про "бежать от конторы без оглядки" это ты зря. Legacy-код никто не отменял. А там и прямая работа с потоками и своя реализация LINQ и что угодно. Если не писать в том же стиле, то как минимум понимать, что в таком коде происходит - нужно.
0
Exerion
[Bicycle Reinventor]
288 / 228 / 105
Регистрация: 19.10.2011
Сообщений: 605
Записей в блоге: 2
Завершенные тесты: 2
16.11.2016, 17:46 #11
Выложу свою попытку тоже, покритикуйте.
0
Вложения
Тип файла: 7z ConsoleSHA.7z (25.0 Кб, 32 просмотров)
freeba
Неадекват
1222 / 1024 / 193
Регистрация: 02.04.2010
Сообщений: 2,360
Записей в блоге: 2
Завершенные тесты: 2
16.11.2016, 17:59 #12
TopLayer, отнюдь. insite2012 написал вариант ТСа, обильно сдобренный оверинжирингом и с разбитием на классы. То же создание нового потока на каждый блок и отсутствие контроля количества потоков. WaitHandle.WaitAll - не панацея, если поток послал сигнал об окончании работы - это не значит, что он уничтожен.

Цитата Сообщение от Usaga Посмотреть сообщение
А вот про "бежать от конторы без оглядки" это ты зря. Legacy-код никто не отменял. А там и прямая работа с потоками и своя реализация LINQ и что угодно. Если не писать в том же стиле, то как минимум понимать, что в таком коде происходит - нужно.
Имелась ввиду не столько работа с кодом, сколько личность дающего такие задания. Тестовые задания даются непосредственными начальниками, ну или как минимум ими одобряются. Переписывание куска фреймворка характеризует оных не с самой лучшей стороны. Хотя это все субъективное мнение.
0
TopLayer
725 / 548 / 290
Регистрация: 23.10.2016
Сообщений: 1,286
Завершенные тесты: 7
16.11.2016, 18:09 #13
freeba, Доступ к completeCount из разных потоков без синхронизации
Кликните здесь для просмотра всего текста
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
    public class QuasiPool
    {
        ThreadWorker[] threads = new ThreadWorker[Environment.ProcessorCount];
        int completeCount = 0;
 
        public QuasiPool()
        {
            for (int i = 0; i < threads.Length; i++)
            {
                var worker = new ThreadWorker();
                worker.ThreadComplete += Worker_ThreadComplete;
 
                threads[i] = worker;
            }
        }
 
        private void Worker_ThreadComplete(object sender, EventArgs e)
        {
            completeCount++;
            if (completeCount == threads.Length) Console.WriteLine("Completed.");
        }
 
        public void Run()
        {
            foreach (var item in threads)
            {
                var thread = new Thread(new ThreadStart(item.Run));
                thread.Start();
            }
        }
 
    }


Добавлено через 4 минуты
Про создание потоков Вы правы. А вот про освобождение системных ресурсов при использовании Thread интересно было бы почитать.
0
freeba
Неадекват
1222 / 1024 / 193
Регистрация: 02.04.2010
Сообщений: 2,360
Записей в блоге: 2
Завершенные тесты: 2
16.11.2016, 18:20 #14
TopLayer, В данном случае не имеет значения - этот код отработает всегда правильно (операция инкремента в clr отрабатывает атомарно, по крайней мере пока, хотя микрософт настойчиво рекомендует использовать Interlocked.Increment). Ошибка в проекте есть, но она не здесь
0
TopLayer
725 / 548 / 290
Регистрация: 23.10.2016
Сообщений: 1,286
Завершенные тесты: 7
16.11.2016, 18:32 #15
freeba, у меня этот код не выводит 5000
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
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
 
namespace ThreadTests
{
    class Program
    {
        private static int count = 0;
        static void Main(string[] args)
        {
            var tasks = new List<Task>();
            for (int i = 0; i < 5000; ++i)
                tasks.Add(Task.Run(() => NoAction()));
            foreach (var t in tasks)
                t.Wait();
            Console.WriteLine(count);
        }
 
        [MethodImpl(MethodImplOptions.NoInlining)]
        static void NoAction()
        {
            count++;
        }
    }
}
0
freeba
Неадекват
1222 / 1024 / 193
Регистрация: 02.04.2010
Сообщений: 2,360
Записей в блоге: 2
Завершенные тесты: 2
16.11.2016, 18:36 #16
Цитата Сообщение от TopLayer Посмотреть сообщение
freeba, у меня этот код не выводит 5000
Так и должно быть. Он выведет 4999
Цитата Сообщение от TopLayer Посмотреть сообщение
А вот про освобождение системных ресурсов при использовании Thread интересно было бы почитать.
Посмотрите код Exerion, он убивает старый поток прежде чем стартануть новый.
0
TopLayer
725 / 548 / 290
Регистрация: 23.10.2016
Сообщений: 1,286
Завершенные тесты: 7
16.11.2016, 18:39 #17
freeba, этот код выводит даёт разные результаты при каждом запуске.

Добавлено через 55 секунд
и всё-таки должен выводить 5000 а не 4999
0
insite2012
Модератор
Эксперт .NET
4795 / 3754 / 1083
Регистрация: 12.10.2013
Сообщений: 11,000
Записей в блоге: 2
16.11.2016, 18:45 #18
Цитата Сообщение от TopLayer Посмотреть сообщение
код выводит даёт разные результаты при каждом запуске.
Да. аналогично. Система у вас случаем не 64 бит? А если поставить блокировку, все срабатывает.
0
TopLayer
725 / 548 / 290
Регистрация: 23.10.2016
Сообщений: 1,286
Завершенные тесты: 7
16.11.2016, 18:46 #19
insite2012, да, 64 бит
0
insite2012
Модератор
Эксперт .NET
4795 / 3754 / 1083
Регистрация: 12.10.2013
Сообщений: 11,000
Записей в блоге: 2
16.11.2016, 18:49 #20
Цитата Сообщение от TopLayer Посмотреть сообщение
64 бит
На 32-х битной XP все отрабатывает как положено. Без блокировок.
0
16.11.2016, 18:49
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
16.11.2016, 18:49
Привет! Вот еще темы с решениями:

Прошу Вашей профессиональной консультации
Всем здравствуйте уважаемые. Помогите разобраться в логах. Не могу &quot;вкурить&quot;...

Прошу консультации с HP Pavilion dv6 3057er
Всем привет! Прошу консультации. Ноутбук HP Pavilion dv6 3057er. Windows 7...

Тестирование компонентов по даташиту. Прошу консультации
Рассмотрим предлагаемые тесты в даташите на мосфет FR9024N (в качестве примера).

Выбор библиотеки для работы с *.pdf прошу консультации
Всем добрый день. Возникла потребность редактирования pdf джавой. Погуглив,...


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

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

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru