Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2005.06.14;
Скачать: CL | DM;

Вниз

Как сделать чтобы форма реагировала во время работы потоков.   Найти похожие ветки 

 
Alex Konshin ©   (2005-05-27 14:14) [40]

Digitman ©   (27.05.05 14:10) [39]
> Alex Konshin ©   (27.05.05 14:04) [38]
ну эт ты загнул)
прерваны они, конечно, м.б., но только не одиночные (т.е. если используется REPХХ-префикс)

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


 
Digitman ©   (2005-05-27 14:21) [41]


> Alex Konshin ©   (27.05.05 14:14) [40]


> значения в регистрах должны как-то оказаться


ну мы ж - конкретно о LODS/STOS/MOVS/CMPS)... а не об иных инструкциях, которые нужны для начальной инициализации используемых цеп.инструкциями регистров


 
Anatoly Podgoretsky ©   (2005-05-27 14:21) [42]

Digitman ©   (27.05.05 14:10) [39]
А это уже означает агрегатные, они к тому же еще и чрезвычайно медленные на современных процессорах. Хорощо что Борланд не купился на них в своем компиляторе.


 
Alex Konshin ©   (2005-05-27 14:36) [43]

Digitman ©   (27.05.05 14:21) [41]
ну мы ж - конкретно о LODS/STOS/MOVS/CMPS)... а не об иных инструкциях, которые нужны для начальной инициализации используемых цеп.инструкциями регистров

В таком случае почти все инструкции - атомарные. Кроме тех, что с двойным обращением к памяти (к некоторым из них и можно применить lock). Только Delphi-то от этого какой прок?
Кстати, movs с двойным обращением, нужно еще посмотреть, что там про нее написано, скорее всего это и не атомарная инструкция вовсе, неясно, что же будет при паралельном обращении другим процессором к ячейке, в которую мы пишем.


 
Digitman ©   (2005-05-27 14:43) [44]


> Anatoly Podgoretsky ©   (27.05.05 14:21) [42]
> Хорощо что Борланд
> не купился на них в своем компиляторе


в смысле ?


 
GuAV ©   (2005-05-27 22:11) [45]

Anatoly Podgoretsky ©   (27.05.05 14:21) [42]
не купился на них


?

var
 A, B: array[Byte] of Byte;
 C, D: array[0..19] of Byte;

A := B;
lea esi,[esp+$00000100]
mov edi,esp
mov ecx,$00000040
rep movsd

C := D;
lea esi,[esp+$00000214]
lea edi,[esp+$00000200]
movsd
movsd
movsd
movsd
movsd


 
Defunct ©   (2005-05-28 00:02) [46]

GuAV ©   (27.05.05 22:11) [45]

Все иногда ошибаются.

Насчет атомарности mov, и строковых операций movs, lods, stos, scas, cmps:

склоняюсь к тому, что все эти инструкции являются атомарными в чистом виде. Так как не используется метод чтение-модификация-запись.


 
Verg ©   (2005-05-28 07:21) [47]

В многопроцессорных системах разделение шины арбитром происходит между циклами шины.
Сколько циклов шины займет атомарная на первый взгляд операция mov [ebx], eax  если, например, ebx = 0x789FF ?


 
isasa ©   (2005-05-28 10:39) [48]

procedure TMyThread1.DoWork;
begin
Form1.CheckBox.Checked := True;
end;
Ну соотвественно второй
Form1.CheckBox.Checked := False;

В многопоточном варианте эта конструкция не есть гуд.
Надо использовать  SendMessage.


 
-=XP=- ©   (2005-05-28 10:48) [49]

В многопоточном варианте эта конструкция не есть гуд.
Надо использовать  SendMessage.


Можете пояснить?


 
isasa ©   (2005-05-28 11:17) [50]

Опять же. Вот фрагмент из Делф. хелп файла
($DELPHI)\Common Files\Borland Shared\MSHelp\WIN32.HLP

The SendMessage function sends the specified message to a window or windows. The function calls the window procedure for the specified window and does not return until the window procedure has processed the message. The PostMessage function, in contrast, posts a message to a thread"s message queue and returns immediately.

LRESULT SendMessage(

   HWND hWnd, // handle of destination window
   UINT Msg, // message to send
   WPARAM wParam, // first message parameter
   LPARAM lParam  // second message parameter
  );


Parameters

hWnd

Identifies the window whose window procedure will receive the message. If this parameter is HWND_BROADCAST, the message is sent to all top-level windows in the system, including disabled or invisible unowned windows, overlapped windows, and pop-up windows; but the message is not sent to child windows.

Msg

Specifies the message to be sent.

wParam

Specifies additional message-specific information.

lParam

Specifies additional message-specific information.



Return Values

The return value specifies the result of the message processing and depends on the message sent.

Где "handle of destination window" Form.Handle

Классики не рекомендуют использовать прямую адресацию между потоками. Жотя здесь маршаллинг не нужен.
Кстати, меня гложет сомнения, что все это работает отдельными потоками.

Я пользуюсь функцией CreateThread (и не заморачиваюсь на TThread)

 TmainForm = class(TForm)
...
 private
   aThreads : aTHandle;
   aThreadIDs : aDWORD;
   activeThreads : integer;
   procedure WMCopyData(var wMsg : TWMCopyData); message WM_COPYDATA;
 public
   cURL : TCheckURL;
 end;
...
procedure TmainForm.WMCopyData(var wMsg: TWMCopyData);
var wmData : PCopyDataStruct;
   mpURL : pURLs;
begin
 wmData:=wMsg.CopyDataStruct;
 mpURL:=wmData.lpData;
...
....
 cURL.msgWnd:=self.Handle;
 hThread:=CreateThread(nil, 0, @CheckURL, @cURL, 0, ThreadID);
 if hThread=0 then Header.Lines.Add("No Thread!");

где поток описан как

 TCheckURL = record
   msgWnd : HWND;
...
 end;
 pURLs = ^TCheckURL;

function CheckURL(p : pointer) : longint;   stdcall;
var cURL : pURLs;
begin
 Result:=0;
 cURL:=pURLs(p);

...
 SendMessage(cURL^.msgWnd, WM_COPYDATA, 0, longint(@wmData));
....
end;

stdcall обязательно.


 
-=XP=- ©   (2005-05-28 11:24) [51]

Классики не рекомендуют использовать прямую адресацию между потоками.

Потоки одного процесса выполняются в едином адресном пространстве. Поэтому с этим проблем нет.

SendMessage отправляет сообщение не в очередь, а напрямую в оконную процедуру. Поэтому, без синхронизации потоков, эта функция использоваться не может. Для подобного решения можно посоветовать использовать PostMessage.

Но если используется Synchronize(), то приведенный автором вопроса код - совершенно корректный. Зачем в данном случае использовать WinAPI, если можно воспользоваться VCL?


 
isasa ©   (2005-05-28 11:30) [52]

Немного прокоментирую.
Собственно вызов потока
 cURL.msgWnd:=self.Handle; // Это хандлер формы куда передается сообщение
 hThread:=CreateThread(nil, 0, @CheckURL, @cURL, 0, ThreadID);

это структура, которая передается потоку
 TCheckURL = record
   msgWnd : HWND;
   mainForm: TForm;
...
 end;
 pURLs = ^TCheckURL;

в нее, например, можно пихнуть все, что угодно, даже TForm.
Но, опять же, напомню прямую адресацию не использовать - дурной тон.

Хотя из потока

mainForm.myControl.Text:="Оба-на!";

работать будет.


 
isasa ©   (2005-05-28 11:40) [53]

По поводу VCL и потоков см. Ч.Калверта

The WM_COPYDATA message is sent when an application passes data to another application.

Remarks

An application must use the SendMessage function to send this message, not the PostMessage function.


поэтому SendMessage


 
-=XP=- ©   (2005-05-28 11:41) [54]

Но, опять же, напомню прямую адресацию не использовать - дурной тон.

Я так понимаю, в контексте сказанного Вами, это опечатка?
Объясните, в чем же проявляется "дурной тон" в данном случае?
Какие последствия могут возникнуть в результате прямого обращения к объектам VCL в данном примере (с использованием Synchronize)? Обращение идет в контексте основного потока. Адресное пространство - одно и то же. RTTI присутствует и непротиворечива.
Что Вы имеете в виду, говоря "дурной тон"?

P.S. Напомню, что мы сечас все же говорим о TThread, а не о работе с потоками напрямую через WinAPI.


 
isasa ©   (2005-05-28 11:53) [55]

Не поленился, нашел.
Ссылка правда старовата , но
Ч.Калверт. Энциклопедия пользователя. стр.134.
пример один к одному,
коментарии
".. главный поток приложения вообще не сможет выполняться, пока не завершится вызов функции Synchronize


 
-=XP=- ©   (2005-05-28 12:06) [56]

главный поток приложения вообще не сможет выполняться, пока не завершится вызов функции Synchronize

Неверная формулировка.
Главный поток продолжает выполняться. В нем выполняется метод, переданный в качестве аргумента методу Synchronize. Работа метода Synchronize заключается в том, что он передает в главный поток сообщение с указателем на метод, переданный в качестве аргумента, и ожидает окончания обработки этого сообщения, то-есть, вторичный поток останавливается. По факту получения сообщения, главный поток выполняет код переданного в качестве параметра метода в совем собственном контексте. По окончании выполнения этого метода, главный поток продолжает выполняться дальше, и вторичный поток возвращается к своему выполнению.

P.S. Хотя, говорить о том, какой поток останавливается - не совсем корректно. На самом деле, два потока синхронизируются, и выполняется один программный код на двоих. Хотя, все же, я склонен утверждать, что останавливается вторичный поток, отдавая метод на выполнение в контексте главного потока.


 
isasa ©   (2005-05-28 12:22) [57]

:))))))))
Все претензии к переводчику (П.А.Матлаш гл.1-8)

А если серьезно, в данном случае, проще через API.
По поводу синхронизации.
В данном примере - реакции одного потока на действия другого (исключая главный поток), я не вижу.


 
-=XP=- ©   (2005-05-28 12:38) [58]

Вот "цитаты" из VCL:

procedure TThread.Synchronize(Method: TThreadMethod);
begin
 ...
 FMethod := Method;
 SyncProc.Thread := Self;
 SyncList.Add(@SyncProc); // Добавляем наш метод, который мы хотим выполнить в контексте основного потока, в список ("В очередь, сукины дети, в очередь!" (С))
 ...
 WaitForSingleObject(SyncProc.Signal, INFINITE); // И ждем окончания выполнения метода в контексте основного потока ("Ждут, не дождутся, когда ж наши мамы вернуться " (С))
 ...
end;

procedure TApplication.WndProc(var Message: TMessage);
begin
...
 case Message.Msg of
   ...
   WM_NULL: CheckSynchronize;  //А вот тут основной поток приступает к обработке запросов от вторичных потоков
...
end;

function CheckSynchronize: Boolean;
begin
...
 while SyncList.Count > 0 do // Проходим список потоков, ожидающих выполнения своих методов в контексте основного потока
 begin
   SyncProc := SyncList[0]; // Берем метод для первого ожидающего потока
   SyncList.Delete(0);
   ...
   SyncProc.Thread.FMethod; // А тут и выполнение нашего метода в контексте основного потока
   ...
   SetEvent(SyncProc.signal); // А теперь говорим ожидающему вторичному потоку, что он может продолжить выполнение
 end;
...
end;


Я так думаю, к правильности кода из папки Source\VCL претензий нет? :)

А если серьезно, в данном случае, проще через API.
Ну, это кому как. :)

В данном примере - реакции одного потока на действия другого (исключая главный поток), я не вижу
Они синхронизируются через главный поток (см. код, приведенный выше) - то есть, оба становятся в очередь и ждут. В этом и заключается синхронизация.


 
-=XP=- ©   (2005-05-28 12:41) [59]

P.S. Прошу прощения, в комментариях "Добавляем наш метод", "Берем метод для первого ожидающего потока" допустил ошибки в описании. На самом деле их надо читать как "Добавляем наш поток" и "Берем первый поток из списка ожидающих потоков".


 
VMcL ©   (2005-05-28 12:48) [60]

>>isasa ©   (28.05.05 11:17) [50]

>Я пользуюсь функцией CreateThread (и не заморачиваюсь на TThread)

Пользоваться функцией CreateThread некошерно. Следует пользоваться функцией BeginThread.


 
VMcL ©   (2005-05-28 12:51) [61]

>>-=XP=- ©   (28.05.05 12:38) [58]

Кстати, так Borland сделал начиная с D6. В D5 было несколько по-другому.


 
Defunct ©   (2005-05-28 19:10) [62]

Verg ©   (28.05.05 07:21) [47]

Один:

Addr Launch (from ebx)
Data (from eax)
W



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

Текущий архив: 2005.06.14;
Скачать: CL | DM;

Наверх




Память: 0.59 MB
Время: 0.051 c
14-1117089702
КаПиБаРа
2005-05-26 10:41
2005.06.14
Двойные стандарты


9-1110736076
Falcon(TFsoft)
2005-03-13 20:47
2005.06.14
My first game....


14-1117114879
lookin
2005-05-26 17:41
2005.06.14
Оформление сайта


3-1115290541
-=XP=-
2005-05-05 14:55
2005.06.14
Получить список полей, их типы и индексы при помощи SQL


14-1117021788
Андрей Жук
2005-05-25 15:49
2005.06.14
Вопрос по С++





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский