Автор | Сообщение |
|
| постоянный участник
|
Пост N: 166
Зарегистрирован: 27.01.07
|
|
Отправлено: 03.10.09 15:29. Заголовок: Вопрос про потоки в harbour
Что-то не нашел я способа, как можно прекратить выполнение потока, созданного hb_threadStart(). hb_threadJoin() не подходит, так как функция, выполняющаяся в потоке, никогда сама не завершится. Возможно ли такое в принципе? P.S. Вроде бы есть hb_threadQuitRequest(), но в исходниках для нее примечание: цитата: | "this function call can be ignored by the destination thread in some cases. HVM does not guaranties that the QUIT signal will be always delivered." |
| Как быть? Известны ли эти самые "in some cases"?
|
|
|
Ответов - 14
[только новые]
|
|
|
| |
Пост N: 1304
Зарегистрирован: 17.05.05
|
|
Отправлено: 03.10.09 17:30. Заголовок: Возможно это чем то ..
|
|
|
|
| постоянный участник
|
Пост N: 168
Зарегистрирован: 27.01.07
|
|
Отправлено: 03.10.09 20:49. Заголовок: Спасибо, Дима! Эту т..
Спасибо, Дима! Эту тему я читал раз пять. :) Видел, что в xHarbour есть StopThread(). А вот в Harbour аналога не нашел... Может плохо искал? Есть возможность остановить все потоки, но это не подходит. Нужно остановить один поток. Ткните носом, плиз, если такая возможность в Harbour есть. Спасибо.
|
|
|
|
| постоянный участник
|
Пост N: 733
Зарегистрирован: 09.10.06
|
|
Отправлено: 03.10.09 21:23. Заголовок: PSP пишет: Видел, ч..
PSP пишет: цитата: | Видел, что в xHarbour есть StopThread(). А вот в Harbour аналога не нашел... |
| Ну почему же, нашли - hb_threadQuitRequest() цитата: | Известны ли эти самые "in some cases" |
| Вот как пишет об этом автор реализации Przemyslaw Czerpak цитата: | hb_threadQuitRequest() can be ignored by thread in some cases due to race condition. It may happen if thread will overwrite request send by caller simultaneously, f.e. by its own BREAK. I can resolve it but we can also leave it as is and document such behavior as expected or even remove this function. Killing other threads in such way is dangerous and can be used only for some simple situation. It's much safer when user uses his own mechanism to terminate treads in some safe for his code place |
|
|
|
|
|
| постоянный участник
|
Пост N: 169
Зарегистрирован: 27.01.07
|
|
Отправлено: 04.10.09 10:18. Заголовок: Спасибо, Петр! Скажи..
Спасибо, Петр! Скажите, а использование HB_THREAD_INHERIT_PUBLIC гарантирует, что функция, исполняющаяся в потоке, "увидит" изменения глобальных переменным? Я уже для себя этот метод испробывал. Вроде работает...
|
|
|
|
| постоянный участник
|
Пост N: 170
Зарегистрирован: 27.01.07
|
|
Отправлено: 04.10.09 12:35. Заголовок: Сделал следующим обр..
Сделал следующим образом: 1. Создал PUBLIC переменную - массив со списком запущенных потоков. 2. Сделал 2 функции: StartThread и StopThread для запуска и остановки потоков. 3. StartThread после успешного (проверяется) запуска потока добавляет в массив-список номер нового потока. 4. Если нужно поток убить, запускаем StopThread. Она удаляет из массива-списка нужный поток. 5. Функция, работающая в самом потоке, контроллирует наличие собственного номера потока (hb_threadSelf()) в массиве-списке. Если его там нет - завершает работу, поток закрывается. Может слехка топорно, но работает... :)
|
|
|
|
| постоянный участник
|
Пост N: 1917
Зарегистрирован: 12.09.06
|
|
Отправлено: 08.11.11 11:43. Заголовок: PSP пишет: Сделал с..
PSP пишет: цитата: | Сделал следующим образом: 1. Создал PUBLIC переменную - массив со списком запущенных потоков. 2. Сделал 2 функции: StartThread и StopThread для запуска и остановки потоков. 3. StartThread после успешного (проверяется) запуска потока добавляет в массив-список номер нового потока. 4. Если нужно поток убить, запускаем StopThread. Она удаляет из массива-списка нужный поток. 5. Функция, работающая в самом потоке, контроллирует наличие собственного номера потока (hb_threadSelf()) в массиве-списке. Если его там нет - завершает работу, поток закрывается. |
| А можно исходники посмотреть ? Или пример самодостаточный..... Заранее спасибо...
|
|
|
|
| постоянный участник
|
Пост N: 606
Зарегистрирован: 27.01.07
|
|
Отправлено: 08.11.11 15:48. Заголовок: PROCEDURE Main() ..
Пример: #include "hbthread.ch" PROCEDURE Main() PUBLIC _aThreads := {} ? "Start..." StartThread( "threadShowDateTime", "@threadShowDateTime()" ) WAIT StopThread( "threadShowDateTime" ) CLS ? "Stop..." WAIT QUIT FUNCTION StartThread( cName, cFunc ) LOCAL i LOCAL pThId i := AScan( _aThreads, { | x | x[ 1 ] == cName } ) IF i == 0 .and. ! ISNIL( cFunc ) pThId := HB_ThreadStart( HB_THREAD_INHERIT_MEMVARS, &( cFunc ) ) IF hb_isPointer( pThId ) AAdd( _aThreads, { cName, pThId } ) END // IF END // IF RETURN NIL FUNCTION StopThread( cName ) LOCAL i i := AScan( _aThreads, { | x | x[ 1 ] == cName } ) IF i <> 0 ADel( _aThreads, i ) ASize( _aThreads, Len( _aThreads ) - 1 ) END // IF RETURN NIL FUNCTION threadShowDateTime() LOCAL cDate WHILE .T. IF ( AScan( _aThreads, { | x | x[ 2 ] == HB_ThreadSelf() } ) == 0 ) EXIT END // IF hb_DispOutAt( 1, 10, Date(), "G+/N" ) hb_DispOutAt( 1, 20, Time(), "R+/N" ) hb_releaseCPU() END // WHILE RETURN NIL
|
|
|
|
| постоянный участник
|
Пост N: 1920
Зарегистрирован: 12.09.06
|
|
Отправлено: 08.11.11 18:42. Заголовок: Спасибо большое ! :..
Спасибо большое !
|
|
|
|
| постоянный участник
|
Пост N: 607
Зарегистрирован: 27.01.07
|
|
Отправлено: 08.11.11 18:47. Заголовок: Пожалуйста :)..
Пожалуйста :)
|
|
|
|
| постоянный участник
|
Пост N: 1921
Зарегистрирован: 12.09.06
|
|
Отправлено: 08.11.11 19:59. Заголовок: Что-то не собирается..
Что-то не собирается в Харборе. Я вообще-то не силен в нем.... Z:\hb30\bin\hbmk2.exe demo.hbp hbmk2: Compiling Harbour sources... Harbour 3.0.0 (Rev. 16951) Copyright (c) 1999-2011, http://harbour-project.org/ Compiling 'test.prg'... test.prg(6) Warning W0002 Ambiguous reference, assuming memvar '_ATHREADS' test.prg(30) Warning W0001 Ambiguous reference '_ATHREADS' test.prg(35) Warning W0001 Ambiguous reference '_ATHREADS' test.prg(47) Warning W0001 Ambiguous reference '_ATHREADS' test.prg(50) Warning W0001 Ambiguous reference '_ATHREADS' test.prg(51) Warning W0001 Ambiguous reference '_ATHREADS' test.prg(51) Warning W0001 Ambiguous reference '_ATHREADS' test.prg(64) Warning W0001 Ambiguous reference '_ATHREADS' test.prg(76) Warning W0003 Variable 'CDATE' declared but not used in function 'THREADSHOWDATETIME(60)' No code generated. hbmk2: Error: Running Harbour compiler (embedded). 1 (Z:\hb30\bin\harbour.exe) -n2 test.prg -w3 -es2 -o.hbmk\win\bcc\ -iZ:\BCC55\Include -iZ:\hb30\include -undef:.ARCH. -D__PLATFORM__WINDOWS -D__LITTLE_ENDIAN__ -D__ARCH32BIT__ Файл demo.hbp: -3rd=hbide_version=1.0 -3rd=hbide_title=Demo&HB_Tread -3rd=hbide_output=demo -inc -mt -w3 -es2 -gtwvg test.prg
|
|
|
|
| постоянный участник
|
Пост N: 608
Зарегистрирован: 27.01.07
|
|
Отправлено: 08.11.11 20:54. Заголовок: Andrey пишет: Varia..
Andrey пишет: цитата: | Variable 'CDATE' declared but not used in function 'THREADSHOWDATETIME(60) |
| Эту переменную можно убрать. Осталась от рабочего кода. Это ни на что не влияет. Слишком чувствительный уровень. Поэтому столько варнингов. По-умолчанию -w1 Возможно поэтому и Harbour.exe не запускается. Убери -w3 и -es2
|
|
|
|
|
| постоянный участник
|
Пост N: 1924
Зарегистрирован: 12.09.06
|
|
Отправлено: 09.11.11 03:19. Заголовок: На другом теперь выл..
На другом теперь вылетает: Z:\hb30\bin\hbmk2.exe demo.hbp hbmk2: Linking... test.exe Turbo Incremental Link 5.00 Copyright (c) 1997, 2000 Borland Error: Unresolved external '_HB_FUN_ISNIL' referenced from Z:\HB30\HB_TREAD\.HBMK\WIN\BCC\TEST.OBJ hbmk2: Error: Running linker. 2 ilink32.exe @C:\DOCUME~1\86A9~1\LOCALS~1\Temp\tg9zfr.lnk
|
|
|
|
| постоянный участник
|
Пост N: 609
Зарегистрирован: 27.01.07
|
|
Отправлено: 09.11.11 08:04. Заголовок: Добавь в начало #in..
Добавь в начало #include "common.ch"
|
|
|
|
| постоянный участник
|
Пост N: 1925
Зарегистрирован: 12.09.06
|
|
Отправлено: 09.11.11 13:07. Заголовок: PSP - Спасибо БОЛЬШО..
PSP - Спасибо БОЛЬШОЕ ! Заработало.... Конечный текст для желающих test.prg Скрытый текст #include "hbthread.ch" #include "common.ch" PROCEDURE Main() PUBLIC _aThreads := {} CLS ? "Start..." StartThread( "threadShowDateTime", "@threadShowDateTime()" ) ? WAIT StopThread( "threadShowDateTime" ) CLS ? "Stop..." ? WAIT QUIT FUNCTION StartThread( cName, cFunc ) LOCAL i LOCAL pThId i := AScan( _aThreads, { | x | x[ 1 ] == cName } ) IF i == 0 .and. ! ISNIL( cFunc ) pThId := HB_ThreadStart( HB_THREAD_INHERIT_MEMVARS, &( cFunc ) ) IF hb_isPointer( pThId ) AAdd( _aThreads, { cName, pThId } ) END // IF END // IF RETURN NIL FUNCTION StopThread( cName ) LOCAL i i := AScan( _aThreads, { | x | x[ 1 ] == cName } ) IF i <> 0 ADel( _aThreads, i ) ASize( _aThreads, Len( _aThreads ) - 1 ) END // IF RETURN NIL FUNCTION threadShowDateTime() LOCAL cDate WHILE .T. IF ( AScan( _aThreads, { | x | x[ 2 ] == HB_ThreadSelf() } ) == 0 ) EXIT END // IF hb_DispOutAt( 1, 10, Date(), "G+/N" ) hb_DispOutAt( 1, 20, Time(), "R+/N" ) hb_releaseCPU() END // WHILE RETURN NIL
| demo.hbp Скрытый текст # # $Id$ # -3rd=hbide_version=1.0 -3rd=hbide_title=Demo&HB_Tread -3rd=hbide_output=demo -3rd=hbide_xhb=YES # -inc -mt -gtwin test.prg
|
|
|
|
|