Передача структуры в тред.

Discussion in 'WASM.BEGINNERS' started by lust, Apr 21, 2008.

  1. lust

    lust New Member

    Blog Posts:
    0
    Добрый вечер, у меня вот такая ситуация:
    Code (Text):
    1. mov thread_struc.dword_1, WithoutHeaderSize
    2.     mov thread_struc.dword_2, pWithoutHeader
    3.     invoke CreateThread,NULL,NULL,addr ThreadProc ,NULL,0,addr ThreadID
    4.     mov hThread,eax
    Код который заполняет структур и создаёт тред.
    Код самого треда:
    Code (Text):
    1. ThreadProc PROC
    2. .while WithoutHeaderSize==0  
    3.        invoke GetCommandFromServer,WithoutHeaderSize,pWithoutHeader
    4.        mov flag,0
    5.        invoke Sleep, 5000
    6. .endw
    7. ret
    8. ThreadProc endp
    Мне не ясен момент, как данные из структуры уже внутри треда данные будут извлекаться.
    Короче говоря как сделать так,чтоб
    invoke GetCommandFromServer
    работала с данными переданными через структуру?

    Спасибо!
     
  2. Com[e]r

    Com[e]r Com[e]r

    Blog Posts:
    0
    эмн.. в смысле передать структуру треду?
    ну это надо один входной парам функции поставить 32битный, и ему передавать, создавая тред:
    invoke CreateThread,NULL,NULL,addr ThreadProc ,addr thread_struc,0,addr ThreadID

    если я правильно тебя понял..
     
  3. WIN32

    WIN32 Member

    Blog Posts:
    0
    В CreateThread не передается структура, туда передается указатель на структуру.
     
  4. lust

    lust New Member

    Blog Posts:
    0
    ну это я понимаю.
    я не понимаю, как с данными из этой структуры работать в треде.
     
  5. cresta

    cresta Active Member

    Blog Posts:
    0
    Копируешь данные из этой структуры в локальную копию, и работай себе на здоровье с копией.
    Можно работать и с оригиналом структуры, но при этом надо быть уверенным, что другие потоки не будут одновременно лезть в эту структуру, а то получится каша.
     
  6. lust

    lust New Member

    Blog Posts:
    0
    В теории это я понимаю, я не очень представляю как это в коде изложить. если не сложно покажи как внутри треда из адрессованой структуры вытаскивать данные. пожалуйста.
     
  7. Osen

    Osen Рие

    Blog Posts:
    0
    lust
    Ты у себя в коде не правильно задал прототип ThreadProc:
    Code (Text):
    1. ThreadProc PROC lParam:DWORD
    2.   mov  eax,lParam
    3.   assume eax:ptr YOUR_STRUCT
    4.   mov ecx,[eax].ThreadID
    5.   ...
    6.   ret
    7. endp
    ThreadProc будет принимать то, что ты передал в вызове CreateThread последним параметром.
     
  8. lust

    lust New Member

    Blog Posts:
    0
    пасибочки)
     
  9. zoool

    zoool New Member

    Blog Posts:
    0
    Тут есть ньюанс один.
    Пусть исходная структура - в локальных.
    Процедура создает тред и, до старта треда, успевает завершиться. А потом стартует новая процедура.
    Стек потерся. Структура тоже.

    Далее стартует наш созданный тред и получаем вместо структуры кашу.

    Тут как минимум нужно юзать объекты синхронизации, чтобы после старта треда, сам тред успел скопировать структуру себе в локальные.
     
  10. cresta

    cresta Active Member

    Blog Posts:
    0
    Можно не заморачиваться на первых порах с этой синхронизацией.
    Каждому экземпляру потока - свой кусок памяти.

    Code (Text):
    1. .data?
    2. MyStruct struct
    3.     message         db  256 dup(?)  
    4.     digit           dd  ?
    5. MyStruct ends
    6.  
    7.  
    8. .code
    9.  
    10.     ;выделяем память под структуру
    11.     invoke  VirtualAlloc, NULL, sizeof MyStruct, MEM_COMMIT, PAGE_READWRITE
    12.     mov     ebx,eax
    13.     assume  ebx:ptr MyStruct
    14.     ;заполняем структуру данными
    15.     mov     [ebx].digit, 12345678
    16.     invoke  lstrcpy, addr [ebx].message, SADD("SOME TEXT PASSED TO THREAD")
    17.     ;создаем поток и передаем в негo указатель на структуру
    18.     invoke  CreateThread, NULL, NULL, MyThread, ebx, NULL, NULL
    19.        
    20.     assume  ebx:nothing
    21.  
    22.  
    23.  
    24. MyThread proc lParam:DWORD
    25.     LOCAL ms            :MyStruct
    26.     LOCAL buffer[256]   :BYTE
    27.    
    28.     ;копируем переданные в тред данные в локальную структуру-аналог
    29.     invoke  RtlMoveMemory, addr ms, lParam, sizeof MyStruct
    30.     ;освобождаем память, из которой скопировали
    31.     invoke  VirtualFree, lParam, NULL, MEM_RELEASE
    32.    
    33.     ;теперь работа с копией переданных данных (ms)
    34.     invoke  MessageBox, NULL, addr ms.message, NULL, NULL
    35.     ;вывод числа ms.digit через отладочное сообщение
    36.     PrintDec ms.digit
    37.     ret
    38.  
    39. MyThread endp
     
  11. Com[e]r

    Com[e]r Com[e]r

    Blog Posts:
    0
    да нет, просто Sleep(1) делается в таком случае, управление переходит новой треде, и она успевает скопироваться.
     
  12. zoool

    zoool New Member

    Blog Posts:
    0
    Comer_
    а если тредов 2 десятка? И наш тред не с самым высоким приоритетом?

    cresta сказал самый правильный вариант. В таком случае даже не прийдется заморачиваться с синхронизацией и можно создавать suspended-потоки, которые последствии, где-то через эн процедур стартовать.
    Самый удобный вариант.
     
  13. Com[e]r

    Com[e]r Com[e]r

    Blog Posts:
    0
    эмн.. ну тогда аллоцировать перед передачей и забывать о том что что то аллоцировали сразу после передачи =\
    типо и треду не придётся аллоцировать что то или попировать.
     
  14. n0name

    n0name New Member

    Blog Posts:
    0
    cresta
    через кучу быстрее.
     
  15. cresta

    cresta Active Member

    Blog Posts:
    0
    Можно и через кучу. Непринципиально, главное, что у каждого потока своя структура.
    Можно вообще не копировать в локальную, а сразу работать с переданным оригиналом, главное потом после работы не забыть освободить память.