|
|
  |
Структура функций, В чём преимущество ? |
|
|
|
May 4 2014, 19:17
|

Универсальный солдатик
     
Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362

|
Цитата(Tiro @ May 4 2014, 22:10)  Вот у Вас есть программно-аппаратный модуль, который программирует таймер, обрабатывает от него прерывания. Он все знает о таймере. Вы его запрограммируете и все. А как узнать, что время, которое Вы заказали, прошло? Надо передать адрес подпрограммы, которая будет вызвана по истечении времени. Это как раз простейший пример "callback" подпрограммы.
P.S. В данном контексте подпрограмма для "обратной связи". Возникло прерывание (событие). Обработчик вызвал некую функцию (она callback?). Все, doom13 дал ссылку. Собственно, я так и думал.
|
|
|
|
|
May 4 2014, 19:38
|
Знающий
   
Группа: Свой
Сообщений: 781
Регистрация: 3-10-04
Из: Санкт-Петербург
Пользователь №: 768

|
Цитата(ViKo @ May 4 2014, 22:17)  Возникло прерывание (событие). Обработчик вызвал некую функцию (она callback?). Выкиньте из головы понятия "события", "функции" применительно к общему контексту выполнения программы. Пользуйтесь нативной понятийной базой. Вот прерывание и подпрограмма - из нативной. А теперь несколько грубых переводов: - настройка callback = подпрограмме А сообщен адрес подпрограммы В для обработки данных, которых подпрограмма А не может обработать - прерывание = аппаратное состояние, обрабатываемое подпрограммой А - обработчик = подпрограмма А - событие = изменилось аппаратное состояние - callback = подпрограмма А вызвала подпрограмму В Не при каждом аппаратном событии модуля А произойдет callback модуля В. Callback модуля В = событие модуля В. Для модуля С все тоже самое. Рекурсивно.
|
|
|
|
|
May 4 2014, 19:48
|

фанат дивана
     
Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684

|
Цитата(ViKo @ May 5 2014, 00:55)  По-вашему, получается, callback - это функция, в которую передали другую функцию в качестве параметра. Так прямо "вызывает"? Может, все таки, возвращается? Разве вызываемая функция не вернется в вызывающую (библиотечную, в вашем примере)? По-моему, callback - это как раз та функция, которую передали. Функция, возвращающаяся назад...? Так они все назад...  Уф... %) Я не понимаю, что вам не понятно. Давайте прямо на примере этой самой функции EnumWindows. Ваша программа хочет получить список всех окон в системе и поэтому вызывает функцию EnumWindows(). Функция EnumWindows() умеет находить все окна в системе. Но что с ними делать дальше, она понятия не имеет. Это знаете вы - вы хотите напечатать названия этих окон. Поэтому вы создаёте специальную функцию - функцию обратного вызова (callback) PrintWindow(), которая печатает название окна, которое передано ей. И передаёте функцию PrintWindow() в качестве параметра при вызове EnumWindows(). Ваша функция PrintWindow() - это как раз и есть callback. Теперь функция EnumWindows() для каждого найденного окна вызовет этот callback. Потом она завершит свою работу, и вернёт управление вашей программе. То есть, у вас в программе есть функция main(), и есть функция PrintWindow(). Вы вызываете из main() библиотечную функцию EnumWindows(PrintWindow). Тогда контроль в вашей программе будет передаваться так: main() - EnumWindows() - PrintWindow() - PrintWindow() - PrintWindow() - PrintWindow()- ... - main(). Что касаемо названия "callback". Вызов из пользовательской программы библиотечной функции - это нормальный вызов. Вызов наоборот - из библиотечной функции пользовательской функции - обратный вызов. Всё логично
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
|
May 4 2014, 23:54
|

Знающий
   
Группа: Участник
Сообщений: 974
Регистрация: 4-04-08
Из: далека
Пользователь №: 36 467

|
Цитата(AHTOXA @ May 4 2014, 13:43)  Ну хватит уже нести чушь. Вы неправильно понимаете, что такое callback. Вот пример синхронного калбэка: EnumWindowsCallback ВСЕГДА асинхронный, строго говоря. и в этом случае тоже. Смысл в том, что мы передаем другой программе/объекту/кернелу/треду "управление". Что оно будет делать и когда нас позовет неизвестно. И EnumWindows не исключение. Другой вопрос, что вернется функция после вызова каллбэка. Но это чисто применение синхронизейшн примитивов. Точно так же можно позвать функцию передачи данных в сериал порт, передать туда каллбэк функцию, котораю будет сигналить объект, а мы после вызова нашей функции будем ждать этот обьект. И абсолютно асинхронный каллбэк "вдруг стал синхронным". На самом деле в обоих случаях сам каллбэк был асинхронным. Иначе это уже не будет то, что называют каллбэком Цитата(ViKo @ May 4 2014, 14:06)  То есть, события, асинхронность - не при чем? Просто передаем один из возможных методов (функций)? И что же тогда означает "callback"? Именно асинхронность и события причем. Вот я, например, написал библиотеку для связи через ethernet. Периодически она будет передавать данные из сети пользователю. Когда - неизвестно. Как пользователю получить данные? Типичное применение - при инициализации моей библиотеки он передает мне callback функцию, которую я буду звать, когда чтото прийдет. Цитата(AHTOXA @ May 4 2014, 14:48)  Что касаемо названия "callback". Вызов из пользовательской программы библиотечной функции - это нормальный вызов. Вызов наоборот - из библиотечной функции пользовательской функции - обратный вызов. Всё логично  Необязательно. Не всякая функция, которую вызывают через пойнтер, является каллбэком
--------------------
Верить нельзя никому, даже себе. Мне - можно.
|
|
|
|
|
May 5 2014, 05:26
|

фанат дивана
     
Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684

|
Цитата(A. Fig Lee @ May 5 2014, 05:54)  Callback ВСЕГДА асинхронный, строго говоря. и в этом случае тоже. Неверно. Асинхронный - это кода управление вернулось после вызова, а вызовы callback-а продолжают поступать. В данном случае callback именно синхронный. Точно так же, как и в примере с сортировкой qsort. Ещё раз повторяю: callback и асинхронность - вещи ортогональные.
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
|
May 5 2014, 12:12
|

Универсальный солдатик
     
Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362

|
Цитата(XVR @ May 5 2014, 14:38)  2 ТС - вы смешали в одну кучу назначение callback'ов, их реализацию и смысл самого понятия callback. Все 3 части могут иметь разные реализации и/или толкования, и не надо их путать  Вообще-то, это не ТС смешал.  Там уже все закончилось. Я набрел на тему поиском по слову callback. Думал, могу получить короткий точный ответ. А вы своим сообщением путаницы добавили.  Дайте уж и свое толкование всех частей.
|
|
|
|
|
May 5 2014, 12:45
|

Знающий
   
Группа: Участник
Сообщений: 974
Регистрация: 4-04-08
Из: далека
Пользователь №: 36 467

|
Цитата(AHTOXA @ May 5 2014, 00:26)  Неверно. Асинхронный - это кода управление вернулось после вызова, а вызовы callback-а продолжают поступать. В данном случае callback именно синхронный. Точно так же, как и в примере с сортировкой qsort. Ещё раз повторяю: callback и асинхронность - вещи ортогональные. Нет. Он синхронный только потому что его принудительно синхронизировали. Такими вещами как WaitForSingleObject. То, что вы этого не видите, ничего не значит. Любой каллбэк можно засинхронизировать по отношению к вызывающей функции. Но он как был по сути асинхронным, так как мы не имеем никакого контроля над самим каллбэком, так и остался.
--------------------
Верить нельзя никому, даже себе. Мне - можно.
|
|
|
|
|
May 5 2014, 13:39
|
Гуру
     
Группа: Свой
Сообщений: 3 123
Регистрация: 7-04-07
Из: Химки
Пользователь №: 26 847

|
Цитата(ViKo @ May 5 2014, 16:12)  Дайте уж и свое толкование всех частей. Их уже давали тут, но все в куче Если хотите, то вот - Понятие callback'а - дословно 'обратный вызов'. Точнее это оповещение о каком то событии, которое (оповещение) передает тот, у кого это событие произошло, тому, кто этот самый callback установил. В установке callback'а обязательно присутствуют 2 стороны - одна предоставляет сам callback, вторая его активирует в соответствующий момент. Назначение callback'а - может быть самое разное. Это может быть сигнализация о наступлении аппаратного прерывания, сигнализация о срабатывании программного события (WaitForSingleObject), доставка пользовательского event'а (в различных оконных системах), наступление каких то программно/аппаратных событий (исчерпании кольцевого DMA буфера например) Реализация callback'а - указатель на функцию callback'а, переданный в виде параметра в вызов интерфейсной процедуры. Тот же самый указатель, помещенный в какой то структуре в памяти. Виртуальные функции в С++. Примитив ОС (HANDLE от CreateEvent).
|
|
|
|
|
May 5 2014, 16:58
|

фанат дивана
     
Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684

|
Цитата(A. Fig Lee @ May 5 2014, 18:45)  Нет. Он синхронный только потому что его принудительно синхронизировали. Такими вещами как WaitForSingleObject. То, что вы этого не видите, ничего не значит. Любой каллбэк можно засинхронизировать по отношению к вызывающей функции. Если его засинхронизировали, то он синхронный. Если он синхронный, то он совершенно точно не асинхронный. По-моему, это очевидно. ЗЫ. Задание на дом - поищите скрытую асинхронность (такие вещи как WaitForSingleObject) в реализации callback-ов в функции qsort() например.
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
|
May 5 2014, 18:22
|
Местный
  
Группа: Участник
Сообщений: 421
Регистрация: 2-01-08
Пользователь №: 33 778

|
Цитата(aaarrr @ May 3 2014, 14:29)  Хорошо, напишем так: это функция, вызываемая по событию, и заранее не определенная для вызывающего её (условно "библиотечного") кода. А это как называется? Или где здесь событие? Код void fooInit(struct foo *x, void * (*dmalloc) (size_t sz)) { lowInit(x->ba1); ... x->dma1 = dmalloc(1024 * x->szE); x->dma2 = dmalloc(1024 * x->szE); ... irqEnable(x->irqN); }
... fooInit(&ifc1, dmalloc_seg1); fooInit(&ifc2, dmalloc_seg2); Попытаюсь дать свое опрделение callback функции. Начать надо с того, что подразумевается разделение кода на некие уровни, слои абстракции. Каждый слой может использовать только более нижние слои для реализации своих функций. Каждый такой вызов это прямой вызов callforward. Если где-то надо вызвать код более высого слоя, то это обратный вызов callback. Самый известный пример, доставка событий. А самая известная реализация в C языках это указатель на функцию.
Сообщение отредактировал amaora - May 5 2014, 18:25
|
|
|
|
|
  |
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0
|
|
|