[Delphi] Работа с потоками

Discussion in 'С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby' started by Kandi, 28 Nov 2010.

  1. Kandi

    Kandi Member

    Joined:
    18 Nov 2009
    Messages:
    344
    Likes Received:
    17
    Reputations:
    0
    Может кто нибудь рассказать как можно правильно и красиво дождаться работы всех потоков?! Собственно имеется TThreadClass который запускается в 3 параллельных потока:
    Code:
    ThreadClass := TThreadClass.Create(False);
    ThreadClass.FreeOnterminate := False;
    ThreadClass.OnTerminate := EndThread;
    Code:
    procedure TMainForm.EndThread();
    begin
      ThreadClass.Free;
      Memo1.lines.add('Завершил!');
    end;
    
    Собственно сабж в том, что когда главный поток завершает работу то его наследники уже не могут работать. И мне очень бы хотелось узнать как ожидать пока наследники не закончат своё дело?
     
  2. 1n0y

    1n0y Active Member

    Joined:
    9 May 2009
    Messages:
    272
    Likes Received:
    276
    Reputations:
    2
    быдлокод-метод: сделай глобальный счетчик потоков. при запуске считай кол-во потоков, а при завершении любого - отнимай от общего кол-ва потоков единицу. далее всё просто - if potcount=0 then ...

    нутыпонял :)

    upd: ну или если надо ждать - то while potcount<>0 do sleep(100);
     
  3. Kandi

    Kandi Member

    Joined:
    18 Nov 2009
    Messages:
    344
    Likes Received:
    17
    Reputations:
    0

    не совсем получается однако,
    while potcount<>0 do sleep(100);
    в самом потоке не хочет работать, не известно почему, ставлю вроде бы в CreateSection) а в OnTerminate зависает форма. Может есть программное решение данной проблемы?
     
  4. RedFern.89

    RedFern.89 Member

    Joined:
    20 Jan 2010
    Messages:
    557
    Likes Received:
    45
    Reputations:
    0
    Kandi, как закончишь работу с потоками, выложишь какуюнить демку по работе с потоками. (а точнее с многопоточностью) очень надо.
     
  5. 1n0y

    1n0y Active Member

    Joined:
    9 May 2009
    Messages:
    272
    Likes Received:
    276
    Reputations:
    2
    может заменить слип на Application.ProcessMessages(); ?
     
  6. Kandi

    Kandi Member

    Joined:
    18 Nov 2009
    Messages:
    344
    Likes Received:
    17
    Reputations:
    0
    кто бы мне выложил демку по поводу моей проблемы :D
    что тебя именно интересует с многопоточностью?) :confused:
     
  7. RedFern.89

    RedFern.89 Member

    Joined:
    20 Jan 2010
    Messages:
    557
    Likes Received:
    45
    Reputations:
    0
    Kandi, обсолютно все) видишь ли, у меня одна идея появилась и если я ее осуществлю, то таких вопросов (про мноргопоточность) на этом форуме будет куда меньше или не будлет вовсе, да и сам разберусь во всем)) да и вообще это значительно облегчит людям жизнь :)
     
    #7 RedFern.89, 29 Nov 2010
    Last edited: 29 Nov 2010
  8. Chrome~

    Chrome~ Elder - Старейшина

    Joined:
    13 Dec 2008
    Messages:
    937
    Likes Received:
    162
    Reputations:
    27
    При нормальном оформлении такой код являеться очень даже неплохим и гарантирует корректную работу с потоками. Также этот метод действительно позволяет отследить завершение всех потоков.
     
    1 person likes this.
  9. _nic

    _nic Elder - Старейшина

    Joined:
    5 May 2006
    Messages:
    651
    Likes Received:
    54
    Reputations:
    3
    WaitForSingleObject
     
  10. Kandi

    Kandi Member

    Joined:
    18 Nov 2009
    Messages:
    344
    Likes Received:
    17
    Reputations:
    0
    ладно предположим, в кнопке запуска в цикле мы добавим Inc(Thread_Count); // глобалка
    а в OnTerminate := EndThread;

    Code:
    procedure EndThread(Sender: object);
    begin
      Dec(Thread_Count);
      .....
      bla bla code
      .....
      while Thread_Count<>0 do Application.ProcessMessages();
    end;
    так будет роботать? Оо у меня так че то не получалось! :(

    Достойный ответ конечно, но информацию об этой вещи не смог достойную найти! :(
     
  11. 1n0y

    1n0y Active Member

    Joined:
    9 May 2009
    Messages:
    272
    Likes Received:
    276
    Reputations:
    2
    хз вощем, что у тебя там. я обычно делаю всё не так (скорее всего - не правильно, зато работает). никакого ендтреада у меня нету. просто:

    закускаю стопицот потоков, считаю их. и если нужно выполнить какое-либо действие в конце последним потоком - просто ставлю if potcount=0 then..



    potok.ехеcute
    begin
    ...
    ..
    dec(potcount);
    if potcount=0 then..

    end;

    и всё.

    ps: Thread_Count не забываешь перед запуском потоков приравнивать к нулю? :)
     
  12. Kandi

    Kandi Member

    Joined:
    18 Nov 2009
    Messages:
    344
    Likes Received:
    17
    Reputations:
    0
    нет вроде бы не забываем) ну a FreeOnTerminate := False? или True? ты ставишь?

    ...
     
    #12 Kandi, 29 Nov 2010
    Last edited: 29 Nov 2010
  13. 1n0y

    1n0y Active Member

    Joined:
    9 May 2009
    Messages:
    272
    Likes Received:
    276
    Reputations:
    2
    Thread:=tThread.Create(true);
    Thread.FreeOnTerminate:=true;
    Thread.Priority:=tpNormal;
    Thread.Resume;

    вот так делаю.
     
  14. _nic

    _nic Elder - Старейшина

    Joined:
    5 May 2006
    Messages:
    651
    Likes Received:
    54
    Reputations:
    3
    Зря ты так.Я понимаю что в твоем возрасте с вниманием и поиском инфы проблематично.Но та функция ждет пока поток с таким то указтелем не проработает с только то времени :) (INFINITE вечность)учи инглишь и гугл)
     
  15. GhostOnline

    GhostOnline Active Member

    Joined:
    20 Dec 2008
    Messages:
    723
    Likes Received:
    110
    Reputations:
    22
    Сплошной идиотизм хоспаде.
    Какая-то херь. Процедурный тип у OnTerminate должен принимать один параметр типа TObject. То что ты написал даже компилироваться не должно.
    Дальше ThreadClass.Free - это что? У тебя объект еще существует, более того он и сгенрировал событие а ты ему Free раньше времени.
    С терминологией тоже херь. Что за главный поток и наследники? Обычно главным потоком называют тот в котором крутится петля обработки сообщений. Он заканчивает свою работу вместе с программой.
    ОМГ CreateSection ?
    Такое нельзя в крит. секцию ставить.
    Подумай сам: один поток заходит в критическую секцию и ждет когда все завершатся, а остальные не могут завершиться ведь КС занята. Получаем дедлок.
    А OnTerminate выполняется в контексте основного потока программы, Sleep там конечно приведет к зависанию. Об этом я тебе уже писал.
    Чем тебя не устравивает демка которую сделал для тебя я? Счетчик потоков, ожидание завершения работы - все это есть :confused:
    блеать а нахера тебе крутится в цикле
    блокируя этим все на свете. другие потоки даже не смогут дойти до
    потому что VCL - поток будет занят бесконечным циклом

    Решение я тебе уже давно дал, и в первом ответе похожее дали -
     
    1 person likes this.
  16. Kandi

    Kandi Member

    Joined:
    18 Nov 2009
    Messages:
    344
    Likes Received:
    17
    Reputations:
    0
    Ну собственно, всем спасибо кто помог, G-Host отдельное спасибо за пример :)
     
  17. Безработный

    Joined:
    25 Jun 2010
    Messages:
    0
    Likes Received:
    1
    Reputations:
    0
    _http://avtuh.ru/2010/04/09/delphi-dopolnitelnyj-potok-v-programme.html
    _http://avtuh.ru/2010/10/10/delphi-videourok-mnogopotochnost-i-sinxronizaciya.html