Форум » [x]Harbour » [translate] BackGround » Ответить

[translate] BackGround

Dima: Кто то может перевести help к этим функциям на русский ? HB_BackGroundActive() Queries and/or changes the activity of a single background task. HB_BackGroundAdd() Adds a new background task. HB_BackGroundDel() Removes a background task from the internal task list. HB_BackGroundReset() Resets the internal counter of background tasks. HB_BackGroundRun() Enforces execution of one or all background tasks. HB_BackGroundTime() Queries or changes the wait interval in milliseconds after which the task is executed. HB_IdleAdd() Adds a background task for being executed during idle states. HB_IdleDel() Removes a task from the list of idle tasks. HB_IdleReset() Resets the internal counter of idle tasks. HB_IdleSleep() Halts idle task processing for a number of seconds. HB_IdleSleepMSec() Queries or changes the default time interval for idle task processing. HB_IdleState() Signals an idle state. HB_IdleWaitNoCPU() Toggles the mode for CPU usage in Idle wait states. SET BACKGROUND TASKS Enables or disables the activity of background tasks. SET BACKGROUNDTICK Defines the processing interval for background tasks.

Ответов - 96, стр: 1 2 3 4 5 All

Dima: Петр Спасибо !!!

Dima: Петр В чем разница ? Похоже и в том и другом случае все завершается коректно. [pre2] PROCEDURE main LOCAL threadA, threadB threadB := StartThread( @MyFuncB()) threadA := StartThread( @MyFuncA() ) JoinThread( threadA ) JoinThread( threadB ) RETURN [/pre2] ********************************* [pre2] PROCEDURE main LOCAL threadA, threadB threadB := StartThread( @MyFuncB()) threadA := StartThread( @MyFuncA() ) WaitForThreads() RETURN [/pre2] И еще вопросы. Можно ли в функции MyFuncB() , стартовать еще потоки на выполнение (StartThread) ? Для чего нужна функция HB_MutexCreate() ?

Dima: Петр Будет ли верно работать такой код или нужно что то поправить ? [pre2] STATIC lExit Global Puts Global cserv PROCEDURE main LOCAL threadA, threadB lExit := .F. puts:="C:\TEST" cserv:="\\servak\sys\sklad" threadB := StartThread( @MyFuncB()) threadA := StartThread( @MyFuncA()) JoinThread( threadA ) JoinThread( threadB ) RETURN ************************* func MyFuncB() local adir LOCAL aFile local aExtract local nind:=0 DO WHILE !lExit adir:=Directory(puts+"A*.zip") if len(adir)>0 FOR EACH aFile IN aDir aExtract := hb_GetFilesInZip( puts+afile[1]) IF HB_UNZIPFILE( puts+afile[1],,,,cserv,aExtract) nind:=val(substr(afile[1],2,at("_",afile[1])-1)) StartThread(Test(nind) // открываем одни и те же базы с разными Alias WaitForThreads() // в зависимости от nind ferase(puts+afile[1])==0 ENDIF next endif ThreadSleep(100) enddo RETURN nil ****************** PROCEDURE MyFuncA( ) DO WHILE inkey( 0.1 ) != 27 ENDDO lExit := .T. RETURN [/pre2]


Петр: Dima пишет: В чем разница ? Похоже и в том и другом случае все завершается коректно В таком контексте - да. Но нужно учесть, что функция WaitForThreads ( в Harbour hb_threadWaitForAll ) приостанавливает выполнение главного потока, дожидаясь пока не завершат свою роботу все остальные потоки. В случае, если до вызова WaitForThreads все вторичные потоки уже завершили свою роботу, функция просто немедленно завершит свое выполнение. Главный поток создается неявно и в главном потоке выполняется функция Main (_AppMain). Использование функции WaitForThreads в вторичных потоках (отличных от главного) не имеет смысла, так как функция просто немедленно возвратит управление вызывающему потоку ничего не делая. Иными словами использовать WaitForThreads можно только в функции Main (_AppMain). Функцию же JoinThread() можно вызывать как из главного, так и из вторичных потоков. Функция JoinThread() ( в Harbour hb_threadJoin ) приостанавливает выполнение того потока, из которого она была вызвана, дожидаясь пока не завершит свою роботу поток, указатель на который был передан функции в виде аргумента. В случае, если до вызова JoinThread( thread) поток thread уже завершил свою роботу, функция просто немедленно завершит свое выполнение. Будет ли верно работать такой код или нужно что-то поправить ? Нужно править. См. выше.

Петр: Dima пишет: Можно ли в функции MyFuncB() , стартовать еще потоки на выполнение (StartThread) ? Для чего нужна функция HB_MutexCreate() ? 1) Можно, только, ну ты сам понимаешь 2) Для разрешения возможных коллизий при одновременном доступе к ресурсам ( например, к переменным ) из разных потоков. Механизм чем-то похожий на блокировки записей, таблиц.

Петр: Dima пишет: ? AdsIsServerLoaded(CurDrive()+":\"+CurDir()+"\DBF\"+"data_nul.dbf") // локальный ADS , возвращает 0 Причем до вызова всех StartThread , AdsIsServerLoaded работает правильно Не могу подтвердить, AdsIsServerLoaded( cPath ) при доступном (существующем) cPath для локального ADS возвращает 1, как и положено. P.S. Имя файла ( AdsIsServerLoaded(CurDrive()+":\"+CurDir()+"\DBF\"+"data_nul.dbf") ) задавать не нужно, все равно оно при проверке отбрасывается.

Dima: Петр пишет: Не могу подтвердить, AdsIsServerLoaded( cPath ) при доступном (существующем) cPath для локального ADS возвращает 1, как и положено. В фунции запущенной через StartThread ? Грю же что проверил , не пашет. До StartThread вернет 1 В функции запущенной в поток вернет 0 ЗЫ Путь cPath одинаков и он существует ! Что касается имени файла , спасибо , поправлю !

Dima: Пример конечно грубый , но понятно где не пашет. Юзаем AdsSetServerType(3) // Local + Remote Ads ........ ? AdsIsServerLoaded(CurDrive()+":\"+CurDir()+"\DBF\") // ==1 threadB:=StartThread(@Test()) В функции Test ? AdsIsServerLoaded(CurDrive()+":\"+CurDir()+"\DBF\") // ==0 всегда в режиме MT (Xharbour)

Петр: Я тестировал на этом - ? res := AdsIsServerLoaded( CurDrive()+":\"+CurDir() ) == 1 [pre2]STATIC lExit // PROCEDURE main LOCAL threadA, threadB, threadC lExit := .F. threadC := StartThread( @TestAds() ) threadB := StartThread( @MyFuncB() ) threadA := StartThread( @MyFuncA() ) WaitForThreads() // RETURN /* */ STATIC FUNCTION MyFuncA( ) DO WHILE inkey( 0.1 ) != 27 ENDDO lExit := .T. // RETURN LastKey() /* */ STATIC FUNCTION MyFuncB( ) LOCAL nCounter, nI DO WHILE !lExit nCounter := 0 FOR nI := 1 TO 2 nCounter ++ NEXT nI ThreadSleep(20) END // RETURN nCounter /* */ FUNCTION TestAds( cDBF ) LOCAL cField, res IF cDbf == NIL cDbf := "test" ENDIF RddSetDefault( "ADSCDX" ) AdsSetServerType( 1 ) AdsSetFileType( 2 ) ? res := AdsIsServerLoaded( CurDrive()+":\"+CurDir() ) IF File( "adstest.dbf" ) FErase( "adstest.dbf" ) ENDIF USE (cDBF) ALIAS "MY" EXCLUSIVE IF ! File( "adstest.dbf" ) COPY STRUCTURE TO adstest ENDIF USE adstest ALIAS "MY2" DO WHILE RecCount() < 1000 ? "Copying..." APPEND ALL FROM test ENDDO cField := Lower( FieldName(1) ) INDEX ON &cField TO (cField) ThreadSleep(20) // RETURN res [/pre2]

Dima: Петр пишет: Я тестировал на этом - Xharbour ?

Dima: Петр пишет: RddSetDefault( "ADSCDX" ) AdsSetServerType( 1 ) AdsSetFileType( 2 ) По ходу эти вещи я объявил в основной процедуре (Main) , может в этом дело.............

Петр: Dima пишет: По ходу эти вещи я объявил в основной процедуре (Main) , может в этом дело............. Очень даже может быть Если так то 0 и ADSCDX/5033 Open error: test.

Петр: Dima пишет: Xharbour ? - угу

Петр: в Harbour - все Ok и так и так. И вообще в Harbour MT (и не только MT) на порядок лучше.

Dima: Петр пишет: И вообще в Harbour MT (и не только MT) на порядок лучше.

Dima: Петр Вроде чуть продвинулся. В примере ниже из потока threadB , запускаю 20 потоков и все корректно завершается на первый взгляд и без падений. Можешь прокоментировать или что то добавить ? [pre2] STATIC lExit PROCEDURE main local threadA, threadB cls lExit := .F. threadB := StartThread( @MyFuncB()) threadA := StartThread( @MyFuncA()) JoinThread( threadA ) JoinThread( threadB ) RETURN ************************* func MyFuncB() local nind local tst:=20 local anind:=array(tst) DO WHILE !lExit for nind=1 to tst anind[nind]:=StartThread(@Test(),nind) next for nind=1 to len(anind) if IsValidThread(anind[nind]) JoinThread(anind[nind]) endif next enddo ThreadSleep(20) RETURN nil ************** Func Test(nrow) local i for i=1 to 1000 DispOutAt(nRow,10,str(i,5)) next return nil ****************** Func MyFuncA( ) DO WHILE inkey( 0.1 ) != 27 ENDDO lExit := .T. RETURN nil [/pre2]

Dima: Чуть усложняем функцию MyFuncB ....полет нормальный однако [pre2] func MyFuncB() local nind local tst local anind DO WHILE !lExit tst:=HB_RandomInt(1,20) anind:=array(tst) for nind=1 to tst anind[nind]:=StartThread(@Test(),nind) next for nind=1 to len(anind) if IsValidThread(anind[nind]) JoinThread(anind[nind]) endif next enddo RETURN nil [/pre2]

Петр: Dima пишет: В примере ниже из потока threadB , запускаю 20 потоков и все корректно завершается на первый взгляд и без падений. Ну падений не должно быть, ты же используешь IsValidThread. Все довольно корректно написано.

Dima: И снова небольшая модификация [pre2] func MyFuncB() local nind local tst local anind DO WHILE !lExit tst:=HB_RandomInt(1,20) anind:=array(tst) for nind=1 to tst anind[nind]:=StartThread(@Test(),nind) ThreadSleep(20) // иначе IsValidThread не всегда вернет .T. next for nind=1 to len(anind) if IsValidThread(anind[nind]) JoinThread(anind[nind]) endif next enddo RETURN nil [/pre2] [pre2] Func Test(nrow) local i for i=1 to 1000 DispOutAt(nRow,10,str(i,5)) ThreadSleep(1) // что бы проц не грузило :) next return nil [/pre2]

Петр: Dima пишет: ThreadSleep(20) // иначе IsValidThread не всегда вернет .T. Да - в Harbour ThreadSleep не нужен, да и нет его , в xHarbour ThreadSleep сводится к банальному sleep. Поскольку Windows никогда не была системой реального времени, вызов ThreadSleep(nTimeOut) с nTimeOut < 20 не желателен, хотя и возможен.



полная версия страницы