как нам вернуться домой (из Thread'a)?

Тема в разделе "WASM.WIN32", создана пользователем cresta, 11 авг 2004.

  1. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257
    Код (Text):
    1. .data
    2.     hThread dd 0
    3. .code
    4.     invoke CreateThread,NULL,NULL,addr ThreadProc,NULL,0,addr hThread
    5.  
    6. ThreadProc proc lParam:dword
    7.     PrintText "HERE"    ;пишет, что в процедуру попали
    8.     ret                 ;программа вылетает
    9. ThreadProc endp




    Собственно сам вопрос: почему программа вылетает при возвращении из потока? Пробовал через GetExitCodeThread-> ExitThread - всё равно вылетает, пробовал TerminateThread - тот же результат.
     
  2. ssx

    ssx Member

    Публикаций:
    0
    Регистрация:
    19 авг 2003
    Сообщения:
    336
    ThreadProc() же передается 1 параметр. ret 4 наверное надо
     
  3. VOOrDOOluck

    VOOrDOOluck New Member

    Публикаций:
    0
    Регистрация:
    12 июл 2004
    Сообщения:
    51
    Адрес:
    Ukraine
    Посмотри пример айселона

    Х:\masm32\icztutes\TUTE15\THREAD.ASM

    Может поймеш



    mov eax,OFFSET ThreadProc

    invokeCreateThread,NULL,NULL,eax,\ NULL,NORMAL_PRIORITY_CLASS,\ADDR ThreadID

    invoke CloseHandle,eax



    ThreadProc PROC USES ecx Param:lol: WORD

    mov ecx,300000000

    Loop1:

    add eax,eax

    dec ecx

    jz Get_out

    jmp Loop1

    Get_out:

    invoke SendMessage,hwnd,WM_FINISH,NULL,NULL

    ret

    ThreadProc ENDP
     
  4. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257
    ssx

    ret 4 тоже пробовал - не помогло.



    VOOrDOOluck





    Видел я это. И что тут можно такого сокровенного найти? Чем принципиально отличается Icezelion'овский пример от моего вызова? hThread возвращается нормально,процедура вызывается правильно,что положено выполняет. Тем что там CloseHandle? Мне хэндл ещё нужен, поэтому не закрываю. Разницы в применении offset и addr в данном случае нет. Перепробовал все варианты.
     
  5. Asterix

    Asterix New Member

    Публикаций:
    0
    Регистрация:
    25 фев 2003
    Сообщения:
    3.576
    cresta



    Если б вместо твоей PrintText "HERE" там стоял MessageBox и ты спрашивал бы, то было бы понятно, но нихрена ведь неизвестно что творится у тебя в PrintText "HERE", бери дебаггер и проверяй.



    ssx

    > ThreadProc() же передается 1 параметр. ret 4 наверное надо



    Это ж masm однако, там и будет ret 4 после компиляции.
     
  6. Asterix

    Asterix New Member

    Публикаций:
    0
    Регистрация:
    25 фев 2003
    Сообщения:
    3.576
    cresta

    > Мне хэндл ещё нужен, поэтому не закрываю.



    Зачем тебе хэндл если thread уже отработал
     
  7. PavPS

    PavPS New Member

    Публикаций:
    0
    Регистрация:
    24 фев 2004
    Сообщения:
    109
    Адрес:
    Russia
    А почему бы не заиметь какой-нибудь Event, созданный, как NotSet и ожидать после вызова CreateThread WaitFor..этот Event. А в ThreadProc в конце поставить SetEvent. Кажется будет работать. Или чё нитак понял.
     
  8. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257
    Asterix





    Это просто пустая процедура для примера(чтобы не заваливать топик), чтобы понять, почему не возвращается, на деле в процедуре работает цикл, и достаточно долго. И при некоторых обстоятельствах бывает необходимо прервать этот поток, чтобы перезапустить снова, уже с другими параметрами. Поэтому хэндл нужен.

    Есть или нет PrintText - ничего не меняется, он только для того, чтобы показать, что вызов прошёл нормально.

    Случайно определил, что поток нормально отрабатывает и нормально, безо всяких коллизий возвращается, если создается в каком - либо другом месте кода. Отсюда вопрос: как влияет на создание и завершение потока конкретное место, откуда он запускается? Разве не всё равно, откуда вызывать CreateThread?
     
  9. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257
    Asterix





    Это просто пустая процедура для примера(чтобы не заваливать топик), чтобы понять, почему не возвращается, на деле в процедуре работает цикл, и достаточно долго. И при некоторых обстоятельствах бывает необходимо прервать этот поток, чтобы перезапустить снова, уже с другими параметрами. Поэтому хэндл нужен.

    Есть или нет PrintText - ничего не меняется, он только для того, чтобы показать, что вызов прошёл нормально.

    Случайно определил, что поток нормально отрабатывает и нормально, безо всяких коллизий возвращается, если создается в каком - либо другом месте кода. Отсюда вопрос: как влияет на создание и завершение потока конкретное место, откуда он запускается? Разве не всё равно, откуда вызывать CreateThread?
     
  10. Black_mirror

    Black_mirror Active Member

    Публикаций:
    0
    Регистрация:
    14 окт 2002
    Сообщения:
    1.035
    cresta



    Может мы все-таки увидим программу или хотя бы исходник?
     
  11. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257
    Black_mirror

    В аттаче 3 процедуры - две из которых вызывается, и одна, которая вызывается.

    [​IMG] _1187373562__tmp.asm
     
  12. Asterix

    Asterix New Member

    Публикаций:
    0
    Регистрация:
    25 фев 2003
    Сообщения:
    3.576
    cresta

    В процедуре PrepareIndex вовсю юзается ebx но я нигде не видел чтобы он у тебя сохранялся!!
     
  13. q_q

    q_q New Member

    Публикаций:
    0
    Регистрация:
    5 окт 2003
    Сообщения:
    1.706
    cresta

    Согласен с Asterix.

    + в PrepareIndex ты не используешь диапазон из lParam, а всегда используешь [0...Cnt], что содержит Cnt при вызове потока из ListProc?
     
  14. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257
    Asterix



    я пробовал делать pushad/popad+push edi&esi/pop edi&esi, пробовал uses, т.к. видел, что регистры меняются все. Да и в варианте с нормальным вызовом и возвратом я ведь не сохраняю ebx тоже, как с этим быть? И при этом работает.



    q_q



    Cnt содержит кол-во файлов найденых поиском. В одном случае (из ListButtProc) запрашиваю сразу для всех индексы иконок, а в другом (из ListProc) только для тех, кто обозначился по LVN_ODCACHEHINT т.е. от .iFrom до .iTo. Пробовал в обоих вариантах использовать передачу диапазона как через lParam, так и через глобальную переменную.
     
  15. q_q

    q_q New Member

    Публикаций:
    0
    Регистрация:
    5 окт 2003
    Сообщения:
    1.706
    cresta

    а в другом (из ListProc) только для тех, кто обозначился по LVN_ODCACHEHINT т.е. от .iFrom до .iTo.

    Но при этом внутри PrepareIndex используешь Cnt, а не lParam. Ты уверен, что Cnt содержит допустимое значение?



    Другое возможное объяснение, что пришло несколько LVN_ODCACHEHINT и запущено несколько PrepareIndex, а что они могут натворить неизвестно.
     
  16. Asterix

    Asterix New Member

    Публикаций:
    0
    Регистрация:
    25 фев 2003
    Сообщения:
    3.576
    cresta

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



    А что до регистров, esi,edi,ebx в случае использования обязательно нужно сохранять, например в ListProc достаточно было написать uses esi edi ebx и не push'ить/pop'ить далее их в процедуре, masm сделает за тебя всё сам.

    И ещё советую не юзать макросов в таком количестве, особенно не своих, ибо не зная логики их написания и работы ты можешь нарваться на косяк, потому что в них часто находят ошибки, также как и в либе masm32.lib :derisive:
     
  17. q_q

    q_q New Member

    Публикаций:
    0
    Регистрация:
    5 окт 2003
    Сообщения:
    1.706
    Asterix

    предположить что косяк в тех параметрах что ты передаешь

    lParam внутри PrepareIndex не используется.
     
  18. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257
    q_q







    В том случае, когда работает(из ListButtProc) у меня есть уже полное количество-1 (Cnt), поэтому сразу для всех заряжаю. Т.е. от 0 до <количество>-1







    Я проверял это: если не трогать скролл LVN_ODCACHEHINT приходит только один раз. Поток не перезапускается. И пробовал искуственно перезапустить в рабочем варианте поток, не ожидая завершения предыдущего. Ничего страшного в этом нет, просто ещё раз пробежал цикл и вернулся. Да и согласно Icezelion'а допускается несколько одновременно запущенных одноименных потоков.



    Asterix





    Проблема не в процедуре как таковой, она свое дело делает, при любых входных параметрах, и можно отследить каждый проход цикла в ней, всё происходит верно, вот только возврат не получается. Или может получается, но неизвестно куда. C вытекающими отсюда последствиями.
     
  19. q_q

    q_q New Member

    Публикаций:
    0
    Регистрация:
    5 окт 2003
    Сообщения:
    1.706
    cresta

    допускается несколько одновременно запущенных одноименных потоков

    В теории этот так. В реальной жизни надо смотреть на функцию потока. В твоем случае она использует глобальную переменную hIconMem.



    Вообще трудно судить о возможных проблемах не имея полного исходного текста, не имея возможности его собрать и посмотреть на работу в отладчике.
     
  20. Asterix

    Asterix New Member

    Публикаций:
    0
    Регистрация:
    25 фев 2003
    Сообщения:
    3.576
    q_q

    > не имея возможности его собрать



    Угу, к тому же из-за использования кучи макросов не каждый может это собрать, мне например лениво ставить следующий после 8.0 masm32, опять перегонять инклуды и т.д.