CreateThread не создается в КОНСОЛЬНОМ приложении.

Тема в разделе "WASM.WIN32", создана пользователем S_Alex, 27 ноя 2008.

  1. S_Alex

    S_Alex Alex

    Публикаций:
    0
    Регистрация:
    27 авг 2004
    Сообщения:
    561
    Адрес:
    Ukraine
    Сел писать КОНСОЛЬНОЕ приложение, раньше не доводилось (ДОС не в счет).
    Возникла детская проблема. :dntknw:
    Не вытолняется треда запущенная из консольного приложения.

    Она вымолняется, но только если после ее создания задействовать GUI, показать MessageBox например.

    Что-то я не ??? то делаю.

    Код (Text):
    1.         invoke  CreateThread,NULL,NULL,ADDR LSTSDI_Thread,ADDR buffer,NULL,ADDR ID_Thread
    2. ;       invoke  MessageBox,NULL,LastError$(),$TA0(@CatStr('Error: File=',%@FileCur,'; Line=',%@Line,'')),MB_ICONERROR
     
  2. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    Хотелось бы модуль увидеть.
     
  3. mrcrown

    mrcrown Member

    Публикаций:
    0
    Регистрация:
    18 янв 2008
    Сообщения:
    227
    Кстати с такой же темой сталкивался! Так и не разобрался в чем прикол.
    У меня был бесконечный цикл в потоке, так вот он выполнялся только один раз и поток завершался, с ГУЯМи все работало, а в консольке отказывалось.
     
  4. S_Alex

    S_Alex Alex

    Публикаций:
    0
    Регистрация:
    27 авг 2004
    Сообщения:
    561
    Адрес:
    Ukraine
    Clerk
    Там пусто. Только отладка.
    Код (Text):
    1. LSTSDI_Thread   proc lpFileName:DWORD
    2.         PrintText   "Begin Thread"
    3. ExitTR:    
    4.     invoke  ExitThread,NULL
    5.     ret
    6.  
    7. LSTSDI_Thread endp
    Так вот эта строка не выводиться пока GUI не задействовать.
     
  5. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    У меня работает, нужен скомпиленый модуль.
     
  6. q_q

    q_q New Member

    Публикаций:
    0
    Регистрация:
    5 окт 2003
    Сообщения:
    1.706
    S_Alex
    Определись "CreateThread не создается" или "строка не выводиться пока GUI не задействовать"?
     
  7. S_Alex

    S_Alex Alex

    Публикаций:
    0
    Регистрация:
    27 авг 2004
    Сообщения:
    561
    Адрес:
    Ukraine
    q_q
    В потоке должна выводиться строка в окно отладки.
    Так вот оной нет.

    Заметил такую особенность:
    Работает если програму запустить из уже запущенной КОНСОЛИ. ( CMD )
    А если запускать из *УЯ (Г), то не хочет работать.
     
  8. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    дай угадаю - дальше у теб идет ret или ExitProcess ?

    и то и другое завершает процесс вместе со ВСЕМИ потоками.
    вызов MessageBox давал время "отложить" завершение процесса и шанс второму потоку на выполнение.
     
  9. S_Alex

    S_Alex Alex

    Публикаций:
    0
    Регистрация:
    27 авг 2004
    Сообщения:
    561
    Адрес:
    Ukraine
    Great
    Спасибо за подсказку.
    Оно самое.
    Слипал очень мало времени не хватало времени.
    Увеличил время - всё заработало.
    Всё. Всем СПСБ. Тема закрыта.
     
  10. Black_mirror

    Black_mirror Active Member

    Публикаций:
    0
    Регистрация:
    14 окт 2002
    Сообщения:
    1.035
    Great
    Если в главном потоке стоит ret, то вызывается ExitThread (ExitProcess вызывается если это последний поток), остальные потоки продолжат работу.
     
  11. q_q

    q_q New Member

    Публикаций:
    0
    Регистрация:
    5 окт 2003
    Сообщения:
    1.706
    S_Alex
    Imho констатировать факт создания потока надо по результату, возвращаемому функцией CreateThread.

    Great
    … ret ... завершает процесс вместе со ВСЕМИ потоками.
    Например, DbgView показывает сообщение от
    Код (Text):
    1. .386
    2. .model flat, stdcall
    3. option casemap:none
    4.  
    5. .nolist
    6. include windows.inc
    7. include kernel32.inc
    8. includelib kernel32.lib
    9. .list
    10.  
    11. .const
    12. sz  db  'Hello from thread',0
    13.  
    14. .code
    15. align 4
    16. foo proc    p : LPARAM
    17.     invoke  OutputDebugString, offset sz
    18.     mov eax,p
    19.     ret
    20. foo endp
    21.  
    22. align 4
    23. start:
    24.     push    0
    25.     mov eax,esp
    26.     invoke  CreateThread, NULL, 0, offset foo, 1, 0, eax
    27.     pop eax
    28.     ret
    29. end start
     
  12. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    q_q
    тут race condition - кто быстрее? код потока нового, которому надо "всего-то" сделать OutputDebugString, или же main thread, которому после возврата (ret) в BaseProcessStart надо сделать ExitProcess - весьма объемную процедуру, состоящую из вызовов ZwTerminateProcess, LdrShutdownProcess, CsrClientCallServer, ZwTerminateProcess

    Вообщем если бы кода во втором потоке было побольше, он бы далеко не весь выполнился
     
  13. q_q

    q_q New Member

    Публикаций:
    0
    Регистрация:
    5 окт 2003
    Сообщения:
    1.706
    Great
    Изменил код потока на
    Код (Text):
    1. foo proc    p : LPARAM
    2.     invoke  OutputDebugString, offset sz
    3.     invoke  Sleep, 10000
    4.     invoke  OutputDebugString, offset sz
    5.     mov eax,p
    6.     ret
    7. foo endp
    DbgView, после непродолжительной задержки, показал
    Код (Text):
    1. 00000000    0.00000000  [764] Hello from thread
    2. 00000001    9.99959469  [764] Hello from thread
    > если бы кода во втором потоке было побольше, он бы далеко не весь выполнился
    Если Sleep'а недостаточно или нужен особенный код, то укажи какой.
     
  14. KeSqueer

    KeSqueer Сергей

    Публикаций:
    0
    Регистрация:
    19 июл 2007
    Сообщения:
    1.183
    Адрес:
    Москва
    Great,
    Black_mirror прав, однако
    Такой код выводит сообщение и ждет положенные полторы секунды:
    Код (Text):
    1. format pe console
    2. include 'win32wxp.inc'
    3.  
    4. INFINITE        equ 0xFFFFFFFF
    5.  
    6. .data
    7.         dwThreadID      dd ?
    8.         hThread         dd ?
    9.         dwExitCode      dd ?
    10.  
    11. .code
    12.         szExample       TCHAR 'Example', 10, 0
    13.  
    14. proc    ThreadProc, lParam
    15.  
    16.         invoke  Sleep, 1500
    17.         invoke  WriteConsole, <invoke GetStdHandle, STD_OUTPUT_HANDLE>, szExample, <invoke lstrlen, szExample>, 0, 0
    18.         invoke  Sleep, 1500
    19.         mov     eax, 0x11223344
    20.         ret
    21.  
    22. endp
    23.  
    24.  
    25. start:  invoke  CreateThread, 0, 0, ThreadProc, 0, 0, dwThreadID
    26.         mov     [hThread], eax
    27.         ;invoke  WaitForSingleObject, [hThread], INFINITE
    28.         ;invoke  GetExitCodeThread, [hThread], dwExitCode
    29.         invoke  CloseHandle, [hThread]
    30.         ret
    31.         ;invoke  ExitProcess, eax
    32.  
    33. .end start
    но все же лучше не надеяться на это, а использовать WaitForSingleObject/ExitProcess IMHO
     
  15. Black_mirror

    Black_mirror Active Member

    Публикаций:
    0
    Регистрация:
    14 окт 2002
    Сообщения:
    1.035
    Great
    Код (Text):
    1. thread:
    2.         ret
    3.  
    4. start:
    5.         invoke CreateThread,0,0,thread,0,CREATE_SUSPENDED,esp,0
    6.         pop eax
    7.         ret
    и где тут "race condition"? что помешало главному потоку процесс прибить?!
     
  16. Velheart

    Velheart New Member

    Публикаций:
    0
    Регистрация:
    2 июн 2008
    Сообщения:
    526
    Можно после CreateThread просто вызвать ExitThread, тогда процесс завершится только с завершением последнего потока.
     
  17. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    q_q
    Сори, напутал. После RET'а виндой делается ExitThread, а не ExitProcess.
     
  18. Velheart

    Velheart New Member

    Публикаций:
    0
    Регистрация:
    2 июн 2008
    Сообщения:
    526
    Great
    А не могло быть такого, что в какой-нибудь версии вызывался ExitProcess, я просто точно помню, что относительно недавно эксперементировал и если из главного потока выходил просто через ret, то были какие-то глюки с выполнением остальных потоков, и вроде бы под отладчиком я попадал в ExitProcess, хотя возможно я пример как-то криво написал тогда...
     
  19. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    Velheart
    Консоль:
    Поток завершился, WaitForSingleObject прервалась, завершилась консольная прога, попали в ExitProcess.

    Гуи:
    Поток завершился, гуи работает дальше.

    KeSqueer
    Black_mirror прав, однако
    Походу он всегда прав.

    P.S Читаем Рихтера.
     
  20. Sol_Ksacap

    Sol_Ksacap Миша

    Публикаций:
    0
    Регистрация:
    6 мар 2008
    Сообщения:
    623
    Имхо такая путанница с ret\ExitThread\ExitProcess из-за того, что в стартовом коде CRT сразу после вызова main\WinMain действительно следует вызов ExitProcess (всё же предваряемый вызовом статических деструкторов; единственная реальная необходимость в ExitProcess после WinMain - предотвращение исполнение каких-либо других потоков после отработки этих деструкторов).