Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Использование CreateThread в Delphi


vertal ©   (2004-06-18 15:26:00) 

Я создаю через CreateThread поток в своем процессе , и вручную устанавливаю IsMultiThread в True.Однако в этом потоке я не могу присваивать значение строкам(динамическим).Грубо говоря , когда пишу

Var
 SomeStr,SomeAnotherStr:String;
 ...
Begin
 SomeStr:=SomeAnotherStr;
 ...

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


Тимохов   (2004-06-21 11:17:00) [1]


> vertal ©   (18.06.04 21:45) [15]
В справке сказано , что при присваивании происходит физическое копирование

врете.

супер вешь - object pascal reference (раздел шлатного хелпа). Там есть все о паскале, который лежит в основе дельфи.


vertal   (2004-06-18 21:45:00) [2]

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


Игорь Шевченко   (2004-06-18 21:24:00) [3]


> Я  понял .Это ребята из борланда дооптимизировались


Вряд ли проблема в ребятах из Borland.


vertal   (2004-06-18 20:43:00) [4]

Речь идет о динамических дельфийских строках , о чем я по-моему сразу сказал.В справке сказано , что при присваивании происходит физическое копирование.Чаще всего так и есть.
Я  понял .Это ребята из борланда дооптимизировались, мля.Суть в том , что при присваивании значения строке физически она копируется только тогда , когда компилятор считает , что ее копия может быть изменена. Если копия будет изменяться как PChar , то компилятор не обратит на это внимание.Вот пример:

{$APPTYPE CONSOLE}
Var
s,t:String;
Begin
s:='1';
t:=s;
t[1]:='2';
//Pchar(t)[0]:='2';
writeln(LongInt(PCHar(s))-LongInt(PCHar(t)),':',t,'-',s);
End.

Если закомментировать строку "t[1]:='2';" вместо "Pchar(t)[0]:='2';" , то writeln напишет "0:2-2".
Я в своей программе слишком буквально полагался на справку(там дело в вызове CharToOEM(Pchar(SomeStr),PCHar(SomeStr))).


Тимохов   (2004-06-18 19:01:00) [5]


> vertal ©   (18.06.04 18:50) [8]

если вам нужно заставить строки скопироваться, то используйте uniquestring


panov   (2004-06-18 19:01:00) [6]

А может все-таки кусок кода привести?
Ну так... на всякий случай - вдруг еще не все поняли логику работы программы.


Тимохов   (2004-06-18 18:57:00) [7]


> Я вручную устанавливаю IsMultiThread в True потому , что
> читал в какой-то книжке по Dephi , что менеджер памяти в
> Delphi будет корректно работать , если запущено несколько
> потоков , только если IsMultiThread=True , а запуская поток
> через api - CreateThread из kernel32.dll , а не через класс
> TThread , я по-моему  должен поставить IsMultiThread=True.

абсолютно верно.

> Это нормально???Строки ведь должны физически копироваться!!

начну издалека.
в дельфи есть несколько типов с управляемым (компилятром) временем жизни:
1. СТроки
2. Дин массивы
3. Интерфейсы.
Есть еще, но не суть.

Все это указатели.
При присваивании одного другому в любом случае происходит копирование указателя с увеличением счетчика ссылок. Но нальше для строки и дин массивов все по-разному. Если в копии строки поменять значение, то строка скопируется в другое место со счетчиком ссылок 1, у старой строки счетчик уменьишстя на 1. У дин массивов такого нет - меняшь в копии, меняешь в оригинале.

Вообще то это все в хелпе описано в разделе object pascal reference.

Т.о. глючите вы.


VMcL   (2004-06-18 18:57:00) [8]

>>vertal ©  (18.06.04 18:50) [8]

>Строки ведь должны физически копироваться!!

Длинные строки не должны. Читай справку/книгу.


vertal   (2004-06-18 18:50:00) [9]

Я вручную устанавливаю IsMultiThread в True потому , что читал в какой-то книжке по Dephi , что менеджер памяти в Delphi будет корректно работать , если запущено несколько потоков , только если IsMultiThread=True , а запуская поток через api - CreateThread из kernel32.dll , а не через класс TThread , я по-моему  должен поставить IsMultiThread=True.
Я сейчас поэкспериментировал с тем кодом и выяснил : FindNext и CreateThread по большому счету ни при чем. Там происходит выход из цикла с FindNext из-за того , что портится значение одной строковой переменной (SomeAnotherStr), которая не должна меняться(так).А портится она из-за того , что после присваивания

 SomeStr:=SomeAnotherStr;

оказывается , что

LongInt(PCHar(SomeStr))-LongInt(PCHar(SomeAnotherStr))=0

Это нормально???Строки ведь должны физически копироваться!!
Это я глючу или компилятор??


Игорь Шевченко   (2004-06-18 16:07:00) [10]


> и вручную устанавливаю IsMultiThread в True.


Зачем ?

"IsMultiThread is set to True by BeginThread in order to allow the memory manager to execute safely if a VCL application has more than one thread. If a second thread attempts to allocate memory, it is blocked until the first thread exits the memory manager."


Тимохов   (2004-06-18 15:57:00) [11]


> и работать с SomeStr как с PCHar , то работа FindNext как
> ни странно , не нарушается.

вы думаете это доказательство?

приведите больше кода: как запускаете поток, фунцию потока ...


Cobalt   (2004-06-18 15:53:00) [12]

1) Код твоей процедуры-потока приведи
2) Var
SomeStr,SomeAnotherStr:String;
...
Begin
SomeStr:=SomeAnotherStr;

- Это откуда? Из потока присваивается? Как объявлены структуры для FindNext? Код присваивоения им значений?


vertal   (2004-06-18 15:49:00) [13]

>не думаю, что ошибку надо искать тут, ошибка в другом
Если перед запуском потока поставить SetLength(SomeStr,MAX_PATH)
,а в потоке вместо

 SomeStr:=SomeAnotherStr;

написать

 Move(PCHar(SomeAnotherStr)^,PCHar(SomeStr)^,Length(SomeAnotherStr)+1);

и работать с SomeStr как с PCHar , то работа FindNext как ни странно , не нарушается.


vertal   (2004-06-18 15:45:00) [14]

Не понял , что BeginThread()?
В справке по winapi :
A thread that uses functions from the C run-time libraries should use the beginthread and endthread ...
Я так понимаю ,что beginthread и endthread не определены в winapi ,и вообще ,причем здесь C ?


Тимохов   (2004-06-18 15:37:00) [15]

не думаю, что ошибку надо искать тут, ошибка в другом


VMcL   (2004-06-18 15:28:00) [16]

BeginThread()
?


Наверх

Титульная страница Поиск, карта сайта Написать письмо