Ну продолжим с потоках.
Что делать со стеком, когда завершается поток?
Память для стек потока я выделяю динамически и ее надо освободить.
Но поток не может освободит свой собственный стек.
А другие потоки приложения просто не знают что поток завершился. Как быть?
Вопросы по некоторым функциям...
Отчего же?johnfound wrote: Но поток не может освободит свой собственный стек.
А другие потоки приложения просто не знают что поток завершился. Как быть?
Code: Select all
mcall 68,13,[thread_stack_2]
mcall -1 ; close this program
Как "отчего же"? Если память стека освобождается после 68,13 то откуда взялся аддрес возврата чтобы поток, потом выполнил mcall -1? И даже если чудесным образом поток вернулся куда надо, то где mcall -1 будет запоминать свой адрес возвратa?Mario wrote:Отчего же?В zSea у меня это вполне работает.Code: Select all
mcall 68,13,[thread_stack_2] mcall -1 ; close this program
Мне кажется что у тебя поток должен умирать из за GPF, а не из за mcall -1.
Вот не надо путать людей макросами.
Code: Select all
mov eax, 68
mov ebx, 13
mov ecx, [thread_stack_2]
int 0x40
mov eax, -1
int 0x40
Теоретически да, однако на практике все работает - никакой ругани на доску отладки не выводится.johnfound wrote:Мне кажется что у тебя поток должен умирать из за GPF, а не из за mcall -1.
Но так выходит что можно ф.-1 вообще не вызывать и так поток завершится на возвращения из ф.68, а может и раньше.
Ничего там не умирает по GPF. Эти функции не обращаются к стеку приложения.
Но если так страшно, есть простое решение
Но если так страшно, есть простое решение
Code: Select all
mov esp, tmp_stack
mov eax, 68
mov ebx, 13
mov ecx, [thread_stack_2]
int 0x40
mov eax, -1
int 0x40
rd 4 ;с большим запасом
tmp_stack:
Просто, но не совсем. Я тоже думал сделать так, но дело в том, что это будет работать правильно если всегда завершается только один поток. А в многопоточном приложении это совсем невозможно гарантировать.Serge wrote:Ничего там не умирает по GPF. Эти функции не обращаются к стеку приложения.
Но если так страшно, есть простое решениеCode: Select all
mov esp, tmp_stack mov eax, 68 mov ebx, 13 mov ecx, [thread_stack_2] int 0x40 mov eax, -1 int 0x40 rd 4 ;с большим запасом tmp_stack:
Поэтому приходим к следующего вопроса: Как реализовать мьютексов в Колибри?
johnfound
Это всегда будет работать правильно, если хранить базовый адрес стека в вершине стека создаваемого потока.
Это всегда будет работать правильно, если хранить базовый адрес стека в вершине стека создаваемого потока.
Зачем изобретать лисопеды, если простое как лопата решение уже работает?
Mario
Если ты создаёшь произвольное число потоков одной переменной thread_stack_2 на всех не хватит.
Если ты создаёшь произвольное число потоков одной переменной thread_stack_2 на всех не хватит.
Зачем?Serge wrote:Mario
Если ты создаёшь произвольное число потоков одной переменной thread_stack_2 на всех не хватит.
У меня на каждый задуманный поток свой стек и своя переменная:
Spoiler:
Code: Select all
;---------------------------------------------------------------------
; clear bacground thread
clear_thread_stack:
dd 0
;----------------------
; window option
thread_stack_7:
dd 0
;----------------------
; window error message
thread_stack_6:
dd 0
;----------------------
; window set sort mode
thread_stack_5:
dd 0
;----------------------
; window background
thread_stack_4:
dd 0
;----------------------
; window about
thread_stack_3:
dd 0
;----------------------
; file info
thread_stack_2:
dd 0
;----------------------
; file open
thread_stack:
dd 0
;---------------------------------------------------------------------
А предыдущий пост мой касался самоубиения вторичного потока, без всяких извратов с подменой значения ESP. Если стек для сепуку не нужен, как ты сам доказал, то зачем придумывать специальный лисопед?
Я создаю произвольное количество потоков - потому что пишу библиотеку, которая должна этого уметь. И при этом у меня потоки должны заканчивать на ret (но это совсем другая история).
Давайте уточнить напоследок: Чтобы вызывать int $40, стек приложению совершенно не нужен. Правильно?
Давайте уточнить напоследок: Чтобы вызывать int $40, стек приложению совершенно не нужен. Правильно?
Стек нужен для сохранения регистров. Если функция их не изменяет или вообще не возвращает значений, то не нужен - это же прерывание. В общем все зависит о реализации вызываемой функции.johnfound wrote:Давайте уточнить напоследок: Чтобы вызывать int $40, стек приложению совершенно не нужен. Правильно?
Мои знания о прерываниях находятся на ниво 8088 - там стек обязательно нужен.
А где запоминаются адрес возврата и регистр флагов?
А где запоминаются адрес возврата и регистр флагов?
Who is online
Users browsing this forum: No registered users and 34 guests