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

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

ru
Offline Offline
Сообщений: 13


« : 01-10-2013 09:49 » 

имеется DLL с подобным кодом

Код:
SECTIONS
.SHARDATA   Read Write Shared
EXPORTS
myhook
get_m


Код:
#pragma data_seg(".SHARDATA")
static int m=0;
#pragma data_seg()

LRESULT CALLBACK myhook(int nCode, WPARAM wParam, LPARAM lParam)
{
m++;
return CallNextHookEx(0,nCode,wParam,lParam);
}

int get_m()
{
return m;
}

следует ли учитывать многопоточность? Может ли код хука одновременно быть вызван из разных процессов, куда dll подгружена ?

(мне интуиция подсказывает, что следует, особенно при наличии метода, подобного get_m() )

--------------------------------------

и ещё вопрос - я так понимаю, про размещение в shared переменных типа map можно и не думать, так как там будет практически бесконтрольная работа с кучей

а если я размещу туда вектор с инициализированной длиной (и не буду её менять) - это нормально ?
Код:
static std::vector<int>(10,0);
« Последнее редактирование: 01-10-2013 10:52 от Алексей++ » Записан

Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #1 : 01-10-2013 10:17 » 

Цитата
wParam [in]
Type: WPARAM
Specifies whether the message was sent by the current thread. If the message was sent by the current thread, it is nonzero; otherwise, it is zero.

что значит - "текущим потоком" ?  Или имеется в виду " поток, установивший хук" ?
« Последнее редактирование: 01-10-2013 10:52 от Алексей++ » Записан

Dimka
Деятель
Команда клуба

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

« Ответ #2 : 01-10-2013 11:34 » 

Алексей++, начни с SetWindowsHookEx

Цитата: MSDN
dwThreadId
[in] Specifies the identifier of the thread with which the hook procedure is to be associated. If this parameter is zero, the hook procedure is associated with all existing threads running in the same desktop as the calling thread.

Не знаю точно, что такое "associated with thread", но раз hook обрабатывает системные сообщения, то, надо полагать, он будет дёргаться всякий раз, как в системе кто-то кому-то пошлёт соответствующее сообщение. Т.е. сработает в контексте любого потока, который это сделает.

Поэтому, если тебе надо, заведи именованный мьютекс - один на все процессы - и не парься.
« Последнее редактирование: 01-10-2013 11:42 от Dimka » Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #3 : 01-10-2013 11:54 » 

Dimka, там имеется в виду, что хучится будет именно указанный поток , для глобального хука указывается 0. И это мой случай

ладно, мутекс, так мутекс. А где его лучше расположить - в расшаренных или "личных"  ?  Разница вроде в одном и множестве экземпляров, но мутекст то, он всё равно именованный будет, работать будет в обоих случаях
Записан

resource
Молодой специалист

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

« Ответ #4 : 01-10-2013 18:35 » 

Насчёт самого первого вопроса.
Ты можешь проверить, если напишешь что-то наподобие
Код:
LRESULT CALLBACK myhook(int nCode, WPARAM wParam, LPARAM lParam)
{
    volatile int a = m;
    Sleep(0);
    TRACE("a = %d for Thread %u", a, GetCurrentThreadId());
    m++;
    return CallNextHookEx(0,nCode,wParam,lParam);
}

Реализация трэйсов любая, лишь бы трэйсы шли  Улыбаюсь
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #5 : 03-10-2013 08:28 » 

resource, а каким образом это прояснит ? )  Кстати, трейс в дебаг не идёт, даже еслиотладку запускать средствами студии ))

ну это ладно, разобрались уже вроде
Записан

resource
Молодой специалист

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

« Ответ #6 : 03-10-2013 18:03 » 

Прояснит очень просто. Если обработчик не будет выполняться одновременно в двух разных потоках, то каждое конкретное значение переменной "a", может быть только в одном трэйсе, т.е. не может быть двух и более трэйсов с одним и тем же значением "a". Достаточно поставить хук на какое-нибудь частое событие, например WH_CALLWNDPROC.

Я так полагаю, что "дебаг" это окно в Visual Studio. Хз чего в него там идёт, и как работает твоя реализация трэйсов. Скажу страшную вещь, я энтерпрайзно не использую студию. А вот DbgView и WinDbg отлично показывают, то что я вывожу через тот же OutputDebugString. Но яж не зря сказал, что реализация любая. Т.е. можешь, например, писать в файл, в пайп, в сокет,  да хоть по RPC, лишь бы для твоего случая подходило.
« Последнее редактирование: 03-10-2013 18:09 от resource » Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #7 : 04-10-2013 03:42 » 

resource, наверное, более логично выводить номер потока  )) Попробую в файл
Записан

Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #8 : 04-10-2013 06:16 » 

хм, а правильно ли я понимаю, что расшаренном блоке вообще не должно использоваться выделение на куче (через new или в составе STL) ?  Ведь выделенная память уже не будет принадлежать шаре

то есть, массив у нас по старинке
int m[100];
Записан

resource
Молодой специалист

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

« Ответ #9 : 05-10-2013 10:04 » 

Цитата: Алексей++
более логично выводить номер потока
Лёш, вот во-первых чем тебе ThreadId не номер потока? А во-вторых это вообще значения не имеет (для красоты). Можно вообще выводить
Код:
 TRACE("%d", a);
Этого достаточно.

Насчет динамически выделяемой памяти (хоть из кучи, хоть не из кучи) отвечу по-сишному. Я могу хранить в шаредной секции указатель на любой буфер и динамически выделять под него память. Главное синхронизировать к нему доступ, если он осуществляется одновременно из разных потоков (это мы и хотим выяснить, как я понимаю). Думаю, что и "наплюсить" можно подобным образом.
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #10 : 05-10-2013 13:44 » 

resource, с выделением у меня что-то не так делается, либо я вообще в корне что-то неверно делаю Улыбаюсь Придётся тебя в понедельник помучать вопросами, если ты не против
Записан

resource
Молодой специалист

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

« Ответ #11 : 05-10-2013 16:00 » 

Я никогда не против ) Но имей ввиду, я не плюсач. Про многопоточность и синхронизацию я кое-что знаю (сам себя не похвалишь...), но если речь пойдёт про плюсовые контейнеры, то надеюсь к дискуссии подключится кто-то ещё.
« Последнее редактирование: 05-10-2013 17:46 от resource » Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #12 : 06-10-2013 04:58 » 

resource, да фиг с ними, с контейнерами, тут они, похоже, не помощники. Можешь мне в ЛС скайп закинуть ?
Записан

Dimka
Деятель
Команда клуба

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

« Ответ #13 : 06-10-2013 12:32 » 

Алексей++, разумеется, выделение в куче не годится. Выделяешь кусок памяти - общий. Получаешь на него указатель. Приводишь тип указателя к какой-то структуре с полями и массивами внутри. И эта структура будет картой статического распределения памяти в этом куске по разным переменным. Ну и пользуйся себе. Статические массивы в структуре либо резервируй с запасом по размеру, либо делай хитрый протокол взаимодействия процессов, что один процесс массив забил полностью, сигналит другому, чтобы тот вычитывал и освобождал - в общем, канал получится. Но если передача однанаправленная, может смысл есть как раз канал (pipe) и использовать. Важно, чтобы структура была платформонезависимой - т.е. если с ней работают как 32 так и 64 битные приложения, чтобы у них ни по размерам типов, ни по выравниванию полей не было различий.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #14 : 07-10-2013 03:05 » new

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

Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines