Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: 1 2 3 4 [5] 6   Вниз
  Печать  
Автор Тема: Процессы  (Прочитано 111651 раз)
0 Пользователей и 3 Гостей смотрят эту тему.
v.korleone
Помогающий

ua
Offline Offline

« Ответ #120 : 05-01-2009 12:56 » 

Вад, я был прав... Препод, сказал, что нужно также сделать, чтобы ввод из файла и вывод студентов на экран, осуществлялся с помощью одного потока. Я так думаю, что сделаю еще одну функцию типа этой "unsigned __stdcall CalcAvg (void * arg)", только внутрь запихну две функции:
Код: (C++)
void inputstfile(Student s[],int &m);        // Функция ввода из файла
void outputst(Student s[],int m);            // Функция вывода на экран массива студентов
Как думаешь, прокатит?
Еще, препод пожелал, чтобы я поставил семафор который будет контролировать, чтобы когда первый поток работает с файлом, остальные 3 ожидали, а также этот семафор дает команду, что можно приступить к вычислениям среднего, когда файл будет загружен, первым потоком.
Хочу знать твои пожелания при решении данной задачи.
Записан
v.korleone
Помогающий

ua
Offline Offline

« Ответ #121 : 05-01-2009 12:59 » 

RXL, здесь абсолютно согласен
Цитата
2. Не пости несколько сообщений подряд, когда можно отредактировать предыдущее. В следующий раз не буду слеплять их а буду удалять.
извиняюсь.
Со всем остальным ознакомлюсь.
Записан
Вад
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #122 : 05-01-2009 13:44 » 

v.korleone, не совсем уловил суть. Преподаватель хочет, чтобы потоки поочерёдно сами читали из файла студентов? А как, по его мысли, быть с 1-м заданием, про среднее по дисциплине - 4 раза прочитать весь файл, чтобы у каждого потока были все данные? Странно как-то...

А с семафором всё, в принципе, ясно: семафор нужен, чтобы только один поток одномоментно мог читать что-то из файла, а остальные, если им понадобился доступ к файлу, ожидали, пока не читающий не освободит этот файл и не просигнализирует с помощью семафора.
Записан
v.korleone
Помогающий

ua
Offline Offline

« Ответ #123 : 05-01-2009 14:00 » 

Вад, насколько я понял он хочет чтобы один поток загрузил все в память, а остальные брали данные из памяти, как-то так. Такой вариант возможен?
Записан
Вад
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #124 : 05-01-2009 14:12 » 

А, кажется, понимаю. Он имеет в виду конвейерную схему? Т.е. один отдельный поток загружает данные и даёт сигнал остальным потокам, что можно начинать этими данными пользоваться? Что ж, тогда задание логичное.
Записан
v.korleone
Помогающий

ua
Offline Offline

« Ответ #125 : 05-01-2009 14:27 » 

Точно! Ты правильно понял! С чего начать?
Записан
v.korleone
Помогающий

ua
Offline Offline

« Ответ #126 : 05-01-2009 14:29 » 

сделал так:
Код: (C++)
unsigned __stdcall vvod( void * arg)   // Функція потоку
 {  int n,N=100;
    Student a[N];
    inputstfile(a,n);
    in.close();
    outputst(a,n);
    return 0;
}
но остальные потоки не видят, данных загруженых этим потоком. Средний бал для все студентов "0", поля таблицы, где должны быть студенты пусты.
Записан
Вад
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #127 : 05-01-2009 14:39 » 

v.korleone, правильно - откуда бы им знать о твоих локальных переменных и внутренних действиях? Нужно сделать результат доступным - по тому же принципу, что и в уже выполненных задачах. Также придётся предоставлять доступ к семафору нескольким потокам - у тебя ведь он будет один, насколько я понимаю? (правда, с семафором можно и проще - использовать именованный семафор)
Записан
v.korleone
Помогающий

ua
Offline Offline

« Ответ #128 : 06-01-2009 06:46 » 

Вад, сделал вот так:
Вот структура (та которая для подсчета среднего по дисциплинам) добавил туда еще "n":
Код: (C++)
struct STask        // Структура, которая используется для подсчета среднего для каждой дисциплины
{
   Student *src;    // Исходные данные
   int size;        // Число элементов в src
   int subj;        // Дисциплина, для которой считаем среднее
   float avg;       // Средний балл - используется для сохранения результата
   int n;
};
Вот код самой функции:
Код: (C++)
unsigned __stdcall InOut (void * arg)
{   STask *task = (STask*) arg;
        if (task) // Проверка передачи параметров
    {   inputstfile(task->src,task->n);
        in.close();
        outputst(task->src,task->n);
        return 0;
    }
    else
        return 1; // Ошибка!
}
Все компилится без ошибок, выводит студентов на экран, но не считает среднее по дисциплинам, а среднее для студентов считает.
Вот реализация вызова в главной программе, потока для вывода на экран:
   
Код: (C++)
    STask tasks[4];
    tasks[i].src = a;
    Thread[0] = (HANDLE)_beginthreadex(NULL, 0, InOut, &tasks[i], 0, &tid);
    WaitForMultipleObjects(1, Thread, TRUE, INFINITE);
    CloseHandle(Thread[0]);
   
Что может быть?
P.S. Как правильно записать
Код: (C++)
"tasks[i].src = a;"

или
Код: (C++)
"tasks[0].src = a;"
?
P.S.P.S. Я вот, что подумал может семофор пора добавлять (и причина именно в этом)? Если да, то не мог бы ты расказать, как и куда его ставить.
« Последнее редактирование: 06-01-2009 09:13 от v.korleone » Записан
Вад
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #129 : 06-01-2009 10:43 » 

Да, семафор добавлять, пожалуй, самое время. В целом-то представляешь, что такое семафор, и как им пользоваться?

И ещё: думаю, я бы сделал отдельную структуру для задачи InOut - там и нужно-то только массив прочитать и размер его вернуть, остальные поля в STask избыточны. А ещё, в прежней версии функции main у тебя был жёстко прописан размер в 20 элементов при выводе на экран, а для подсчёта в задачи в первом случае передавалось n, которое вычислялось в процессе чтения файла - оно потерялось, и ничего считаться не будет, потому что n = 0. Вторая же задача не совсем верно работает, поскольку не делит массив на ровные части n/4, а просто берёт по 5 студентов в каждую задачу. А если студентов в файле будет больше или меньше?
« Последнее редактирование: 06-01-2009 10:47 от Вад » Записан
v.korleone
Помогающий

ua
Offline Offline

« Ответ #130 : 06-01-2009 17:59 » 

Вад, спасибо, за подсказки. Сделал структуру. Теперь вопрос:
Цитата
А ещё, в прежней версии функции main у тебя был жёстко прописан размер в 20 элементов при выводе на экран, а для подсчёта в задачи в первом случае передавалось n, которое вычислялось в процессе чтения файла - оно потерялось, и ничего считаться не будет, потому что n = 0.
Больше мест с переменной n, в функции main, я не заметил:
   
Код: (C++)
    max = a[0].col[3];
    for(i = 1; i < n; i++)
    if (a[i].col[3]>max) max = a[i].col[3];
Ты хочешь сказать чтобы включить эту функцию в unsigned __stdcall InOut (void * arg)?
Записан
Вад
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #131 : 06-01-2009 18:07 » 

Какую функцию? Куда внести? С ума сойти...
Я про это говорил:
Код:
for (int i = 0; i < 4; ++i)
    {   tasks[i].src = a; // было: tasks[i].src = s;
        tasks[i].size = n;
        tasks[i].subj = i;
        Thread[i] = (HANDLE)_beginthreadex(NULL, 0, CalcAvg, &tasks[i], 0, &tid);
    }
Записан
v.korleone
Помогающий

ua
Offline Offline

« Ответ #132 : 06-01-2009 18:26 » 

Это для подсчета среднего по дисциплинам, ты хочешь сказать нужно сделать аналогично для вывода на экран.
Записан
Вад
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #133 : 06-01-2009 18:45 » 

Я хочу сказать, что если у тебя ввод данных будет в отдельном потоке, и потоки, выполняющие CalcAvg не будут знать, сколько там элементов было прочитано в отдельном потоке, то ничего они считать не будут.
Записан
v.korleone
Помогающий

ua
Offline Offline

« Ответ #134 : 06-01-2009 18:54 » 

Вот добавил "n" при вызове:
Код: (C++)
   
IOput inouts[4];
inouts[0].src = a;
inouts[0].n = n;
Thread[0] = (HANDLE)_beginthreadex(NULL, 0, InOut, &inouts[0], 0, &tid);
WaitForMultipleObjects(1, Thread, TRUE, INFINITE);
CloseHandle(Thread[0]);
вот функция для потока:
Код: (C++)
unsigned __stdcall InOut (void * arg)
{   IOput *inout = (IOput*) arg;
        if (inout) // Проверка передачи параметров
    {   inputstfile(inout->src,inout->n);
        in.close();
        outputst(inout->src,inout->n);
        return 0;
    }
    else
        return 1; // Ошибка!
}
Каким образом им (потокам) можно сообщить сколько там элементов было прочитано в отдельном потоке?
Записан
Вад
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #135 : 06-01-2009 18:58 » 

Код: (C++)
   
IOput inouts[4];
inouts[0].src = a;
inouts[0].n = n;
Thread[0] = (HANDLE)_beginthreadex(NULL, 0, InOut, &inouts[0], 0, &tid);
WaitForMultipleObjects(1, Thread, TRUE, INFINITE);
CloseHandle(Thread[0]);
OMG, а зачем тебе массив из 4х структур?

Цитата
Каким образом им (потокам) можно сообщить сколько там элементов было прочитано в отдельном потоке?
А сам как думаешь? Улыбаюсь
Записан
v.korleone
Помогающий

ua
Offline Offline

« Ответ #136 : 06-01-2009 19:00 » 

Невнимательный я, невнимательный!!!
Неужели указателями??? Улыбаюсь
Семафором??? Жаль
Может "n" присвоить 20, но это тоже пожалуй не выход?
Не знаю...
Вад, ну ответь, пожалуйста.
Может сделать, чтобы функциия возращала??? А черт его знает...
« Последнее редактирование: 06-01-2009 19:52 от v.korleone » Записан
v.korleone
Помогающий

ua
Offline Offline

« Ответ #137 : 06-01-2009 20:09 » 

Вад, но я честно не знаю, как? Скажи...
Может здесь, что то не так (вроде все как ты писал)?
Структура правильна:(?)
Код: (C++)
struct IOput        // Структура, которая используется для вывода массива n
{
   Student *src;    // Исходные данные
   int n;           //
};
« Последнее редактирование: 06-01-2009 20:20 от v.korleone » Записан
Вад
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #138 : 06-01-2009 20:41 » 

Чтобы значение было одно для всех потоков, даже если кто-то один это число меняет, нужно, чтобы все владели указателями на одну и ту же область памяти, где хранится число.
Записан
v.korleone
Помогающий

ua
Offline Offline

« Ответ #139 : 06-01-2009 20:42 » 

так я и пишу вроде *src, или это не то?
Записан
v.korleone
Помогающий

ua
Offline Offline

« Ответ #140 : 06-01-2009 20:50 » 

Код: (C++)
inouts[0].src = a;
inouts[0].size = 20;
Может как-то так?
Может n=20  и все... Но я пробовал буквально так, не получается
« Последнее редактирование: 06-01-2009 20:56 от v.korleone » Записан
Вад
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #141 : 06-01-2009 21:04 » 

Ну, а размер массива?
Записан
v.korleone
Помогающий

ua
Offline Offline

« Ответ #142 : 06-01-2009 21:14 » 

...
const int N = 100;
...
Student a[N];    // Массив студентов
Всеравно не вкурю!
Цитата
Ну, а размер массива?
- не понял, понял так как написал вверху...
« Последнее редактирование: 06-01-2009 21:21 от v.korleone » Записан
Вад
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #143 : 06-01-2009 21:23 » 

Как к твоему int n в структуре IOput получат доступ остальные потоки, когда им потребуется знать, сколько студентов в списке?
Записан
v.korleone
Помогающий

ua
Offline Offline

« Ответ #144 : 06-01-2009 21:31 » 

Сделать в остальных 2 структурах указатель на IOput? Правильно???
« Последнее редактирование: 06-01-2009 21:35 от v.korleone » Записан
Вад
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #145 : 06-01-2009 21:39 » 

Ну, можно и так.
Записан
v.korleone
Помогающий

ua
Offline Offline

« Ответ #146 : 06-01-2009 21:41 » 

Вад, разобрался с предыдущей задачей. Перехожу к семофорам.
Знаю, немного теории, что семафоры используются для синхронизации, используют счетчик т.д. т.п. (на практических занятиях мы их не расматривали, только на лекциях). Также теоретически знаю создание семафора:
Код: (C++)
HANDLE CreateSemaphore
(
LPSECURITY_ATTRIBUTES lpSemaphoreAttributes, // атрибут доступа
LONG lInitialCount, // инициализированное начальное состояние счетчика
LONG lMaximumCount, // максимальное количество обращений
LPCTSTR lpName // имя объекта
);
У меня вопрос по практике, куда его вставлять? И как с ним обращаться?
Это "LONG lMaximumCount, // максимальное количество обращений" равно по всей видимости 3 т.к. 3 потока ждут?
Или это все же  LONG lInitialCount, // инициализированное начальное состояние счетчика?
lpName а здесь, что Thread[0]?
А "LPSECURITY_ATTRIBUTES lpSemaphoreAttributes, // атрибут доступа" чему равно?

Новый вопрос: как лучше для данной задачи сделать, семафорами или может быть функцией ожидания?
« Последнее редактирование: 07-01-2009 10:36 от v.korleone » Записан
Вад
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #147 : 07-01-2009 10:58 » 

Про семафоры:
http://www.firststeps.ru/mfc/msdn/r.php?81
http://www.firststeps.ru/mfc/winapi/r.php?117

А лучше делать так, как сказал преподаватель Улыбаюсь
Записан
v.korleone
Помогающий

ua
Offline Offline

« Ответ #148 : 07-01-2009 11:12 » 

Вад, в том то и дело, что я напутал, он сказал осуществить задачу синхронизации, а как это сделать, нужно смотреть самому т.е. как будет лучше. Что скажешь?
Есть мысль использовать события, хочу узнать твое мнение.
« Последнее редактирование: 07-01-2009 11:26 от v.korleone » Записан
Вад
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #149 : 07-01-2009 11:33 » 

В принципе, можно и событие. Почему нет?
Записан
Страниц: 1 2 3 4 [5] 6   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines