Forth и другие саморасширяющиеся системы программирования Locations of visitors to this page
Текущее время: Ср окт 05, 2022 19:49

...
Google Search
Forth-FAQ Spy Grafic

Часовой пояс: UTC + 3 часа [ Летнее время ]




Ответить
Имя пользователя:
Заголовок:
Текст сообщения:
Введите текст вашего сообщения. Длина сообщения в символах не более: 60000

Размер шрифта:
Цвет шрифта
Настройки:
BBCode ВКЛЮЧЕН
[img] ВЫКЛЮЧЕН
[flash] ВЫКЛЮЧЕН
[url] ВКЛЮЧЕН
Смайлики ВЫКЛЮЧЕНЫ
Отключить в этом сообщении BBCode
Не преобразовывать адреса URL в ссылки
Вопрос
Теперь гостю придется вводить здесь пароль. Не от своей учетной записи, а ПАРОЛЬ ДЛЯ ГОСТЯ, получить который можно после регистрации на форуме через ЛС.:
Этот вопрос предназначен для выявления и предотвращения автоматических регистраций.
   

Обзор темы - поддержка многозадачности. вопросы
Автор Сообщение
  Заголовок сообщения:   Ответить с цитатой
возник вот какой вопрос. как можно (наиболее простым образом) вызвать определенный код внутри порожденного потока?
то есть вариант callback вызова, когда один поток передает управление на заданный адрес внутри другого потока.
соответсвтенно, пока только для win платформы.
Сообщение Добавлено: Ср май 06, 2009 21:18
  Заголовок сообщения:   Ответить с цитатой
в отличие от СПФа любое слово может быть запущено, как задача, кроме того, может быть передано любое (разумное) число значений со стека данных запускающей задачи. Выглядит это так:

1 2 3 4 5 6 7 8 4 test START

будет запущено слово test (оно в коде описано)
test получит 4 параметра с вершины стека данных запускающего процесса

Ловля исключений для порожденных потоков пока не сделана, поэтому критическая ошибка в любом порожденном потоке будет "ронять" весь процесс!

вот, если есть замечания или предложения, готов выслушать.
Сообщение Добавлено: Вт май 05, 2009 23:21
  Заголовок сообщения:   Ответить с цитатой
ладно, вот что пока получается:

<pre>
\ 28.04.2009 ~mOleg
\ Сopyright [C] 2009 mOleg mininoleg@yahoo.com
\ поддержка многозадачности

os/ defwords.fts

WINAPI: CreateThread KERNEL32.DLL ( lpThreadId dwCreationFlags lpParameter dwStackSize lpThreadAttributes --> tid | 0 )
WINAPI: ExitThread KERNEL32.DLL ( exitcode --> )
WINAPI: Sleep KERNEL32.DLL ( ms --> x )
WINAPI: SuspendThread KERNEL32.DLL ( tid --> u | -1 )
WINAPI: ResumeThread KERNEL32.DLL ( tid --> time )


USER-VECT TASK-EXCEPTION \ вектор для перехвата исключения

\ сделать свой обработчик исключений!!!
: (T-EXC) ( DispatcherContext ContextRecord EstablisherFrame ExceptionRecord --> flag )
(ENTER) \ фрейм для стека данных


;

\ уснуть на указанное количество милисекунд
\ в случае, если ms = 0 поток просто отдает управление другому потоку
: PAUSE ( ms --> ) Sleep DROP ;

\ остановить текущий поток (удалить)
: TERMINATE ( exitcode --> )
ThreadHeap *IF HeapDestroy THEN DROP
ExitThread ;

\ слово вызывается при запуске нового процесса.
\ Обеспечивает инициализацию Форт-окружения:
\ инициализация стеков, пользовательской области, обработчиков исключений
: (TASK) ( r: spam sp --> )
[ 0x58 B, \ pop tos
0x64 B, 0x8F B, 0x05 B, 0x0 , ] \ pop fs: [14]
(ENTER) INIT-MEM 0
['] (~ERROR) err-handler !
[ 0x64 B, 0x8B B, 0x1D B, 0x0 , \ MOV EBX, FS:[0]
0x64 B, 0xC7 B, 0x05 B, 0 , 0 , \ MOV FS:[0],0
0x8B B, 0x4B B, 0x04 B, \ MOV ECX, [EBP+4]
0x87 B, 0xE5 B, \ XCHG ESP, EBP
0x41 B, \ INC ECX
0xFF B, 0x34 B, 0x8B B, \ PUSH [EBX+ECX*4]
0x49 B, \ DEC ECX │
0x75 B, -6 B, \ JNZ ─────┘
0x8B B, 0x43 B, 0x00 B, \ MOV EAX, [EBX]
\ сообщаем породившему процессу о том, что можно удалять параметры:
0xC7 B, 0x03 B, 0 , \ MOV [EBX] , 0
0x59 B, \ POP ECX
0x87 B, 0xE5 B, ] \ XCHG ESP, EBP
<SET-EXC-HANDLER>
\ если очень хочется, тут можно проинитить вектора и потоки
CATCH TERMINATE ;

\ запуск указанного слова xt в новом процессе с указанными параметрами
\ [ params ] # , которые должны лежать на стеке данных запущенного процесса
: START ( [ params ] # xt --> task-handle )
SP@ >L \ указатель на вершину стека данных родительского процесса
0>R' \ tid
0 \ flags
L> \ param
['] (TASK) \ start routine
0 \ (equal stack size)
0 \ pointer to SECURITY_ATTRIBUTES
CreateThread
RDROP >L \ --> [params] # xt
BEGIN *WHILE 0 PAUSE REPEAT \ ожидание пока скопируются параметры
DROP nDROP \ удаление уже не нужных параметров
L> ;

\ усыпить поток
: SUSPEND ( tid --> ) SuspendThread DROP ;

\ разбудить поток
: RESUME ( tid --> ) ResumeThread DROP ;

\ ------------------------------------------------------------------------------

\ пример использования
:> test ( ix --> )
CONSOLE-HANDLES \ без этого нельзя работать с вводом\выводом
ISO> INPUT-STREAM \ без этого не будет форматного преобразования
S-O TO CONTEXT init-order DEFINITIONS \ без этого не будет поиска
prefer @ BASE ! \ без этого будет ловиться ошибка деления на нуль
\ при попытке вывести число

ORDER \ посмотреть на контекст
.S \ посмотреть на полученные параметры

." hello from task\n\r"

;
</pre>
Сообщение Добавлено: Вт май 05, 2009 23:18
  Заголовок сообщения:   Ответить с цитатой
адвокат писал(а):
SPF4 позволяет компилировать одновременно в нескольких потоках.

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

_Harry писал(а):
Это не много не то, т.е. имя должно быть отдельное или словарь отдельный, чтобы конкретно понимать где выделяется память. Это важно.

эм, в СПФе сделано так: у каждого потока собственный хип. Завершается поток - удаляется хип. Это позволяет избавляться от утечек памяти(если они есть). Я тут ничего не меняю, просто хип будет создаваться лишь по факту обращения к нему (но это действительно только для порожденных потоков, а в главном потоке Хип создается в любом случае)

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

это понятно, только вот THROW никак на эту роль не подходит. Должен быть отдельный какой-то механизм.
Сообщение Добавлено: Чт апр 30, 2009 00:28
  Заголовок сообщения:   Ответить с цитатой
SPF4 позволяет компилировать одновременно в нескольких потоках.
Сообщение Добавлено: Ср апр 29, 2009 22:54
  Заголовок сообщения:   Ответить с цитатой
diver писал(а):
создать глобальную структуру типа очереди или стека ошибок/исключений потоков, пусть потоки отчитываются туда. можно переопределить тот же THROW. а главный поток пусть эту очередь расхлебывает.

у mOleg'а были подходящие разработки - и стек строк (для репортов) и завёрнутый стек - очередь ...
Сообщение Добавлено: Ср апр 29, 2009 20:34
  Заголовок сообщения:   Ответить с цитатой
mOleg писал(а):
а это будет уже не то. Задача должна порождать поток и продолжать свое выполнение, ведь, к примеру, может быть необходимо запустить 100 потоков, и потом заниматься своими делами, периодически опрашивая потоки и ловя сообщения об ошибках в них. Так вот вопрос как ловить ошибки? THROW для этого не подходит явно.


создать глобальную структуру типа очереди или стека ошибок/исключений потоков, пусть потоки отчитываются туда. можно переопределить тот же THROW. а главный поток пусть эту очередь расхлебывает.
Сообщение Добавлено: Ср апр 29, 2009 18:41
  Заголовок сообщения:   Ответить с цитатой
mOleg писал(а):
а это будет уже не то. Задача должна порождать поток и продолжать свое выполнение, ведь, к примеру, может быть необходимо запустить 100 потоков, и потом заниматься своими делами, периодически опрашивая потоки и ловя сообщения об ошибках в них. Так вот вопрос как ловить ошибки? THROW для этого не подходит явно.

Точно это я с тупил. :roll:
Надо забираться в MSDN и там блуждать пока не найдеш чего.
Может какие системные события можно использовать я таким не занимался.

mOleg писал(а):
вообще есть такой вариант:

Код:
USER-VALUE HEAP

: ALLOCATE ( # --> addr | false )

                  HEAP IFNOT CREATE-HEAP THEN

                  (ALLOCATE) ;



Это не много не то, т.е. имя должно быть отдельное или словарь отдельный, чтобы конкретно понимать где выделяется память. Это важно.
Сообщение Добавлено: Ср апр 29, 2009 15:25
  Заголовок сообщения:   Ответить с цитатой
_Harry писал(а):
Думаю что лучше всего активно использовать хип процесса. Слова ядра ALLOCATE и т.п. должны работать с ним. А для хипа потока использовать отдельную библиотеку по мере необходимости.

вообще есть такой вариант:
<pre>
USER-VALUE HEAP

: ALLOCATE ( # --> addr | false )
HEAP IFNOT CREATE-HEAP THEN
(ALLOCATE) ;
</pre>
собственно при первой надобности будет создаваться в потоке хип, тем более, что всеравно операция достаточно медленная.

_Harry писал(а):
mOleg писал(а):- нужно ли инициализировать контекст? [ведь не обязательно будет поиск, компиляция и пр. в словаре]
кроме того, может быть большое и понятное желание для каждого нового потока иметь собственный контекст.
Все так но, в подаляющем большинстве случаев потоки не будут компилировать ни чего.
Опять же отдельная библиотека подключающая "многоконтекстность" решит проблему.
(Интересно кому нибудь раньше такое понадобилось)

А собственно, в СПФе и нельзя компилировать одновременно в нескольких потоках, причем в форке я эту проблему еще не разрешил (хотя знаю как)
с другой стороны ведь не обязательно компилировать, скорее надо будет транслировать. То есть создается некий специфичный DSL, закрывается в своем контексте его интерфейс, и задача запускается внутри этого контекста (это уже не Форт может быть).

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

_Harry писал(а):
Ну а если так слово запускающее поток должно положить на стек результат завершения потока.
Когда завершение штатное это 0, если ошибка код ошибки. Обработка соответственно в родительском потоке.

а это будет уже не то. Задача должна порождать поток и продолжать свое выполнение, ведь, к примеру, может быть необходимо запустить 100 потоков, и потом заниматься своими делами, периодически опрашивая потоки и ловя сообщения об ошибках в них. Так вот вопрос как ловить ошибки? THROW для этого не подходит явно.
Сообщение Добавлено: Ср апр 29, 2009 00:29
  Заголовок сообщения:   Ответить с цитатой
diver писал(а):
1)Насколько я понимаю, и по скромному опыту, в СПФе стеки и юзер область создаются на автомате. С хипом тоже особо не морочился, в случае нужды поток брал себе память по ALLOCATE. про контекст не помню точно, вроде бы на автомате был для каждого свой, хотя могу и ошибиться. Входной/выходной потоки общие, по крайней мере консоль изначально при запуске. Можно сделать, как в swiftx - юзер переменные для ввода-вывода и векторные слова.

да, я в курсе, как создаются в СПФ потоки (и мне оно не нравится)
Вопросы не в том, как оно делается, а что действительно необходимо делать, а что нет.
вот и получается, что контекст для порождаемого процесса скорее всего не должен наследовать контекст родительского (он и так его не наследует, кстати), а скорее всего должен работать в своем собственном окружении.
наследовние консоли тоже большой вопрос, я могу себе представить вариант, когда главный процесс общается с порожденным через терминальный интерфейс- то есть получает данные у процесса в виде строк и отдает решение в виде строк же, работая при этом через стандартные stdin stdout потока(понятно, что это частное решение, однако имеющее право на жизнь). А вот выдавать инфу из другого потока скорее всего не нужно, если только ваш поток не простой пример многозадачного предложения.

diver писал(а):
2) что значит поток упал? как упал, в каком смысле?

есть несколько вариантов:
1) выполнение недопустимой операции\деление на нуль и т.п.
2) выполнение THROW , без предваряющего CATCH
3) автоматическое завершение (ExitThread)

diver писал(а):
можно выделить отдельный контроллирующий поток(ну или пусть это будет основной) и передавать код ошибки и ИД потока ему (самое простое через "глобальные" переменные или структуры), а там пусть он решает, насколько критично падение потока и стоит ли его тормозить или перезапускать.

вот это как раз тот вопрос, который я задал. Как лучше сообщать главному потоку сообщения о критическом завершении потока?
Сообщение Добавлено: Ср апр 29, 2009 00:16
  Заголовок сообщения:   Ответить с цитатой
mOleg писал(а):
1) что нужно инициализировать при запуске нового потока?
- стеки (данных, локальный, возвратов) [тут понятно]
- user область [тут понятно]
- обработчик исключений [тут понятно]
а дальше непонятки идут
- собственный хип потока. [а нужен ли он? USER область у меня лежит в стеке(уже) хип не нужен реально ни для чего]

Думаю что лучше всего активно использовать хип процесса. Слова ядра ALLOCATE и т.п. должны работать с ним. А для хипа потока использовать отдельную библиотеку по мере необходимости.

mOleg писал(а):
- нужно ли инициализировать контекст? [ведь не обязательно будет поиск, компиляция и пр. в словаре]
кроме того, может быть большое и понятное желание для каждого нового потока иметь собственный контекст.

Все так но, в подаляющем большинстве случаев потоки не будут компилировать ни чего.
Опять же отдельная библиотека подключающая "многоконтекстность" решит проблему.
(Интересно кому нибудь раньше такое понадобилось)

mOleg писал(а):
2) что делать, если запущенный процесс поработав упал?
- ничего? завершать поток(как в СПФ)? завершать все потоки и делать BYE?
- сообщать основному потоку о падении порожденного, и если сообщать, то как(передавать код с THROW идея неудачная)?

Ну а если так слово запускающее поток должно положить на стек результат завершения потока.
Когда завершение штатное это 0, если ошибка код ошибки. Обработка соответственно в родительском потоке.
Сообщение Добавлено: Вт апр 28, 2009 15:23
  Заголовок сообщения:   Ответить с цитатой
1)Насколько я понимаю, и по скромному опыту, в СПФе стеки и юзер область создаются на автомате. С хипом тоже особо не морочился, в случае нужды поток брал себе память по ALLOCATE. про контекст не помню точно, вроде бы на автомате был для каждого свой, хотя могу и ошибиться. Входной/выходной потоки общие, по крайней мере консоль изначально при запуске. Можно сделать, как в swiftx - юзер переменные для ввода-вывода и векторные слова.
2) что значит поток упал? как упал, в каком смысле? плохо ещё то, что поток не знает своего ИД после запуска. можно выделить отдельный контроллирующий поток(ну или пусть это будет основной) и передавать код ошибки и ИД потока ему (самое простое через "глобальные" переменные или структуры), а там пусть он решает, насколько критично падение потока и стоит ли его тормозить или перезапускать.
Сообщение Добавлено: Вт апр 28, 2009 08:07
  Заголовок сообщения:  поддержка многозадачности. вопросы  Ответить с цитатой
вот, дошли руки для разборок с тем, как в СПФе устроена многозадачность, и сразу вылазит куча вопросов.

1) что нужно инициализировать при запуске нового потока?
- стеки (данных, локальный, возвратов) [тут понятно]
- user область [тут понятно]
- обработчик исключений [тут понятно]
а дальше непонятки идут
- собственный хип потока. [а нужен ли он? USER область у меня лежит в стеке(уже) хип не нужен реально ни для чего]
- нужно ли инициализировать контекст? [ведь не обязательно будет поиск, компиляция и пр. в словаре]
кроме того, может быть большое и понятное желание для каждого нового потока иметь собственный контекст.
- нужно ли инициализировать входной\выходные потоки, а если нужно, то чем?

2) что делать, если запущенный процесс поработав упал?
- ничего? завершать поток(как в СПФ)? завершать все потоки и делать BYE?
- сообщать основному потоку о падении порожденного, и если сообщать, то как(передавать код с THROW идея неудачная)?
Сообщение Добавлено: Вт апр 28, 2009 05:39

Часовой пояс: UTC + 3 часа [ Летнее время ]


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
phpBB сборка от FladeX // Русская поддержка phpBB