Вверх ↑
Этот топик читают: Гость
Ответов: 704
Рейтинг: 7
#1: 2014-01-21 01:11:33 ЛС | профиль | цитата
Когда-то поднимал я тему на счет потоков и ошибок. Индиго мне ткнул носом в мютексы. И все вроде заработало. Пока не сменил компьютер на более шустрый. Тут опять вылезли накладки с потоками. Потому прошу знающих подсказать в этой алгоритмической схеме как правильно поставить мютексы и может где-то нужно потоки заменить чем-то... Может алгоритм неверный в корне. Читал в википедии что вроде мютексы нельзя ставить на 2 разных потока ибо будет самоблокировка и "гонка" и треш и хоррор
В общем сам запутался в край. Прошу подтолкнуть.
В схеме все подписал через LH.
code_32873.txt
карма: 0

0
файлы: 1code_32873.txt [1.8KB] [199]
Разработчик
Ответов: 26304
Рейтинг: 2146
#2: 2014-01-21 01:27:09 ЛС | профиль | цитата
Neo, между прочим, к SQLite применять потоки крайне нежелательно, тк SQLite сам использует потоки и у него есть своя собственная очередь запросов. В твоей схеме надо использовать синхронизацию по doSynchExec.

Как-то вот так

Add(Timer,2359789,294,399)
{
@Hint=#12:Типа порт ))|
link(onTimer,5160726:doEvent1,[])
AddHint(-33,-37,75,13,@Hint)
}
Add(MathParse,10371621,399,504)
{
@Hint=#28:Обрабатываем очередь с порта|
link(onResult,11105397:doText,[])
AddHint(-82,44,177,13,@Hint)
}
Add(Hub,429521,609,399)
{
@Hint=#31:Шлем обработанные данные в порт|
InCount=3
OutCount=1
link(onEvent1,2359789:doTimer,[(649,405)(649,593)(284,593)(284,405)])
AddHint(31,-24,196,13,@Hint)
}
Add(Thread,4033809,343,196)
{
@Hint=#108:Поток чтоб доставать всегда без пропусков, и чтоб не висло. да и независимо от данных с порта чтоб работало.|
link(onExec,68944:doQuery,[])
link(onSyncExec,9640015:doData,[(389,209)(389,251)])
AddHint(-120,-72,188,52,@Hint)
}
Add(SQLite_Exec,10137621,385,350)
{
@Hint=#19:Пишем в базу данные|
AddHint(-206,-10,127,13,@Hint)
}
Add(Hub,5160726,350,399)
{
OutCount=3
link(onEvent1,10137621:doExec,[(375,405)(375,356)])
link(onEvent2,5672657:doExec,[])
link(onEvent3,10371621:doCalc,[(389,419)(389,510)])
}
Add(SQLite_Query,68944,399,196)
{
@Hint=#33:Достаем инфу из записанных данных|
link(onQuery,7164691:doValue,[])
AddHint(53,-44,171,26,@Hint)
}
Add(Label,11105397,455,504)
{
@Hint=#27:Выводим на интерфейс данные|
Left=320
Top=265
link(onClick,429521:doEvent3,[(494,510)(494,419)])
AddHint(-69,-35,176,13,@Hint)
}
Add(Thread,6990771,385,287)
{
@Hint=#8:Поток...|
link(onExec,8923181:doQuery,[])
link(onSyncExec,7981061:doData,[(431,300)(431,342)])
AddHint(-52,-121,55,13,@Hint)
}
Add(SQLite_Exec,5672657,441,406)
{
@Hint=#8:Пишем...|
AddHint(52,-39,60,13,@Hint)
}
Add(SQLite_Query,8923181,441,287)
{
@Hint=#10:Достаем...|
link(onQuery,5784375:doValue,[])
AddHint(111,-120,70,13,@Hint)
}
Add(Memory,5784375,504,287)
{
}
Add(DoData,7981061,504,336)
{
link(onEventData,429521:doEvent2,[(592,342)(592,412)])
link(Data,5784375:Value,[])
}
Add(DoData,9640015,504,245)
{
link(onEventData,429521:doEvent1,[(599,251)(599,405)])
link(Data,7164691:Value,[])
}
Add(Memory,7164691,504,196)
{
}

В таком случае, у тебя два потока не сработают одновременно, тк событие doSynchExec синхронизировано с главным потоком приложения
карма: 22

0
Ответов: 704
Рейтинг: 7
#3: 2014-01-21 01:38:54 ЛС | профиль | цитата
nesco, спасибо. Пока не додумался рассмотреть такой вариант, так как пугает возможность, что когда-то может получится сразу штук 5 результатов за один запрос из БД, и тут мемори не справится. А если поставлю накопление результатов вместо мемори, то ведь будут подвисания основного потока? Мютексы вообще не нужны здесь?

И вдруг основной поток быстрее сделает свою работу, а doSynchExec возьмет данные, которые БД еще пишет своим потоком в мемори? Или это невозможно? Что-то в потоках плаваю... А экспериментально слишком долго приходится ждать вылезет накладка или нет
------------ Дoбавленo в 01.38:
И ведь основной поток может притормозить так как выводит данные на интерфейс. В этот момент параллельный поток сработает и будет накладка?
карма: 0

0
Разработчик
Ответов: 26304
Рейтинг: 2146
#4: 2014-01-21 01:53:22 ЛС | профиль | цитата
Neo писал(а):
а doSynchExec возьмет данные, которые БД еще пишет своим потоком в мемори? Или это невозможно?

Нет, это невозможно. Сначала выполнится вся цепть событий, подключенных к точке onExec, и только после этого, поток включит переход на событие onSynchExec, которое тоже сразу не сработает, а только тогда, когда это событие попадет в обработку очереди главного потока
Neo писал(а):
В этот момент параллельный поток сработает и будет накладка?

Не будет, поток запишет данные в Memory, а вот прочитает их только тогда, когда главный поток разрешит выполнить событие onSynchExec
------------ Дoбавленo в 01.53:
Neo писал(а):
возможность, что когда-то может получится сразу штук 5 результатов

Делай буфер и циклично его выбирай до опустения
карма: 22

1
Голосовали:Neo
Ответов: 704
Рейтинг: 7
#5: 2014-01-23 18:08:32 ЛС | профиль | цитата
nesco, А здесь я правильно организовал или есть более красивый метод?
Сложность в том, что некоторые компоненты выдают данные уже в новом потоке и точки синхронизированного события у них нет.
code_32908.txt
карма: 0

0
файлы: 1code_32908.txt [1.1KB] [210]
Ответов: 4663
Рейтинг: 767
#6: 2014-01-23 18:12:59 ЛС | профиль | цитата
Neo писал(а):
точки синхронизированного события у них нет

Neo, здесь на последней странице я выложил схему с IC, которая показывает вызов синхронного события из любого места потока. Только нужен файл NSThreads.pas из первого поста.
карма: 26

1
Голосовали:Neo
Ответов: 704
Рейтинг: 7
#7: 2014-01-25 16:12:51 ЛС | профиль | цитата
Запутался совсем. Растолкуйте как правильно организовать такой пример:
Пишем в список системным потоком. Но читать и записывать в базу уже нужно только параллельным потоком, и запись может длиться даже когда новые данные уже будут хотеть добавиться в список. А потом произойдет очистка (по синхронизированному событию) и они тоже очистятся, так и не исполнившись? Да и еще я получу ошибку доступа к данным если будет одновременно и запись и чтение?
Направьте мою мышку опытной рукой к нужным компонентам
Add(DoData,10372767,203,175)
{
link(onEventData,7160791:doAdd,[])
}
Add(Memo,7160791,259,175)
{
Left=5
Top=5
}
Add(SQLite_Exec,921486,252,238)
{
link(SQL,7160791:Text,[])
}
Add(Thread,9353554,154,238)
{
link(onExec,921486:doExec,[])
link(onSyncExec,7160791:doClear,[(241,251)(241,188)])
}
Add(Timer,12076826,154,175)
{
link(onTimer,10372767:doData,[])
}


карма: 0

0
7
Сообщение
...
Прикрепленные файлы
(файлы не залиты)