Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2005.07.31;
Скачать: [xml.tar.bz2];

Вниз

CreateThread и метод класса   Найти похожие ветки 

 
Dust ©   (2005-07-12 12:03) [0]

CreateThread требует получить указатель на функцию и ни в каком виде не хочет принимать метод класса, а именно
procedure TClientSocket.DoLoop();
DoLoop - метод
-----
даже если написать так -
type ptoctype = Procedure();
var prctp : ptoctype;
то
никак не удастя сделать следующее присвоение -
prctp:=DoLoop;

А потому мне пришлось сделать функцию-обёртку, только для вызова одного метода.
Как вы поступали в таких ситуациях? Существует ли другой выход?


 
имя   (2005-07-12 12:07) [1]

Удалено модератором


 
Юрий Зотов ©   (2005-07-12 13:01) [2]

> CreateThread требует получить указатель на функцию и ни в
> каком виде не хочет принимать метод класса

Что и естественно. Методы классов имеют еще один (неявный) параметр (Self) - и, таким образом, получается несовпадение числа параметров.

> Существует ли другой выход?

CreateThread, среди прочих параметров, принимает указатель на данные пользователя, а затем передает его функции потока. Если через этот указатель передать экземпляр объекта, то функция потока сможет его использовать - в том числе, вызывать его методы.

Только тут надо быть аккуратным - вызывать метод объекта из другого потока можно лишь если этот метод потокобезопасен.


 
Alex Konshin ©   (2005-07-12 13:03) [3]

Кстати, используй BeginThread вместо CreateThread.


 
begin...end ©   (2005-07-12 13:04) [4]

> Dust ©   (12.07.05 12:03)

Если параметров нет (и внутри метода не используется Self -- явно или неявно), то всё просто.

type
 TMyForm = class(TForm)
   ...
 private
   procedure M;
 end;

var
 Id, H: Cardinal;

procedure TMyForm.Button1Click(Sender: TObject);
type
 TObjProc = procedure of object;
 TProc = procedure;
var
 OP: TObjProc;
 P: TProc;
begin
 OP := M;
 P := TMethod(OP).Code;
 H := CreateThread(nil, 0, @P, nil, 0, Id);
 Win32Check(H <> 0)
end;

procedure TMyForm.M;
begin
 Application.MessageBox("Ура, товарищи!", "Ура!")
end.


P.S. CreateThread выкинуть. Использовать BeginThread.


 
Digitman ©   (2005-07-12 13:05) [5]


> Dust ©   (12.07.05 12:03)


> требует получить указатель на функцию


если требует именно функцию, какого ж лешего ты пытаешься не функцию, а процедуру (неважно - регулярную или метод класса) "подсунуть" ?


 
isasa ©   (2005-07-12 13:13) [6]

Не принципиально

BeginThread(...)
=
IsMultiThread := TRUE;
CreateThread(...);


 
Alex Konshin ©   (2005-07-12 13:13) [7]

Там не только это.


 
Dust ©   (2005-07-12 13:22) [8]

TO: begin...end, Alex Konshin
ясно, спасибо,,,, но чем лучше BeginThread нежели CreateThread??


 
Dust ©   (2005-07-12 13:24) [9]

какая разница, будет ли этот флаг стоять...


 
begin...end ©   (2005-07-12 13:24) [10]

> Dust ©   (12.07.05 13:22) [8]

См. справку по BeginThread.


 
isasa ©   (2005-07-12 13:42) [11]

>Там не только это.

модуль System

function BeginThread(SecurityAttributes: Pointer; StackSize: LongWord;
 ThreadFunc: TThreadFunc; Parameter: Pointer; CreationFlags: LongWord;
 var ThreadId: LongWord): Integer;
var
 P: PThreadRec;
begin
 New(P);
 P.Func := ThreadFunc;
 P.Parameter := Parameter;
 IsMultiThread := TRUE;
 Result := CreateThread(SecurityAttributes, StackSize, @ThreadWrapper, P,
   CreationFlags, ThreadID);
end;


 
Alex Konshin ©   (2005-07-12 13:42) [12]

Флаг этот важный. Он говорит менеджеру памяти, что нужно использовать синхронизацию.
Помимо этого там инициируется что-то в TLS и, насколько я помню, формируется фрейм на стеке. Иначе будут проблемы при exception.


 
Alex Konshin ©   (2005-07-12 13:44) [13]

isasa ©   (12.07.05 13:42) [11]
Ну и посмотри внимательнее на параметры CreateThread


 
isasa ©   (2005-07-12 13:48) [14]

Кроме
IsMultiThread := TRUE;
все транзит.
Я работаю с  CreateThread и не имею головной боли, что такое ThreadWrapper и где его искать.


 
Alex Konshin ©   (2005-07-12 13:56) [15]

ThreadWrapper там же.
Borland предупредил, а ты волен поступать как хочешь. Только предупреди пож-ста, какие программы ты написал, чтоб случайно не купить.
Кстати, в VC тоже существует обертка для этой API функции (по-моему даже называется так же) по той же причине.


 
isasa ©   (2005-07-12 14:08) [16]

Работает начиная с D4(не сам придумал - Калверт посоветовал :))
Это просто прокладка ( :) ) для обеспечения кросс-платформы,
кроме того

function ThreadWrapper(Parameter: Pointer): Integer; stdcall;

формально, является

function ThreadWrapper(Parameter: PThreadRec): Integer; stdcall;

вот и помни. Неудобно.


 
Alex Konshin ©   (2005-07-12 14:18) [17]

А зачем тебе это помнить? Есть BeginThread, вот и используй.
Сама-то функция CreateThread конечно работает, но она не делает инициализацию нити для использования с RTL Delphi. Как я уже сказал, абсолютно аналогичная ситуация и для других RTL, например, для VC.
И там вовсе не обеспечение кроссплатформенности. Да, там есть понимание платформы, но именно для выполнения требуемых действий на той платформе, а эта функция была и в D3, где linux и не пахло. Там инициализируется FPU и стек. Потенциально неиспользование BeginThread может привести к неверной обработке исключений в нити. Выглядит это так, что при исключении нить просто пропадает, даже чирикнуть не успевает.
Наверно и какие-то эффекты с FPU, но я практически никогда FPU не использую, так что не в курсе, чем это грозит.


 
isasa ©   (2005-07-12 14:34) [18]

Про FPU (floationg point unit - сопроцессор плавающей арифметики) - не понял.
Чего его инициализировать. Он или есть, или его нет.
Соответсвенно код компилируется или с инструкциями для него, или с эмуляцией оных.


 
Alexander Panov ©   (2005-07-12 15:19) [19]

isasa ©   (12.07.05 13:48) [14]
Я работаю с  CreateThread и не имею головной боли,


А почему ты должен ее иметь?

Вот только BeginThread простейшая надстройка и ей пользоваться удобнее тем, что не надо думать о том, что для CreateThread, например, соглашение о передаче параметров StdCall...


 
evvcom ©   (2005-07-12 16:32) [20]


> Про FPU (floationg point unit - сопроцессор плавающей арифметики)
> - не понял.
> Чего его инициализировать. Он или есть, или его нет.

Я нарывался на ошибки сопроцессора в казалось бы безобидных ситуациях типа y := round(x); и получал через раз ошибку деления на ноль. Начал выяснять, оказалось неверно инициализировались служебные регистры FPU. А ты говоришь, чего инициализировать!


 
isasa ©   (2005-07-12 17:18) [21]

А если у меня процессор P4 с гипертрайдингом, где FPU фактически второй процессор, то инициализация его регистров
внутри приложения (процесса) выглядит по меньшей мере странно.


 
ANB ©   (2005-07-12 17:24) [22]


> если требует именно функцию,
- а какя разница (с точки зрения Windows) между процедурой и функцией ?


 
DiamondShark ©   (2005-07-12 18:25) [23]

Кого-то очень сильно клинит...


 
Alex Konshin ©   (2005-07-12 23:22) [24]

isasa ©   (12.07.05 17:18) [21]
А если у меня процессор P4 с гипертрайдингом, где FPU фактически второй процессор, то инициализация его регистров
внутри приложения (процесса) выглядит по меньшей мере странно.

При переключении нитей состояние всех регистров сохраняются-восстанавливаются. Так что как инициализировал, так и будет. HT тут абсолютно ни при чем. Кстати, и для процесса могут сохраняться некие установки, по крайней мере я видел это в исходниках Windows CE, не думаю, что в NT+ сильно иначе.



Страницы: 1 вся ветка

Форум: "Основная";
Текущий архив: 2005.07.31;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.51 MB
Время: 0.038 c
1-1121159860
Uzver32.dll
2005-07-12 13:17
2005.07.31
Массив компонентов без компонентов


3-1118910194
злобная танька
2005-06-16 12:23
2005.07.31
SQL и дата/время


14-1120534822
Starcom
2005-07-05 07:40
2005.07.31
Присоеденительные файлы!


3-1119705538
Хиндельберг
2005-06-25 17:18
2005.07.31
Как умножить данные в таблице


1-1121322454
zamik
2005-07-14 10:27
2005.07.31
Опять вопрос по QReport





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский