Вход | Регистрация
    1  2  3  4  5  6   

Решение проблемы 100% загрузки процессора при ожидании транзакции (ВК+перехват DLL)

Ø [romix, 30.05.06 - 15:50]
Решение проблемы 100% загрузки процессора при ожидании транзакции (ВК+перехват DLL)
Я
   romix
 
Модератор
09.04.06 - 00:27
Компонента с исходным кодом (Delphi 6) и тестовой конфигурацией выложена здесь:

http://x-romix.narod.ru/vk_TerminalSleep.rar
   romix
 
Модератор
1 - 09.04.06 - 00:31
Решил посмотреть, что же происходит, когда 1С ожидает блокировку.
Создал простейшую конфу, в которой есть всего один документ.
В модуль проведения вставил Предупреждение, чтобы она останавливалась и все блокировала.

// ******************** 
Процедура ОбработкаПроведения()
    Предупреждение("Имитация длительного проведения.");
КонецПроцедуры
Открываю другую копию той же конфигурации, и пытаюсь создать новый документ.
(или провести старый).

1С в этом случае загружает проц на 100% и крутится в непрерывном цикле, опрашивая время.
   insider
 
2 - 09.04.06 - 00:43
(0) так что делает компонента, я так и не понял?
   romix
 
Модератор
3 - 09.04.06 - 00:44
Софтайсом останавливаю наугад - с большой вероятностью процессор попадает в этот цикл, и я могу пройти его по шагам.

Непрерывно жму F10 - действительно крутится в одном и том же цикле.

Нахожу осмысленные функции, заходя по F8 во вложенные CALL-ы
CALL [KERNEL32!LockFile]//Вызов системной функции LockFile 
TEST EAX, EAX//Проверка на 0 
JNZ 1F10EAD9//Переход не выполняется 
CALL [KERNEL32!GetLastError]//Вызов системной функции GetLastError 
TEST EAX, EAX//Проверка на 0 
JZ 1F10EAD9//Переход не выполняется 
CMP EAX,21//Проверка на код ошибки 21h или 33 - файл заблокирован 
JNZ 1F10EAB8//Переход не выполняется 


(комментарии я добавил сейчас вручную - SoftICE их, конечно же, не показывает).
   romix
 
Модератор
4 - 09.04.06 - 00:45
(2) Устраняет 100% загрузку процессора, когда кто-то проводит документ, а кто-то второй пытается тоже начать его проводить.
   romix
 
Модератор
5 - 09.04.06 - 00:46
(+4) Точнее, когда один юзер проводит документ, а другой пытается создать новый документ или провести другой документ - тогда в терминале (да и не в терминале тоже) все, что называется, встают.
   insider
 
6 - 09.04.06 - 00:46
(4) "устраняет" - вот это не совсем понятно, как она обходит платформу или что она делает (конечно можно исходник посмотреть, но может в двух словах... а то мне SoftIce, увы, ни о чем не говорит)
   romix
 
Модератор
7 - 09.04.06 - 00:49
(6) Короче 1С-ка непрерывно долбится в функцию KERNEL32!LockFile, и пытается заблокировать файл. Программисты забыли вставить вызов sleep(), и поэтому при многопользовательской работе в 1С включаются тормоза.
   romix
 
Модератор
8 - 09.04.06 - 00:50
Я перехватываю системный вызов GetLastError - возврат последнего кода ошибки. Если он равен 33 (21h), то я включаю паузу на указанное (при вызове внешней компоненты) количество миллисекунд.
   insider
 
9 - 09.04.06 - 00:50
(7) ага, понял, а ты этот вызов обходишь?
   insider
 
10 - 09.04.06 - 00:50
+9 все, уже прочитал
   romix
 
Модератор
11 - 09.04.06 - 00:52
Я взял этот код из дампа (см. выше):
CMP EAX,21//Проверка на код ошибки 21h или 33 - файл заблокирован  
Код ошибки 33 MSDN расшифровывает так:
33 The process cannot access the file because another process has locked a portion of the file. ERROR_LOCK_VIOLATION
   romix
 
Модератор
12 - 09.04.06 - 00:53
Инициализация компоненты в коде 1С:
Процедура ПриНачалеРаботыСистемы()
    ЗагрузитьВнешнююКомпоненту(КаталогИБ()+"..\DLL\TerminalSleep.dll");
    Tsleep=СоздатьОбъект("Addin.TerminalSleep");
    Tsleep.УстановитьПаузуПриБлокировке(1000);
КонецПроцедуры   // ПриНачалеРаботыСистемы 

   insider
 
13 - 09.04.06 - 00:55
(12) т.е. проверка "проведенности" будет производиться не в вечном цикле, а с интервалом 1с, так?
   romix
 
Модератор
14 - 09.04.06 - 00:59
(13) Короче, если кто-то другой проводит документ, то ты не можешь провести свой документ, и не можешь создать новый документ - 1С-ка ждет в цикле, пока другой пользователь не освободит таблицу. Я вставляю паузы sleep, которые не потребляют процессорного времени. Получается, что ожидание происходит с минимальной загрузкой проца и сети.
   insider
 
15 - 09.04.06 - 01:01
(14) спасибо, дошло :)
   Olm
 
18 - 09.04.06 - 01:09
по ссылке (0) есть исходники и пример, но нет самой компоненты TerminalSleep.dll ?
   romix
 
Модератор
20 - 09.04.06 - 01:16
(18) Посмотри сейчас.
   MMF
 
21 - 09.04.06 - 01:19
(20) а ты компоненту свою потестировал в разделенном режиме :-) ?
   Olm
 
22 - 09.04.06 - 01:24
(20) спасибо.
   romix
 
Модератор
23 - 09.04.06 - 01:25
(21) Запускал 2 копии одной конфы на одном компе.
Как еще тестить, пока не придумал.
Блокировку ловит, что видно из отладочной печати.
   romix
 
Модератор
27 - 09.04.06 - 01:41
(26) Загруженность процессора должна упасть до 0. Ты в Диспетчере задач ее смотришь?
   romix
 
Модератор
33 - 09.04.06 - 01:46
(31) Точнее, время ожидания захвата таблиц = 15
   romix
 
Модератор
61 - 09.04.06 - 12:00
(58) А руками у тебя работает подбор, когда ты активизируешь поле, медленно жмешь F4, потом первую букву, потом вторую и т.д.? Вставь паузы sleep между имитациями нажатий, чтобы в замедленном темпе увидеть, а что происходит. Я не помню, есть ли в компоненте (51) этот метод, но в компоненте (0) или здесь http://x-romix.narod.ru/Sleep.rar он точно есть, и его можно поюзать.

(60) Вот думаю для SQL-базы то же самое намутить, там наверняка тоже "порожний" цикл без выполнения пауз, и резко падает производительность...
   romix
 
Модератор
64 - 09.04.06 - 12:12
(63) Ты в обработчике нажатия на кнопку (к примеру) можешь вызвать событие?
Еще вариант - событие попадает в форму справочника, т.к. там есть его обработчик.
   romix
 
Модератор
65 - 09.04.06 - 12:13
Т.е. там можно и вписать продолжение алгоритма, если вызвать событие с особым названием, и в кач. параметра передать нажатую клавишу.
   Может
69 - 09.04.06 - 12:46
в "другом" - ничего нет вообще, чисто. А в обработчик события отладчик не идет
Процедура ПриНажатииКнопкиКлавиатуры(прм_КодКлавиши,прм_Alt,прм_Shift,прм_Ctrl,прм_Символ,прм_ФСО)
   //Сообщить("Код клавиши: "+прм_КодКлавиши);
 
    чКодКлавиши=прм_КодКлавиши;
    стрА=Форма.АктивныйЭлемент();
        Если прм_Ctrl=1 Тогда
            Возврат;
        КонецЕсли;
        
        Если стрА="Улица" Тогда
            Если (ПустоеЗначение(прм_Символ)=0) Тогда
              глСервис.ВнешнееСобытие("FormEx","ВводСимвола",прм_Символ);
            КонецЕсли;
        КонецЕсли;
                                                                               
КонецПроцедуры
вот сюда попадает и все 
глСервис.ВнешнееСобытие("FormEx","ВводСимвола",прм_Символ);
   Maniac
 
Модератор
78 - 09.04.06 - 14:48
это только для дбф ?
   romix
 
Модератор
79 - 09.04.06 - 15:16
(70) Хм, к сожалению нету у меня сегодня xp sp2, завтра посмотрю. На всякий случай, у меня 25 релиз 1С. DBENG32 7.70.0.14
   ildus
 
89 - 09.04.06 - 15:37
(85) а если не через файл, а через сообщения или реестр?
   romix
 
Модератор
90 - 09.04.06 - 15:38
(89) Надо чтобы на разных тачках его было видно. Файл-сервер же :-)
   romix
 
Модератор
91 - 09.04.06 - 15:40
(87) Там короче надо открыть две копии конфы, в одной из них начать проводить документ, а в другой попытаться создать новый док. Без ВК загрузка процессора под 100%, с ВК загрузка = 0 (или близка к 0).
  1  2  3  4  5  6   

Список тем форума
Рекламное место пустует  Рекламное место пустует
2 + 2 = 3.9999999999999999999999999999999...
ВНИМАНИЕ! Если вы потеряли окно ввода сообщения, нажмите Ctrl-F5 или Ctrl-R или кнопку "Обновить" в браузере.
Ветка сдана в архив. Добавление сообщений невозможно.
Но вы можете создать новую ветку и вам обязательно ответят!
Каждый час на Волшебном форуме бывает более 2000 человек.