Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

RFpro.ru: Программирование на C / C++


Хостинг портала RFpro.ru:
Московский хостер
Профессиональный ХОСТИНГ на базе Linux x64 и Windows x64

РАССЫЛКИ ПОРТАЛА RFPRO.RU

Лучшие эксперты данной рассылки

Гаряка Асмик
Статус: Академик
Рейтинг: 7168
∙ повысить рейтинг »
Boriss
Статус: Академик
Рейтинг: 2651
∙ повысить рейтинг »
Абаянцев Юрий Леонидович aka Ayl
Статус: Профессионал
Рейтинг: 2252
∙ повысить рейтинг »

/ КОМПЬЮТЕРЫ И СОФТ / Программирование / C/C++

Номер выпуска:1632
Дата выхода:15.02.2011, 17:30
Администратор рассылки:Киселёва Алёна aka Verena (Профессор)
Подписчиков / экспертов:321 / 188
Вопросов / ответов:1 / 1

Вопрос № 182146: Здравствуйте, уважаемые эксперты! Прошу вас ответить на следующий вопрос:Помогите написать программу на языке С++. Распишите какие объекты используются, подробно про комментируйте основные части алгоритма и при возможности приложите файл с готовой пр...



Вопрос № 182146:

Здравствуйте, уважаемые эксперты! Прошу вас ответить на следующий вопрос:Помогите написать программу на языке С++. Распишите какие объекты используются, подробно про комментируйте основные части алгоритма и при возможности приложите файл с готовой программой.
Условие задачи:
4 объекта хаотично движутся в одном окне.
- Форма объекта значение не имеет. Квадраты, треугольники, кружочки, на Ваше усмотрение.
- Направление и скорость значение не имеют.
- Главное, что каждый объект должен отрисовываться отдельным потоком (thread).
- Используя объекты синхронизации, добиться того, чтобы объекты не наезжали друг на друга

Заранее Большое Спасибо!!!!!!!!!!!!

Отправлен: 09.02.2011, 09:12
Вопрос задал: Magma (Посетитель)
Всего ответов: 1
Страница вопроса »


Отвечает Киселёва Алёна aka Verena (Профессор) :
Здравствуйте, Magma!
Вот пример под Builder 6.0. Я так понимаю, задание на использование api-функций синхронизации. В качестве объекта синхронизации используем событие (event). Сначала надо его создать функцией CreateEvent.
Эта функция создаёт или открывает существующее событие, возвращаемым значением является его описатель.
Код:
HANDLE CreateEvent(
LPSECURITY_ATTRIBUTES lpEventAttributes, //Аттрибуты защиты
BOOL bManualReset, //Ручной сброс
BOOL bInitialState, //Состояние при создании
LPCTSTR lpName //Имя (если необходимо)
);

Параметры функции:
lpEventAttributes - в качестве этого параметра передаётся адрес структуры вида:
Код:
typedef struct _SECURITY_ATTRIBUTES {
DWORD nLength; //Размер структуры (как правило, берётся sizeof)
LPVOID lpSecurityDescriptor; //Указатель на дескриптор, контролирующий совместное //использование объекта
BOOL bInheritHandle; //Флаг, разрешающий наследование объекта дочерним процессом
} SECURITY_ATTRIBUTES, *PSECURITY_ATTRIBUTES;

bManualReset - если этот параметр true, то помещение объекта в несигнальное состояние нужно производить вручную (путём вызова специальной функции). Если же передать сюда false, то событие будет обладать автосбросом, т.е. автоматически возвращаться в несигнальное состояние.
bInitialState - если этот параметр равен true, начальное состояние события - сигнальное, в противном случае - несигнальное.
Более подробную информацию можно получить в MSDN.
В данном случае вызов такой:
hEvent = CreateEvent(NULL, FALSE, TRUE, NULL);
т.е. автосброс и исходное состояние - сигнальное.
Чтобы делать это событие сигнальным (что мы будем делать, как только надо будет освободить ресурс, в данном случае - область рисования), будем вызывать функцию SetEvent (hEvent).
Также необходимо, собственно, дождаться, когда ресурс будет свободен, т.е. событие станет сигнальным. Для этого предусмотрен ряд wait-функций, нас в данном случае интересует WaitForSingleObject. Эта функция приостанавливает выполнение текущего потока до тех пор, пока указанный в её параметрах объект ядра не придёт в сигнальное состояние (также возможен выход по таймауту). Применяется для ограниничения доступа к разделяемым ресурсам. Параметром чаще всего служит событие, семафор или мьютекс, но также в качестве параметра может выступать уведомление (notification), процесс, поток и некоторые другие объекты. Возвращаемое значение показывает, что послужило выходом из функции. Это может быть WAIT_ABANDONED (специфическое значение, возвращаемое в случае завершения потока, владеющего мьютексом), WAIT_OBJECT_0 (объект получил сигнальное состояние - в этом случае функция сама переводит его в несигнальное, а для семафора наращивает счётчик числа занятых ресурсов), WAIT_TIMEOUT (функция вышла по таймауту).
Код:
DWORD WaitForSingleObject(
HANDLE hHandl e, //Описатель объекта ядра, сигнальное состояние которого нас интересует
DWORD dwMilliseconds //Таймаут, по истечению которого пре рвать ожидание
);

Параметры функции:
dwMilliseconds - здесь можно указать любой необходимый таймаут, кроме того, если указать 0, функция вернёт потоку управление сразу (таким образом можно проверить состояние объекта), а если указать константу INFINITE, функция не будет учитывать время и будет ждать только сигнального состояния объекта ядра.
Более подробную информацию можно получить в MSDN.
Нам нужно вызывать её внутри потока при каждой итерации вот так:
WaitForSingleObject (hEvent, INFINITE)
И, наконец, нам необходимо созадавать потоки, которые будут рисовать. Для этого используем CreateThread.
Эта функция создаёт поток внутри адресного пространства текущего процесса. Возвращает описатель созданного потока. Функция полезна, когда, например, нужно выполнять какие-то действия в оконном приложении, но не отключать при этом его интерфейс. В общем случае поток начинает работу сразу после вызова этой функции, и все действия, которые он выполняет, не мешают работе программы.
Код:
HANDLE CreateThread(
LPSECURITY_ATTRIBUTES lpThreadAttributes, //Аттрибуты защиты
SIZE_T dwStackSize, //Размер стека потока (если указать 0, то берётся по умолчанию)
LPTHREAD_START_ROUTINE lpStartAddress, //Адрес стартовой функции
LPVOID lpParameter, //Параметр для передачи потоку
DWORD dwCreationFlags, //Служебные флаги
LPDWORD lpThreadId //ID потока
);

Параметры функции:
lpStartAddress - указатель на стартовую функцию потока (т.е. её название), которую надо объявить внутри приложения. Она должна иметь определённый вид:
Код:
DWORD WINAPI ThreadProc( //Имя функции может быть произвольным 
LPVOID lpParameter
);

lpParameter - параметр, передаваемый в стартовую функцию потока. Если потоку необходимо передать несколько параметров, следует либо использовать глобальные переменные, либо объявлять структуру со всеми необходимыми данными и передавать её.
dwCreationFlags - в основном этот параметр используется для того, чтобы обозначить, следует ли запустить поток сразу после создания или по вызову функции ResumeThread (в первом случае в параметре можно передать 0, во втором - флаг CREATE_SUSPENDED).
lpThreadId - возвращаемый п араметр - id потока, который иногда может быть полезен (например, если потоку будет посылаться сообщение). Если id не нужен, можно передать NULL.
Более подробную информацию можно получить в MSDN.
Мы будем создавать потоки в цикле так:
CloseHandle(CreateThread(NULL, 0, WorkThread, (void*)obj[i], 0, &dwID));
CloseHandle пишем, чтобы описатель сразу закрылся, потому что мы не будем им пользоваться (сам поток при это не будет завершён, закрывается только handle).

Рисовать будем разноцветные квадраты на Image. Всё остальное должно быть ясно из комментариев.
Удачи!

Приложение:

-----
Эта история - не для истории, понимаешь?

Ответ отправил: Киселёва Алёна aka Verena (Профессор)
Ответ отправлен: 15.02.2011, 16:55
Номер ответа: 265877
Россия, Москва
Адрес: Москва, Солнцево
Адрес сайта: Творчество, цитаты, события.
ICQ # 230360822

Вам помог ответ? Пожалуйста, поблагодарите эксперта за это!
Как сказать этому эксперту "спасибо"?
  • Отправить SMS #thank 265877 на номер 1151 (Россия) | Еще номера »
  • Отправить WebMoney:


  • Оценить выпуск »
    Нам очень важно Ваше мнение об этом выпуске рассылки!

    Задать вопрос экспертам этой рассылки »

    Скажите "спасибо" эксперту, который помог Вам!

    Отправьте СМС-сообщение с тестом #thank НОМЕР_ОТВЕТА
    на короткий номер 1151 (Россия)

    Номер ответа и конкретный текст СМС указан внизу каждого ответа.

    Полный список номеров »

    * Стоимость одного СМС-сообщения от 7.15 руб. и зависит от оператора сотовой связи. (полный список тарифов)
    ** При ошибочном вводе номера ответа или текста #thank услуга считается оказанной, денежные средства не возвращаются.
    *** Сумма выплаты эксперту-автору ответа расчитывается из суммы перечислений на портал от биллинговой компании.



    В избранное