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

Вниз

Tthread и с чем его едят?   Найти похожие ветки 

 
malefik   (2006-11-08 10:28) [0]

Добрый времени суток!
несложный вопрос....
допустим обьявлен класс унаследованный от tthread. в секции public обьявлено поле типа int.

в приложении при создании формы создается обьект....этого класса....

TMyThread * thread = new TMyThread(false);
могу я после этого обратится к полю...

например
thread->имя_поля

или всю работы всегда проводить через
Synchronize???


 
DrPass ©   (2006-11-08 10:30) [1]


> могу я после этого обратится к полю...
>
> например
> thread->имя_поля

Можешь, ничего страшного не произойдет. Syncronize - только для потоконезащищенных операций


 
DVM ©   (2006-11-08 10:32) [2]


> могу я после этого обратится к полю...
>
> например
> thread->имя_поля

Не стоит так делать.


> Можешь, ничего страшного не произойдет

не факт


 
malefik   (2006-11-08 10:37) [3]

А что отностится к потоко незащищеным операциям??


 
DVM ©   (2006-11-08 10:38) [4]

Лучше так как то:

TMyThread = class(TThread)
private
   FCriticalSection: TCriticalSection;
   FMyParam: integer;
   procedure SetMyParam(const AMyParam: integer);
   function GetMyParam: integer;
public
   constructor Create(CreateSuspended: boolean);
   destructor Destroy;  override;
   property MyParam: integer read GetMyParam write SetMyParam;
end;

constructor TMyThread.Create(CreateSuspended: boolean);
begin
 inherited Create(CreateSuspended);
 FCriticalSection := TCriticalSection.Create;
end;

destructor TMyThread.Destroy;
begin
 FCriticalSection.Free;
 inherited Destroy;
end;

procedure TMyThread.SetMyParam(const AMyParam: integer);
begin
 FCriticalSection.Enter;
 try
   FMyParam := AMyParam;
 finally
   FCriticalSection.Leave;
 end;
end;

function TMyThread.GetMyParam: integer;
begin
 FCriticalSection.Enter;
 try
   Result := FMyParam;
 finally
   FCriticalSection.Leave;
 end;
end;


 
DVM ©   (2006-11-08 10:39) [5]

Вот из другого потока теперь можно смело обращаться к TMyThread.MyParam


 
Percent   (2006-11-08 10:40) [6]

обьявлено поле типа int

Тип integer - потокобезопасный. Поэтому можно. Правда, при этом надо учитывать и в основном потоке, и в дополнительном, что значение этого поля может измениться совершенно произвольно в любой момент времени. Но это уже проблема алгоритма. А с доступом к полю типа integer, повторюсь, проблем не будет.


 
malefik   (2006-11-08 10:49) [7]

А ansistring ? его надо через синхронизацию...


 
DVM ©   (2006-11-08 10:51) [8]


> malefik   (08.11.06 10:49) [7]
> А ansistring ? его надо через синхронизацию...

Делай все как я написал, проблем не будет. Насчет интегер я не уверен тоже. boolean - за него можно вроде не беспокоиться.
вот еще тебе пригодится книжка:
http://mbo88.narod.ru/ToC.html


 
Percent   (2006-11-08 10:52) [9]

А ansistring ? его надо через синхронизацию...

Операции с AnsiString не атомарны, поэтому работа с ними в контексте нескольких потоков - только с использованием механизмов синхронизации или блокировки.


 
Percent   (2006-11-08 10:57) [10]

Насчет интегер я не уверен тоже

Любая операция с этим типом данных проходит, в максимуме, за один такт процессора, поэтому этот тип данных - потокобезопасный.


 
DrPass ©   (2006-11-08 11:04) [11]


> Делай все как я написал, проблем не будет. Насчет интегер
> я не уверен тоже.

Если не уверен, то RTFM. Избыточные проверки (тем более критические секции) в коде - дурной тон программирования


 
DVM ©   (2006-11-08 11:10) [12]


> Если не уверен, то RTFM. Избыточные проверки (тем более
> критические секции) в коде - дурной тон программирования

Я Integer поле привел лишь для иллюстрации метода. Надо было наверное string указать, чтобы у не возникало вопросов.

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

Насчет атомарности операций с Integer я в самом деле не был уверен.


 
Anatoly Podgoretsky ©   (2006-11-08 11:23) [13]

> DrPass  (08.11.2006 10:30:01)  [1]

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


 
Anatoly Podgoretsky ©   (2006-11-08 11:27) [14]

> Percent  (08.11.2006 10:40:06)  [6]

Возьми опасный. Код приведеный DVM прекрасно иллюстрирует возможность исполнения не в главном потоке с помощью Synchronize


 
Anatoly Podgoretsky ©   (2006-11-08 11:34) [15]

> malefik  (08.11.2006 10:49:07)  [7]

В каком месте и в каком контексте?


 
Anatoly Podgoretsky ©   (2006-11-08 11:38) [16]

> DVM  (08.11.2006 10:51:08)  [8]

> Насчет интегер я не уверен тоже. boolean - за него можно вроде не беспокоиться.

Беспокоиться есть повод всегда, все зависит от того какой код будет сгенерирован, если подобный этому, то опасно, в [ebx+offset] пускай будет Integer или Boolean, не принципиально, видно что операция не атомарная.

mov eax,[ebx+offset]
inc eax
mov [ebx+offset], eax


 
Сергей М. ©   (2006-11-08 13:00) [17]


> Percent   (08.11.06 10:57) [10]
> Любая операция с этим типом данных проходит, в максимуме,
>  за один такт процессора, поэтому этот тип данных - потокобезопасный.


В мультипроцессорных системах и с учетом DMA не стоит на это полагаться.


 
malefik   (2006-11-08 14:57) [18]

немного повторюсь.....но все-же..

в конструкторе нити у меня передается указатель на некий обьект .......который мне необходим внутри нитки......для создания обьектов некого другого класса ....и для просмотра свойств этого обьетка на предмет чего либо......

Вопрос ....как все таки лучше сделать......и самое главное правильно ли это

      TWinSocketStream * _stream; обьект который создается внутри нити
      TCustomWinSocket* _socket; передаваемый указатель


 
Сергей М. ©   (2006-11-08 15:02) [19]

Ты мультипоточный сервер что ли изобретаешь ?


 
malefik   (2006-11-08 15:14) [20]

не совсем...........есть клиент....который цепляется к серверу.....вот и дергаю с него данные в блокирующем режиме.....waitfordata останавлвает основную нить.....


 
Сергей М. ©   (2006-11-08 15:17) [21]


> дергаю с него данные в блокирующем режиме


Ничто не мешает задействовать неблокирующий режим, тогда надобность в доп.нити, возможно. отпадет.


> waitfordata останавлвает основную нить


Не основную, а текущую.. на, заметь, заданное время ... которое не обязоно быть указано не иначе как INFINITE


 
malefik   (2006-11-08 15:26) [22]

переписываю клиента на блокирующие.....потому как в неблокирующих нет гарантии ....а типы соединений у меня разные от гпрс до лан

пример....поплюйтесь......


void __fastcall TClientThread::Execute()
{
AnsiString _cmd_send;

      do
      {
               if (_socket->Connected)
               {
                              switch (_cmd)
                               {
                                case cm_authorize:
                                {
                                 if (!_autorized)
                                 {
                                  _cmd = cm_idle;
                                  Synchronize(_get_autorize_info);
                                   _cmd_send = "<AU|" + _uname + "|" + _upassword + ">";
                                  _stream->Write(_cmd_send.c_str(), _cmd_send.Length());
                                  _wait_and_receive_data();
                                 }
                                }
                               }
               }
      }while( !Terminated );

}


AnsiString TClientThread::_wait_and_receive_data(void)
{
AnsiString _buffer;
char buffer[BUFFERSIZE];
memset(buffer, 0, sizeof(buffer));

if (_socket->Connected)
{
while(_stream->WaitForData(CMDWAITTIME))
{
        _stream->Read(buffer, sizeof(buffer));
       _buffer += StrPas(buffer);
}
}
return buffer;
}


 
Anatoly Podgoretsky ©   (2006-11-08 15:29) [23]

> malefik  (08.11.2006 14:57:18)  [18]

Это вроде не Дельфи


 
malefik   (2006-11-08 15:30) [24]

а то что клиент сокет находится в основной нити приложения это как???


 
Ketmar ©   (2006-11-08 15:31) [25]

>[22] malefik 8-Nov-2006, 15:26
>пример....поплюйтесь......
плююсь: dcc32.exe это скомпилировать не смог.


 
malefik   (2006-11-08 15:31) [26]

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


 
Anatoly Podgoretsky ©   (2006-11-08 15:34) [27]

Раз разницы нет, то приведи и оттрасируй код на Дельфи.


 
Anatoly Podgoretsky ©   (2006-11-08 15:34) [28]

Предупреждение: код на СИ обсуждаем в Прочее


 
Ketmar ©   (2006-11-08 15:38) [29]

>[26] malefik 8-Nov-2006, 15:31
>билдер ...какая собсно разница
а я сейчас приведу код на ALISP. и тоже буду утверждать, что разницы нет.


 
malefik   (2006-11-08 15:39) [30]

хорошо...прошу прощения за код......опустим его.....вопрос остался....
а то что клиент сокет находится в основной нити приложения это как???

ЗЫ VCL она и в африке VCL


 
Сергей М. ©   (2006-11-08 16:10) [31]


> а то что клиент сокет находится в основной нити приложения
> это как???
>


Это никак. По кр.мере пока не объяснишь. что есть "клиент сокет находится в основной нити приложения"


 
Percent   (2006-11-08 17:08) [32]

[17] Сергей М. ©   (08.11.06 13:00)

> Percent   (08.11.06 10:57) [10]
> Любая операция с этим типом данных проходит, в максимуме,
>  за один такт процессора, поэтому этот тип данных - потокобезопасный.

В мультипроцессорных системах и с учетом DMA не стоит на это полагаться.


Доступ к значению для переменных типа integer - атомарная, а посему - потокобезопасная операция.
Все остальное не имеет никакого значения.
Хоть в мультипроцессорной системе, хоть с учетом DMA, хоть в другой звездной системе...


 
Ketmar ©   (2006-11-08 17:10) [33]

>[32] Percent 8-Nov-2006, 17:08
>Доступ к значению для переменных типа integer - атомарная,
если integer поравняли, конечно.


 
evvcom ©   (2006-11-08 17:34) [34]

> [32] Percent   (08.11.06 17:08)
> Доступ к значению для переменных типа integer - атомарная

Доступ на чтение? Запись? Чтение и запись? Если просто почитать и больше ничего не делать, то да. А если..., то нет.


 
malefik   (2006-11-08 18:57) [35]

не правильно сформулировал, сорри.....
Вобщем так, ClientSocket находится в основной нити приложения......и в его обработчике события OnConnect создаем нить .......куда передаем указатель       TCustomWinSocket* _socket; .....в самой нитке создается обьект класса  ТWinSocketStream * _stream; ....который и имеет собственно метод WaitForData....
Короче это работает сейчас у меня .....основное приложение не тормозит.....но хотелось бы узнать ......правильно это или нет.....


 
malefik   (2006-11-08 18:59) [36]


> Доступ на чтение? Запись?

на запись ....из основной нити даю команды другой на работу с сетью....


 
evvcom ©   (2006-11-08 19:10) [37]

> [36] malefik   (08.11.06 18:59)

Не может быть просто на запись. Скорее всего не может быть даже просто на чтение. Прежде, чем что-то писать, ты все равно сначала читаешь значение и его анализируешь, и если удовлетворяет каким-то условиям, пишешь новое значение. Другой поток, освобождаясь, начинает перебирать "задания", читая значения. Увидев задание в очереди, он пишет флаг, что он взялся за это задание, потом, вероятно пишет, что он его выполнил. Так вот эти чтение/запись должны быть защищены от изменения.


 
Percent   (2006-11-08 22:19) [38]

Доступ на чтение? Запись? Чтение и запись? Если просто почитать и больше ничего не делать, то да. А если..., то нет.

Как все многозначительно и загадочно... :-)
На самом деле, никакой разницы.
Потокобезопасно и все (в отношении 32-разрядных целых).

если integer поравняли, конечно.

Куда поравняли? К 32-бит-кратной границе? Не имеет значения. Операции перемещения память-регистр и регистр-память с 32-битными операндами выполняются одной командой процессора. Поток не может быть приостановлен "где-то в процессе" выполнения такой команды. Хотя бы потому, что состояние регистров при такой остановке окажется неопределенным. А при остановке потока поизводится сохранение состояния регистров. Что сохранять, если состояние неопределенное?

Другой поток, освобождаясь, начинает перебирать "задания", читая значения. Увидев задание в очереди, он пишет флаг, что он взялся за это задание, потом, вероятно пишет, что он его выполнил. Так вот эти чтение/запись должны быть защищены от изменения.

Про "задания", "очередь", "флаги", "отчет о выполнении", "защиту от изменения чтения/записи" и их влияние на многопоточность - пожалуйста, если можно, подробнее. Особенно - про "защиту от изменения" и "отчет о выполнении"...


 
Сергей М. ©   (2006-11-09 08:17) [39]


> Percent


Как думаешь, зачем в Intel придумали префикс lock ?
От нефига делать, надо понимать ?)


 
Anatoly Podgoretsky ©   (2006-11-09 08:59) [40]

Конечно не просто так, его придумали для 8086, начиная с 80486 неактуален.


 
Ketmar ©   (2006-11-09 12:03) [41]

>[38] Percent 8-Nov-2006, 22:19
>процессора. Поток не может быть приостановлен "где-то в
>процессе" выполнения такой команды.
ты упоминал многопроцессорные системы. там ничего не "приостанавливается". а одновременные обращения всё равно бывают. загадка?

зыж как ты думаешь, отчего aligned-данные выбираются быстрее?


 
evvcom ©   (2006-11-09 12:07) [42]

> [38] Percent   (08.11.06 22:19)
> Про "задания", "очередь", "флаги", "отчет о выполнении",
> "защиту от изменения чтения/записи" и их влияние на многопоточность
> - пожалуйста, если можно, подробнее. Особенно - про "защиту
> от изменения" и "отчет о выполнении"...

Спроси у Рихтера, он знает. Выкладывать сюда полкниги я не собираюсь.


 
Anatoly Podgoretsky ©   (2006-11-09 12:10) [43]

> Ketmar  (09.11.2006 12:03:41)  [41]

Отвечать надо? С одной стороны вроде риторический вопрос, с другой стороны в конце стоит знак вопроса.
Кстати а ты уверен?


 
Ketmar ©   (2006-11-09 12:50) [44]

>[43] Anatoly Podgoretsky(c) 9-Nov-2006, 12:10
>Отвечать надо?
нет, риторический.

>Кстати а ты уверен?
на моём pIII это именно так. может, новая память адресуется как-то по другому, но что-то я сильно сомневаюсь.



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

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

Наверх




Память: 0.59 MB
Время: 0.051 c
15-1162908698
RomanH
2006-11-07 17:11
2006.11.26
Применение DecisionCube


15-1163080474
Greenchel
2006-11-09 16:54
2006.11.26
Сохранить текст из Edit


15-1162962849
Elen
2006-11-08 08:14
2006.11.26
Подскажите в сети литературу о PopUp меню


3-1159203037
*Ray*
2006-09-25 20:50
2006.11.26
Обработка ошибок


6-1152266385
MN
2006-07-07 13:59
2006.11.26
Как программно активировать сетевое подключение?