Создание нити в WFX плагине

Только для тех, кто пишет плагины под Total Commander. Обмен опытом, решение проблем.

Модераторы: Avada, CaptainFlint, Nik, d-view, Моторокер

Ответить
Аватара пользователя
Xerx
Сообщения: 8
Зарегистрирован: Пн янв 29, 2007 18:05
Откуда: Калуга

Создание нити в WFX плагине

Сообщение Xerx »

Не могу добиться создания отдельного потока на все время работ плагина. Т.е. поток должен создаваться при FsInit() и завершаться при выгрузке плагина из памяти. Проблема в том, что после завершения работы FsInit() поток завершает свою работу (вроде бы). В чем дело и как добиться работы потока?

Урезаный вариант:

Код: Выделить всё

function FsInit();
begin
// стандартная инициализация
// создаю поток
    ThreadHandle := CreateThread(nil, 0, @MyThreadProc, nil, 0, thID);
// некая задержка, например sleep() или MessageBox()
// ....

// после окночания задержки и выхода из FSInit() поток прекращает работу.

	Result := 0;
end;
В реализации кода потока и его создании ошибок нет (я на этом как говорится "собаку съел"). Скорее всего происходит смена контекста или выгрузка DLL(?). Так в чем же дело?

Жду любых советов и предложений. На любом ЯП (данный пример, дкмаю, понятен всем).
Goth with us
Аватара пользователя
Maximus
Сообщения: 927
Зарегистрирован: Чт апр 07, 2005 10:51
Откуда: Украина, Кировоградская обл., г. Знаменка
Контактная информация:

Сообщение Maximus »

Скорее всего происходит смена контекста или выгрузка DLL(?).
Выгрузка DLL не происходит. Мне показалось, что Total выгружает их только по cm_UnloadPlugins.
TC Plugins Manager говорит, что они остаются загруженными.
Аватара пользователя
Xerx
Сообщения: 8
Зарегистрирован: Пн янв 29, 2007 18:05
Откуда: Калуга

Сообщение Xerx »

А тогда в чем дело? Почему поток завершает работу? Ведь он запускается в контексте самого Командера. Получается, что для отдельного потока придется втихую запускать внешнее приложение (или вообще драйвер процессом грузить) и обращаться к нему из плагина? Или все-таки можно запускать поток каким-либо образом???
Goth with us
Аватара пользователя
D1P
Сообщения: 2987
Зарегистрирован: Пн дек 20, 2004 18:30
Откуда: Тбилиси
Контактная информация:

Сообщение D1P »

Проблема, как любят говорить связисты, "на вашей стороне". Вот такой бесхистростный код

Код: Выделить всё

Procedure MyThreadProc;
var
i:LongInt;
Begin
i:=0;
While True do
 begin
 SetWindowText(FindWindow ('TTOTAL_CMD',nil),pchar(IntToStr(i)));
 sleep (1000);
 inc (i);
 end;
End;

function FsInit(PluginNr:integer;pProgressProc:tProgressProc;pLogProc:tLogProc;
 pRequestProc:tRequestProc):integer; stdcall;
Begin
CreateThread(nil, 0, @MyThreadProc, nil, 0, thID);
MessageBox (FindWindow ('TTOTAL_CMD',nil),'Поток создан','',0);
End;
у меня работает великолепно.
Сначала грешил, что какие-то используемые переменные могли быть обьявлены локально - но нет, как их не обьявляй, всё работает.
Аватара пользователя
Xerx
Сообщения: 8
Зарегистрирован: Пн янв 29, 2007 18:05
Откуда: Калуга

Сообщение Xerx »

Вопрос админам: А ГДЕ КОНЕЦ ЭТОЙ ВЕТКИ? ТУТ ЕЩЕ НЕСКОЛЬКО СООБЩЕНИЙ БЫЛО! ЕЩЕ ДНЕМ БЫЛИ!!! ЧТО ЗА ГЛЮКИ!
Goth with us
Аватара пользователя
D1P
Сообщения: 2987
Зарегистрирован: Пн дек 20, 2004 18:30
Откуда: Тбилиси
Контактная информация:

Сообщение D1P »

Пипец... По ходу какие-то работы на сайте - на wincmd.ru тоже "откат" произошёл (я страницу плагина обновлял, потом захожу - опять всё старое).
К счастью я сохранил часть ветки на винте, инфа пригодится для TCKB. Ссылка: http://super.wincmd.ru/_tmp/thread.rar
Аватара пользователя
Xerx
Сообщения: 8
Зарегистрирован: Пн янв 29, 2007 18:05
Откуда: Калуга

Сообщение Xerx »

Эх, конечно кое-что восстановилось, но не все... Подожду. если не востановят, напиху снова на чем остановился.
Goth with us
Аватара пользователя
Xerx
Сообщения: 8
Зарегистрирован: Пн янв 29, 2007 18:05
Откуда: Калуга

Сообщение Xerx »

Не восстановили еще. Ну и ладно. Повторюсь, хотя буду краток. Тотал по прежнему вылетает после выгрузки плагина. Я переделал с использованием Mutex'ов и через одно место сделанным потоком. Думал поможет. Но увы. Выложил там же (xerxde.narod.ru/dinc.dpr).

Пробовал отладить в OllyDbg. Выдает следующее:
Module D:\...\DiNC.wfx
New thread with ID 00000460 created
Unload D:\...\DiNC.wfx
Access violation when executing [00E8354E]
Вот и получается, что все дело в том, что после выгрузки DLL, кода в памяти уже нет, а поток пытается выполняться. Моему Тоталу (6.52/6.53) это ОЧЕНЬ не нравится.
Goth with us
Аватара пользователя
D1P
Сообщения: 2987
Зарегистрирован: Пн дек 20, 2004 18:30
Откуда: Тбилиси
Контактная информация:

Сообщение D1P »

Ну я напишу то же, что уже писал:
1) От версии Тотала работа не зависит (проверял на разны).
2) Оба варианта (с мьютексами и без) у меня работают как и задумано.
vserd
Сообщения: 118
Зарегистрирован: Вт апр 26, 2005 16:54

Сообщение vserd »

Xerx
Вот и получается, что все дело в том, что после выгрузки DLL, кода в памяти уже нет, а поток пытается выполняться. Моему Тоталу (6.52/6.53) это ОЧЕНЬ не нравится.
Это не нравится не только тоталу, но и любой программе. Заведи в потоке флаг который будешь проверять в коде потока, и если он установлен, выходить из потока.
Аватара пользователя
Xerx
Сообщения: 8
Зарегистрирован: Пн янв 29, 2007 18:05
Откуда: Калуга

Сообщение Xerx »

vserd писал(а):Xerx
Вот и получается, что все дело в том, что после выгрузки DLL, кода в памяти уже нет, а поток пытается выполняться. Моему Тоталу (6.52/6.53) это ОЧЕНЬ не нравится.
Это не нравится не только тоталу, но и любой программе. Заведи в потоке флаг который будешь проверять в коде потока, и если он установлен, выходить из потока.
Вообще-то в примере так и сделано, правда с небольшим усовершенствованием: отсутствие контексто-зависимой переменной! Так что это уже не работает. Код успевает выполнится после выгрузки библиотеки.
Goth with us
vserd
Сообщения: 118
Зарегистрирован: Вт апр 26, 2005 16:54

Сообщение vserd »

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

В свете того что твой пример и пример D1P у меня не сохранился, то публикуй код заново. :( И делаешь ли ты задержку для того чтобы твой поток успел обработать завершение? (WaitForSingleObject)
Аватара пользователя
Xerx
Сообщения: 8
Зарегистрирован: Пн янв 29, 2007 18:05
Откуда: Калуга

Сообщение Xerx »

Мой пример с мютексами: http://xerxde.narod.ru/dinc.dpr
Значит сделано не правильно, если код успевает выполнится....
Тогда где ошибка?
Goth with us
vserd
Сообщения: 118
Зарегистрирован: Вт апр 26, 2005 16:54

Сообщение vserd »

Xerx
твой код на 6.56 и 7 pb2 выполняется нормально, никаких AV при закрытии тотала нет, при cm_UnloadPlugins тоже нет AV.
Ответить