Funkce několikrát spuštěná zároveň – Visual Basic – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu
Reklama
Reklama

Funkce několikrát spuštěná zároveň – Visual Basic – Fórum – Programujte.comFunkce několikrát spuštěná zároveň – Visual Basic – Fórum – Programujte.com

 

Hledá se programátor! Plat 1 800 € + bonusy (firma Boxmol.com)
Kartik
~ Anonymní uživatel
35 příspěvků
9. 5. 2016   #1
-
0
-

Ahoj,

Předpokládám, že je teoreticky možné možné, že i funkce z VBA může být spuštěna v jeden moment několikrát v různých vláknech, ale jde mě o to jak to funguje obecně. Nevím jak je to určitě, ale tipnul bych, že v paměti je funkce jen jedna a tedy případné několikanásobné spuštění bude používat stejné proměnné ve funkci, což povede k blbosti, nebo rovnou chybě v přístupu. Rád bych tedy věděl jak se tento problém řeší, aby funkce šla bezpečně použít, i když je volána několikrát ve stejný čas.

Nahlásit jako SPAM
IP: 90.178.131.–
Reklama
Reklama
q
~ Anonymní uživatel
219 příspěvků
10. 5. 2016   #2
-
0
-

Jestli "proměnnými ve funkci" myslíš lokální proměnné, tak ty má každé vlákno vlastní.

Ale pokud odkazují na nějaký globální/sdílený objekt, tak si ho ty funkce (vlákna) mohou měnit pod rukama. To může být problém a řeší se to synchronizací - prostě vytvoříš nějaký zámek a každá funkce před přístupem k těm datům čeká dokud není odemčený, pak si ho zamkne pro sebe, použije ta data a zase ho odemkne.

Bohužel nevím, jak se to dělá ve VBA, ale určitě to někde vygooglíš.

Nahlásit jako SPAM
IP: 213.211.51.–
Kartik
~ Anonymní uživatel
35 příspěvků
10. 5. 2016   #3
-
0
-

Mam ve funkci jak lokální proměnné uvnitř funkce, tak sdílené v rámci modulu (ty používá několik funkcí) - ty má také každá funkce vlastní? 

Takže spíš než že by se dělaly funkce, které je možné spustit několikrát zároveň, tak se to řeší až při jejich použití, kdy pokud je funkce už spuštěna, tak se znova nevolá, dokud neskončí to první volání? 

Nahlásit jako SPAM
IP: 90.178.131.–
q
~ Anonymní uživatel
219 příspěvků
10. 5. 2016   #4
-
0
-

Proměnné modulu jsou sdílené mezi vlákny. Tam je potřeba přístup synchronizovat, pokud jsou to proměnné, kde by to způsobilo problém.

Ty funkce běží současně, jen kritické části se právě synchronizují tak, aby si navzájem neškodily.

Dejme tomu, že máš kolekci (colWork), ke které nejde přistupovat z několika vláken současně. (Nebo několik souvisejících proměnných, nemusí to být jen jedna). Tak ji můžeš chránit zámkem (lckWork) nějak takhle:

Dim lckWork As Lock
Dim colWork As Collection

Sub AddWork(ByRef work As WorkData)
	lckWork.Lock()
	colWork.Add(work)
	lckWork.Unlock()
End Sub

Function GetWork() As WorkData
	Dim work as WorkData

	Set work = Nothing

	lckWork.Lock()
	If colWork.Count > 0 Then
		Set work = colWork.Remove(1)
	End if
	lckWork.Unlock()

	Set GetWork = work
End Function

A pak jsi třeba ještě v aplikaci, se kterou taky musíš komunikovat sériově (podle jiného dotazu možná tvůj případ). Tak to zase synchronizuješ (lckApp):

Dim lckApp as Lock

Sub AppReportProgress()
	lckApp.Lock()
	app.WorkFinished(1)
	lckApp.Unlock()
End Sub

A nakonec třeba 3 vlákna a nikde se nic nepere.

Sub ThreadProc()
	Dim work as WorkData

	Set work = GetWork()

	If work Is Nothing Then
		' pockat na praci. idealne pomoci semaforu.
		Sleep(5)
	Else
		' delat zadanou praci
		AppReportProgress()
	End If
End Sub

app.RegisterConsumer(AddWork)

RunInThread(ThreadProc)
RunInThread(ThreadProc)
RunInThread(ThreadProc)

Je to pseudokód, VB si moc nepamatuju. Někde najdi, jak se dělá ten lock.

Nahlásit jako SPAM
IP: 213.211.51.–
q
~ Anonymní uživatel
219 příspěvků
10. 5. 2016   #5
-
0
-

V principu jde o to, že se ten kód v Lock() zasekne dokud předchozí držitel ten zámek neodemkne.

Nahlásit jako SPAM
IP: 213.211.51.–
Kartik
~ Anonymní uživatel
35 příspěvků
11. 5. 2016   #6
-
0
-

Díky.

Napadá mě, že by to možná šlo taky řešit pomocí vytváření kopií proměnných, takže by každá funkce měla svoje a mohli by pak běžet zároveň bez omezení.

A otázka mimo, i když to možná souvisí. Jak funguje winapi funkce SetTimer, jestli si vytváří svoje vlákno, nebo jak to funguje, když se po vypršení limitu volá nějaká funkce zatímco jiný kód již běží. 

Nahlásit jako SPAM
IP: 90.178.131.–
q
~ Anonymní uživatel
219 příspěvků
11. 5. 2016   #7
-
0
-

Timer se zpracuje v cyklu GetMessage-DispatchMessage (i když použíješ TimerFunc).

Nahlásit jako SPAM
IP: 213.211.51.–
Kartik
~ Anonymní uživatel
35 příspěvků
15. 5. 2016   #8
-
0
-

Ten timer po té co vyprší hodí zprávu, že požadovaný čas vypršel a spustí se funkce... a kdy tedy proběhne tato funkce, když právě probíhá ve vlákně jiný kód? Podle toho jak na pohled průběh vypadá a jestli je to v jednom vlákně, tak to možná po vypršení času kód zastaví, proběhne ta funkce a pak pokračuje původní kód. Pokud by to bylo, tak je problém podobný, protože uprostřed funkce může spustit tu samou funkci.

Nahlásit jako SPAM
IP: 90.178.131.–
q
~ Anonymní uživatel
219 příspěvků
16. 5. 2016   #9
-
0
-

Zprávy se hromadí ve frontě, ze které se postupně vytahují a zpracovávájí. Timer se zpracuje až na něj dojde řada, nic se nepřeruší (může dojít k rekurzi). Pokud má proces více vláken, tak může dojít ke kolizi (ale stejně tak v obsluze timeru, jako obsluze tlačítka, vykreslování okna, nebo kdekoli jinde) - takže buď data nesdílej, nebo přístupy synchronizuj. Nevím, jak to ještě vysvětlit.

Nahlásit jako SPAM
IP: 213.211.51.–
Kartik
~ Anonymní uživatel
35 příspěvků
19. 5. 2016   #10
-
0
-

Nešlo mě už o původní dotaz, spíš jsem jen chtěl vědět jak přesně to probíhá, když vyprší ten timer a volá se jiná procedura. Mam představu, že system rozesílá zprávy a zase procedury zasílají zprávy na zpracovaní, ale já ve VBA se zprávama nic nedělám, nevím tedy jestli na pozadí nejsou nějaké odesílány, ten timer je posílá určitě.

Když jsem to testoval, tak běží funkce A dokud není zavolána funkce B přes timer, zároveň neběží.

Nahlásit jako SPAM
IP: 90.182.189.–
Kartik
~ Anonymní uživatel
35 příspěvků
19. 5. 2016   #11
-
0
-

Ještě k těm vláknům, stejně nechápu jak přesně může fungovat kontrola třeba toho jestli jsou data zamčená, nebo nějaká kontrola toho jestli je funkce již spuštěna. Tedy v případě, že je ve více vláknech spuštěná funkce ve stejný čas a tedy postupně zároveň probíhají i jednotlivé bloky kódu. Takže vlákna dojdou zároveň třeba k

If spusteno=false then
  spusteno=true
  
  ...

  spusteno=false 
end if

Takže všechna spuštění funkce projdou podmínkou?

Nahlásit jako SPAM
IP: 90.182.189.–
Kartik
~ Anonymní uživatel
35 příspěvků
19. 5. 2016   #12
-
0
-

Už to asi mám, ten test musí být jen v jednom vláknu a tam se jedna funkce dostane dřív a jiná/jiné dýl.

Nahlásit jako SPAM
IP: 90.182.189.–
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 15 hostů

Moderátoři diskuze

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032016 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý