быть потоку или не быть

Общие вопросы программирования, алгоритмы и т.п.

Модератор: Модераторы

быть потоку или не быть

Сообщение Attid » 18.06.2009 16:52:38

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

есть у меня небольшой демон, работающий с устройствами.

алгоритм прост до безобразияи рабоет стабильно :
1, загружаем список устройств
2, проверяем их по очереди
3, записываем лог в файл что сделали
4, отчитались в БД что натварили
5. goto 2


все было хорошо пока не появились сетевые устройства
а когда они пропадают, система очень долго может весеть прежде чем вернет что устройство отсутствует.
как я понимаю эта батва на уровне протокола TCP\IP и с этим ничего сделать нельзя, но тормазить очередь нельзя.
вывод надо распаралелится

I класический вариант fork
1 загружаю список устройств
2, создаю клонов согласно купленным билетам каждому даю свою задачу.

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

II потоки
1, получаю информацию
2, создаю каждому по потоку и там они опрашиваются.
3, в синхронизации пишу все в лог и в БД чтоб не плодить конекты


с логикой вроде понятно. с потоками не разу не сталкивался кроме теоретики.
теперь вопрос
1. какие потоки использовать лучше те которые класические в паскале критические функции или из lcl TTheard ?
2. что есть "потокобезопасная функция" и как их правельно создовать ?
Аватара пользователя
Attid
долгожитель
 
Сообщения: 2585
Зарегистрирован: 27.10.2006 17:29:15
Откуда: 44°32′23.63″N 41°2′25.2″E

Re: быть потоку или не быть

Сообщение Ракшас » 18.06.2009 20:39:28

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

Возможно скажу глупость, но может просто ограничить время на опрос одного устройства? Поставить таймер, по выполнении которого неответившее устройство считается нерабочим/отсутствующим.
Ракшас
незнакомец
 
Сообщения: 8
Зарегистрирован: 17.11.2008 17:07:35

Re: быть потоку или не быть

Сообщение Logo » 18.06.2009 22:56:01

Помойму это наиболее просто, в данном случае:
(uses System;)

BeginThread(@MyProcedure, @MyMem, ID_of_thread);

MyProcedure// процедура обработки
MyMem// Память для общения с Thread (например структура)
var ID_of_thread: QWord // идентефикатор потока.

Можно еще задать стек, но для Линукс это не актуально.


TO: Ракшас
Возможно скажу глупость, но может просто ограничить время на опрос одного устройства? Поставить таймер, по выполнении которого неответившее устройство считается нерабочим/отсутствующим.

Как? Есть идеи? Я не исключаю, что это можно сделать, но не представляю как.

Добавлено спустя 6 минут 27 секунд:
fork полностью копирует приложение в новую область памяти продолжая выполнение с точки после fork. По моему это очень расточительно для памяти, во всяком случае для данной задачи.

Добавлено спустя 8 минут 5 секунд:
что есть "потокобезопасная функция" и как их правельно создовать ?

Не лезть в недопустимые регистры. Если писать без ассемблеровских кодов, то проблем не возникает. INC() и DEC() в потоках нельзя использовать, есть им замена InterLockedDecrement(), InterLockedDecrement64(), InterLockedIncrement(), InterLockedIncrement64(). Какие еще - не помню :oops: Но наводка есть, думаю разберешься.
Logo
постоялец
 
Сообщения: 464
Зарегистрирован: 20.08.2008 01:00:47

Re: быть потоку или не быть

Сообщение Vadim » 19.06.2009 07:06:10

Logo писал(а):InterLockedDecrement(), InterLockedDecrement64(), InterLockedIncrement(), InterLockedIncrement64()

Это для WinAPI, а для Линукса?
Vadim
долгожитель
 
Сообщения: 4112
Зарегистрирован: 05.10.2006 08:52:59
Откуда: Красноярск

Re: быть потоку или не быть

Сообщение Attid » 19.06.2009 10:54:00

Ракшас писал(а):но может просто ограничить время на опрос одного устройства?

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


Logo писал(а):BeginThread(@MyProcedure

а для доступа к общем данным что лучше критическую секцию или мутексы или чего еще ?
причем желательно выставить очередь чтобы не получилось что пришли данные от 1 2 3 4

1 захватил ресурс, остальняе стунулись стали ждать 1мс
2 захватил ресурс, 3,4 ждут 1с
а тутвернулся 1 и опять захватил. а 3 4 будут задерживаться
Аватара пользователя
Attid
долгожитель
 
Сообщения: 2585
Зарегистрирован: 27.10.2006 17:29:15
Откуда: 44°32′23.63″N 41°2′25.2″E

Re: быть потоку или не быть

Сообщение Max Rusov » 19.06.2009 11:11:46

Ну так критическая секция нужна только при доступе к общим ресурсам (записи в лог). По сравнению со временем опроса устройства его можно считать пренебрежимо малым.
Max Rusov
постоялец
 
Сообщения: 191
Зарегистрирован: 25.04.2009 15:46:03

Re: быть потоку или не быть

Сообщение FedeX » 19.06.2009 12:07:59

Не лезть в недопустимые регистры. Если писать без ассемблеровских кодов, то проблем не возникает. INC() и DEC() в потоках нельзя использовать, есть им замена InterLockedDecrement(), InterLockedDecrement64(), InterLockedIncrement(), InterLockedIncrement64(). Какие еще - не помню :oops: Но наводка есть, думаю разберешься.

Это для WinAPI, а для Линукса?

Нашел эти функции в rtl (под разные системы), но всё-таки не понял их назначения - я раньше думал, что при переключении потоков система сама сохраняет и переключает стек и все (или почти все) регистры процессора, так что у каждого потока своя копия этих ресурсов... Разве нет? И если нет, то почему тогда только для инкрементов/декрементов такая немилость? Где узнать полный список разрешонных в потоке регистров и операций? У меня в коде уже немало инк-ов и дек-ов в потоках, пока работает, но появились опасения... :o Вообщем откудого такая информация?

а для доступа к общем данным что лучше критическую секцию или мутексы или чего еще ?

То что удобнее в конкретной ситуации..
1 захватил ресурс, остальняе стунулись стали ждать 1мс
2 захватил ресурс, 3,4 ждут 1с
а тутвернулся 1 и опять захватил. а 3 4 будут задерживаться

А зачем им ждать 1 с? Сейчас не имею дело с потоками, но точно помню что какой-то из типов синхронизации (криические секции?) сам притормаживает выполнение потока ровно до того момента когда секция освободиться, тоесть 3 и 4 запустяться сразу после того как 1 освободит критическую секцию (или что там ещё), точнее запуститься тот который запросил её следующим, (напр 3, а 4 останеться ждать..) Вроде так..
Аватара пользователя
FedeX
постоялец
 
Сообщения: 422
Зарегистрирован: 27.03.2006 09:25:34
Откуда: украина, житомир

Re: быть потоку или не быть

Сообщение Attid » 19.06.2009 12:31:18

FedeX писал(а):Вроде так..

да так и будет и именно с критическими секциями. по крайней мере на стенде =) с ПН поставлю в поле.

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

если нет то надеюсь только на свой опыт =)
Аватара пользователя
Attid
долгожитель
 
Сообщения: 2585
Зарегистрирован: 27.10.2006 17:29:15
Откуда: 44°32′23.63″N 41°2′25.2″E

Re: быть потоку или не быть

Сообщение Max Rusov » 19.06.2009 12:57:47

Interlocked функции нужны только при обращении из разных потоков к общим переменным. Они позволяют в ряде простых случаев обойтись без критической секции. К локальным переменным потока доступ, естественно, свободный.
Max Rusov
постоялец
 
Сообщения: 191
Зарегистрирован: 25.04.2009 15:46:03

Re: быть потоку или не быть

Сообщение FedeX » 19.06.2009 13:25:28

А.. Тогда всё понятно :) А то напугали)

редактирование.. О! С этим постом я стал числиться на форуме как "бывалый" :D
Аватара пользователя
FedeX
постоялец
 
Сообщения: 422
Зарегистрирован: 27.03.2006 09:25:34
Откуда: украина, житомир

Re: быть потоку или не быть

Сообщение Logo » 19.06.2009 13:36:13

Max Rusov писал(а):Interlocked функции нужны только при обращении из разных потоков к общим переменным. Они позволяют в ряде простых случаев обойтись без критической секции. К локальным переменным потока доступ, естественно, свободный.

+100
Вот пример из fpc Help:
Код: Выделить всё
{$mode objfpc} 

uses 
  sysutils {$ifdef unix},cthreads{$endif} ;  //Не понятно! Предупреждают, что "cthreads" должен быт обязательно первым, а в примере второй. Отнесем на ошибку хелпа.

const 
  threadcount = 100; 
  stringlen = 10000; 

var 
   finished : longint; 

threadvar 
   thri : ptrint; 

function f(p : pointer) : ptrint; 

var 
  s : ansistring; 
begin 
  Writeln(’thread ’,longint(p),’ started’); 
  thri:=0; 
  while (thri<stringlen) do 
    begin 
    s:=s+’1’; 
    inc(thri);  //Локальные переменные инкрементируются без проблем
    end; 
  Writeln(’thread ’,longint(p),’ finished’); 
  InterLockedIncrement(finished);  //Инкремент глобальной переменной
  f:=0; 
end; 

var 
   i : longint; 

begin 
   finished:=0; 
   for i:=1 to threadcount do 
     BeginThread(@f,pointer(i)); 
   while finished<threadcount do ; 
   Writeln(finished); 
end. 


Списосок:
InterLockedDecrement
InterLockedIncrement
InterLockedExchange
InterLockedExchangeAdd
InterlockedCompareExchange
Может в fpc 2.3.1 чего изменили, я не смотрел.

Добавлено спустя 12 минут 9 секунд:
Глобальные переменные описаные,как "threadvar " доступны в потоках обычным образом см. пример:
threadvar
thri : ptrint;
Logo
постоялец
 
Сообщения: 464
Зарегистрирован: 20.08.2008 01:00:47

Re: быть потоку или не быть

Сообщение Sergei I. Gorelkin » 19.06.2009 14:06:49

Attid писал(а):а для доступа к общем данным что лучше критическую секцию или мутексы или чего еще ?

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

Attid писал(а):причем желательно выставить очередь чтобы не получилось что
пришли данные от 1 2 3 4
1 захватил ресурс, остальняе стунулись стали ждать 1мс
2 захватил ресурс, 3,4 ждут 1с
а тутвернулся 1 и опять захватил. а 3 4 будут задерживаться

Так не получится, потому что пока (2) владеет ресурсом, (3) и (4) ждут не просто так, а на попытке захвата, и как только (2) освободится, ресурс сразу достанется либо (3), либо (4) - поэтому "вернувшийся" (1) не сможет ничего захватить, пока (3) или (4) не освободят.
Но, если учесть, что один или несколько потоков могут застрять на сетевом интерфейсе на пару минут, конечный результат едва ли будет напоминать очередь...
Аватара пользователя
Sergei I. Gorelkin
энтузиаст
 
Сообщения: 1405
Зарегистрирован: 24.07.2005 14:40:41
Откуда: Зеленоград

Re: быть потоку или не быть

Сообщение Attid » 01.07.2009 00:02:44

чет я разогнался =(
критические секции висят в
{%MainUnit ../lclintf.pp}
// included by interfacebase.pp and lclintf.pp
тобишь зависимо от виджетов, а их то у меня и нет. как разруливать доступ к общим ресурсам в лине в консоле ?
Аватара пользователя
Attid
долгожитель
 
Сообщения: 2585
Зарегистрирован: 27.10.2006 17:29:15
Откуда: 44°32′23.63″N 41°2′25.2″E

Re: быть потоку или не быть

Сообщение Max Rusov » 01.07.2009 00:12:46

Enter/Leave CriticalSection определены в System, Вы о чем?
Max Rusov
постоялец
 
Сообщения: 191
Зарегистрирован: 25.04.2009 15:46:03

Re: быть потоку или не быть

Сообщение Attid » 01.07.2009 14:00:30

Max Rusov
да я пример в лазаре взял а там используется
InitializeCriticalSection\EnterCriticalSection(CriticalSection);

а о том что еще бывают
InitCriticalSection/EnterCriticalsection как-то подумал :oops:

Добавлено спустя 1 минуту 24 секунды:
кста а чем они отличаются и зачем ини бывают разные ?
Аватара пользователя
Attid
долгожитель
 
Сообщения: 2585
Зарегистрирован: 27.10.2006 17:29:15
Откуда: 44°32′23.63″N 41°2′25.2″E

След.

Вернуться в Общее

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 8

Рейтинг@Mail.ru