Форум программистов, компьютерный форум CyberForum.ru

C++, задачка. Где же я мог накосячить? - C++

Восстановить пароль Регистрация
 
Ranadaine
0 / 0 / 0
Регистрация: 03.12.2012
Сообщений: 6
26.12.2012, 22:29     C++, задачка. Где же я мог накосячить? #1
Собственно, есть вот такая задачка:

Используя С++, Win32 API и STL корректно реализовать следующую задачу:

Откуда-то дано:

C++
1
2
3
4
5
6
7
8
9
10
11
12
class Request
{
};
 
// возвращает NULL если нужно завершить процесс, либо указатель на память,
// которую в дальнейшем требуется удалить
Request* GetRequest() throw(); 
 
// обрабатывает запрос, но память не удаляет
void ProcessRequest(Request* request) throw();
 
const int NumberOfThreads = 2;
Основной поток должен:
1) Запустить несколько рабочих потоков (NumberOfThreads).
2) Класть в одну очередь заданий задачи до тех пор, пока GetRequest() не вернёт NULL.
3) Корректно остановить рабочие потоки. Они должны доделать текущий ProcessRequest, если он имеется, и остановиться. Если имеются необработанные задания, не обращать на них внимания.
4) Завершить программу.
Рабочий поток должен:
1) Обрабатывать поступающие через очередь запросы с помощью ProcessRequest.
2) Завершиться, как только основной поток ему это скомандует.
Вызовы GetRequest() и ProcessRequest() могут работать долго.


Моё решение выглядело как-то так:
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
#include <windows.h>
#include <deque>
#include <iostream>
using namespace std;
 
// данные, имеющиеся извне
class Request{};
Request* GetRequest() throw(){}; //а это, всё-таки, явственное указание на отсутствие exception
void ProcessRequest(Request* request) throw(){};
const int NumberOfThreads = 2;
 
// дополнительные объекты и методы, используемые в программе
void Full_Process(); // полный цикл обработки Request'a (получение и обработка)
CRITICAL_SECTION req_queue_cs; // крит. секция, определяющая право доступа к очереди Request'ов
deque <Request*> req_queue; // собственно, очередь Request'ов
bool finalize_signal=false; // признак необходимости завершения потоков - обработчиков
 
int main(int argc, char const *argv[])
{   
    // инициализация критической секции и создание необходимого числа потоков-обработчиков
    InitializeCriticalSection(&req_queue_cs);
    HANDLE* threads = new HANDLE[NumberOfThreads];
    for (int i = 0; i < NumberOfThreads; ++i)
    {
        threads[i]=CreateThread(NULL,0, (LPTHREAD_START_ROUTINE) Full_Process, NULL, 0, NULL);
    }
    
    Request* req;
    // цикл генерации Request'ов
    while (true) {
            req=GetRequest();
            
            // условие выхода из цикла и подача обработчикам сигнала на завершение
            if (req==NULL) {
            finalize_signal=true;
            WaitForMultipleObjects(NumberOfThreads,threads,true,INFINITE);
            req_queue.clear();
            return 0;
            }
        // вход в крит. секцию и добавление Request'а в очередь
        EnterCriticalSection(&req_queue_cs);
        req_queue.push_back(req);
        LeaveCriticalSection(&req_queue_cs);
    }
}
 
// основная функция обработки
void Full_Process(){
    Request* temp;
    // рабочий цикл c условием выхода
    while (!finalize_signal) {
        temp=NULL;
        // попытка входа в крит. секцию
        if (TryEnterCriticalSection(&req_queue_cs)){
            // если очередь не пуста - выполнение действий над первым элементом, иначе - освобождение крит. секции
            if (req_queue.size()>0){
            temp=req_queue.front();
            req_queue.pop_front();
            LeaveCriticalSection(&req_queue_cs);
            // обработка Request'a
            ProcessRequest(temp);
            // удаление обработанного объекта не производится в связи с отсутствием такого указания в задании
            }
            else LeaveCriticalSection(&req_queue_cs);
        }
        else Sleep(1);
    }
    return;
}
Таки оно было признано недостаточно правильным. Где у меня основные ошибки?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
26.12.2012, 22:29     C++, задачка. Где же я мог накосячить?
Посмотрите здесь:

самый простой вопрос который мог задать нуб!не получается подсчет слов!!!!! C++
C++ Как в программе сделать чтобы результат мог быть не целым ?
C++ И последняя задачка, где нужно реализовать 3 класса. Надеюсь, что Вы справитесь:)
как сделать через функцию пользователя и чтобы размер мог вводить пользователь ? C++
C++ Не мог бы кто-нибудь дать пособия для 1 курса с++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
asidorchenko
379 / 205 / 25
Регистрация: 09.04.2012
Сообщений: 635
27.12.2012, 00:13     C++, задачка. Где же я мог накосячить? #2
Нет освобождения памяти выделенной с помощью new и обнуления указателя на данную область памяти. Возможно это могло показаться очень серьезной ошибкой (утечка памяти).

Возможно не во всех точках возврата есть return.

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

Возможно ожидалась обработка исключений.

Возможно где-то нет проверок перед вызовами функций на корректность ожидаемых функциями данных. (ProcessRequest(temp);
)
Ranadaine
0 / 0 / 0
Регистрация: 03.12.2012
Сообщений: 6
27.12.2012, 00:31  [ТС]     C++, задачка. Где же я мог накосячить? #3
Итак-с. Нам сверху дано, что GetRequest и ProcessRequest не дают исключений в принципе. Просто исходя из их объявления. Соответственно, try-catch здесь не нужны.

Return'ы вроде бы везде есть.

Память - тоже не соглашусь. В задании не было указано, откуда именно приходят данные. Может, они лежат в разделяемой памяти и с ними планируется что-то еще делать? Тогда их не то, что не нужно чистить, но и категорически нельзя. А единственный оператор выделения памяти, который у меня есть - это задание массива HANDLE'ов. И deque с указателями чистится сам перед завершением программы.

Либо я что-то не так понимаю... Можно чуть более подробно?
И да. Касательно стиля критику принимаю целиком и полностью, это одна из самых слабых моих сторон.
asidorchenko
379 / 205 / 25
Регистрация: 09.04.2012
Сообщений: 635
27.12.2012, 00:50     C++, задачка. Где же я мог накосячить? #4
Я имел в виду, что вы не освободили память из под массива HANDLE'ов..
Ranadaine
0 / 0 / 0
Регистрация: 03.12.2012
Сообщений: 6
27.12.2012, 00:57  [ТС]     C++, задачка. Где же я мог накосячить? #5
Оу... Каюсь, не понял этого сразу. Тут - да, проморгал.
А еще что-нибудь?
UserAK
70 / 70 / 4
Регистрация: 25.12.2012
Сообщений: 189
Записей в блоге: 2
27.12.2012, 05:55     C++, задачка. Где же я мог накосячить? #6
в глаза бросается ++i в цикле создания потоков.
Schizorb
27.12.2012, 06:57
  #7

Не по теме:

Цитата Сообщение от UserAK Посмотреть сообщение
в глаза бросается ++i в цикле создания потоков.
А что с ней не так?

UserAK
70 / 70 / 4
Регистрация: 25.12.2012
Сообщений: 189
Записей в блоге: 2
27.12.2012, 07:57     C++, задачка. Где же я мог накосячить? #8
ой извиняюсь, всё нормально с ней, чёт я подумал, что она увеличивается раньше времени.
Ranadaine
0 / 0 / 0
Регистрация: 03.12.2012
Сообщений: 6
27.12.2012, 08:45  [ТС]     C++, задачка. Где же я мог накосячить? #9
Ну должно же с ней быть хоть что-то серьезно не так...
UserAK
70 / 70 / 4
Регистрация: 25.12.2012
Сообщений: 189
Записей в блоге: 2
27.12.2012, 10:00     C++, задачка. Где же я мог накосячить? #10
вот оно получает запросы и кладёт их в очередь, когда запрос получить не может - всё останавливает и очередь уничтожает, не смотря на то, что там может ещё что-то осталось. это наверное не совсем правильно. или я чего то упустил.

Добавлено через 3 минуты
ну то-есть, наверное неплохо было бы очередь проверить, прежде чем флаг ставить

Добавлено через 19 минут
CloseHandle не нашёл тут
asidorchenko
379 / 205 / 25
Регистрация: 09.04.2012
Сообщений: 635
27.12.2012, 14:25     C++, задачка. Где же я мог накосячить? #11
Код
 for (int i = 0; i < NumberOfThreads; ++i)
    {
        threads[i]=CreateThread(NULL,0, (LPTHREAD_START_ROUTINE) Full_Process, NULL, 0, NULL);
    }
Нет проверки на возврат NULL функцией CreateThread и обработки соответствующей ошибки, связанной с тем, что поток не создан.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
27.12.2012, 21:06     C++, задачка. Где же я мог накосячить?
Еще ссылки по теме:

Где оибка не мог ни как понять C++
C++ Знатоки С++ и СИ, где вы ? Интересная олиппиадная задачка (Нужно перевести )
C++ Bat файл, который бы мог компилировать С++ из VS

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

Или воспользуйтесь поиском по форуму:
Ranadaine
0 / 0 / 0
Регистрация: 03.12.2012
Сообщений: 6
27.12.2012, 21:06  [ТС]     C++, задачка. Где же я мог накосячить? #12
asidorchenko, вооот, это уже серьезный мой косяк. Взял на заметку.
UserAK, отсутствие CloseHandle - тоже моя оплошность. Однако с проверкой очереди - таки неправда ваша, ибо в задании явно сказано
1) Запустить несколько рабочих потоков (NumberOfThreads).
2) Класть в одну очередь заданий задачи до тех пор, пока GetRequest() не вернёт NULL.
3) Корректно остановить рабочие потоки. Они должны доделать текущий ProcessRequest, если он имеется, и остановиться. Если имеются необработанные задания, не обращать на них внимания.
4) Завершить программу.
Yandex
Объявления
27.12.2012, 21:06     C++, задачка. Где же я мог накосячить?
Ответ Создать тему
Опции темы

Текущее время: 11:40. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru