Страница 1 из 1

Как создать и убить Thread средствами WinAPI

Добавлено: 19 Ноябрь 2008, 15:57
han
Требуется используя CreateThread создать поток, что-бы затем можно было его в любой момент убить с помощью TerminateThread. Проблема в том, что процедура создаваемого потока должна быть объявлена такой-вот конструкцией
DWORD WINAPI ThreadProc(
[in] LPVOID lpParameter
);

И как можно эту конструкцию интерпретировать в Clarion-e. Др. сл. как оформить процедуру в ссответсвиии с требовании Windows CallBack
Заранее всем благодарен.

Re: Как создать и убить Thread средствами WinAPI

Добавлено: 20 Ноябрь 2008, 2:07
StillZero
примеры

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

   MAP
CFC_hook:MessageProc PROCEDURE(LONG inCode,ULONG wParam,LONG lParam),LONG,[b]PASCAL[/b]
WatchFileProc   PROCEDURE(LONG),LONG,[b]PASCAL[/b]
   END
в твоем случае

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

MAP
   ThreadProc (LONG lpParameter),LONG,PASCAL
END
CreateThread также описать с LONG и передавать ThreadProc как ADDRESS(ThreadProc)
в ThreadProc будет передаваться адрес lpParameter, получать данные из него по memcpy

Re: Как создать и убить Thread средствами WinAPI

Добавлено: 20 Ноябрь 2008, 2:13
StillZero
вот нашел какой то стародавний пример с этой хней

Re: Как создать и убить Thread средствами WinAPI

Добавлено: 24 Сентябрь 2010, 12:34
StillZero

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

HANDLE CreateThread(
  LPSECURITY_ATTRIBUTES lpThreadAttributes,
  SIZE_T dwStackSize,
  LPTHREAD_START_ROUTINE lpStartAddress,
  LPVOID lpParameter,
  DWORD dwCreationFlags,
  LPDWORD lpThreadId
);
здесь интересует lpStartAddress, где говорится, что это ThreadProc, то бишь процедура потока
Про ThreadProc написано следующее

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

DWORD WINAPI ThreadProc(
  LPVOID lpParameter
);
в кларе описываем так

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

 Map
   WatchFileProc(long lpParameter),long,pascal
 end
Здесь интересен только момент PASCAL

Далее эту процедуру надо реализовать.
Из прототипа видно, что надо передавать какой то параметр по адресу. ЭТот параметр передается опять таки через CreateThread (четвертым параметром), т.е.

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

CreateThread(0,256,address(WatchFileProc),address(ПАРАМЕТР),1,ThreadID)
по адресу можно передать много чего, в примере передается группа, которая разбирается топорным копированием по memcpy

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

memcpy(address(locWaitStruct),lpWaitStruct,size(WaitStruct))

Re: Как создать и убить Thread средствами WinAPI

Добавлено: 24 Сентябрь 2010, 15:32
Koss
WatchFileProc - это обычная виндовс бэхейрвором сделатая?

Re: Как создать и убить Thread средствами WinAPI

Добавлено: 24 Сентябрь 2010, 16:14
StillZero
Обычная кларина процедура, имя любое может быть, прототип как описано в MSDN, атрибут PASCAL необходим для всех API

Re: Как создать и убить Thread средствами WinAPI

Добавлено: 24 Сентябрь 2010, 21:56
WadimZapara
это работает

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

Test    PROGRAM
  MAP
    MODULE('Windows')
       CloseHandle(UnSigned Handle), BOOL, Raw,Pascal,DLL(TRUE), Proc
       CreateThread(ULong PtrSecurAttr=0, ULong StackSizeInBytes=0, ULong AddrProcThread, ULong PtrToParams=0, |
                    ULong CreationFlags=0, ULong Ptr_ThreadId=0), UnSigned,Pascal,DLL(TRUE)
       TerminateThread(UnSigned hThread, ULong dwExitCode),Signed, RAW,Pascal,DLL(TRUE), Proc
    END
MeProc PROCEDURE(ULong MeParam), Pascal !вызов через CreateThread

  END
h       Unsigned  !Handle
tcs     CString(1024),Static
  CODE
   tcs = 'что-то абрабкадабристое'
   h = CreateThread(0, 25000, Address(MeProc), Address(tcs))
  if Message('Основная программа близка к завершению', 'Убить поток?', ICON:Exclamation, 'ДА|НЕТ') = 1 then
     TerminateThread(h, 0)
     CloseHandle(h) ! обязательно
  else
     ! ну не знаю - что хочешь тут
     CloseHandle(h) ! обязательно
  end
  Message('Всё')
  RETURN

!--------------------------------------------------------
MeProc PROCEDURE(ULong MeParam) !вызов через CreateThread
IN_TCS  Group
Addr        ULong(0)
Leng        ULong(1024)
         End
TCS   Group,Over(IN_TCS)
ptr         &CString
         End
  Code
  ! Обрабатываю MeParam, например, то, что по этому адресу
  IN_TCS = MeParam ! настраиваю указатель, длина уже задана=1024
  ! теперь TCS.ptr указывает на строку, адрес которой передан в процедуру
  Message(TCS.ptr) ! выводим "что-то абрабкадабристое"
Return
Остерегаться:
1) если параметр, адрес которого передаётся в процедуру отдельного потока, не STATIC, в связи с постраничной работой с памятью Windows может произойти "Access Violation" ошибка, т.е. переменная может оказаться выгруженной в страничный файл
2) если процедура, где объявлена эта переменная, прекратит свою работу раньше, чем новый поток, а после этого последует в потоке обращение к данной переменной (через её адрес) - будет та же ошибка
- в обоих случаях программа упадёт